Skip to content

Commit dcf6104

Browse files
committed
Allow QgsPropertyTransformers to have an associated QgsCurveTransform
1 parent 5c3198d commit dcf6104

File tree

4 files changed

+244
-19
lines changed

4 files changed

+244
-19
lines changed

python/core/qgspropertytransformer.sip

+13
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class QgsPropertyTransformer
6060

6161
QgsPropertyTransformer( double minValue = 0.0, double maxValue = 1.0 );
6262

63+
QgsPropertyTransformer( const QgsPropertyTransformer& other );
64+
6365
virtual ~QgsPropertyTransformer();
6466

6567
virtual Type transformerType() const = 0;
@@ -78,11 +80,18 @@ class QgsPropertyTransformer
7880

7981
void setMaxValue( double max );
8082

83+
QgsCurveTransform* curveTransform() const;
84+
85+
void setCurveTransform( QgsCurveTransform* transform /Transfer/ );
86+
8187
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const = 0;
8288
virtual QString toExpression( const QString& baseExpression ) const = 0;
8389

8490
static QgsPropertyTransformer* fromExpression( const QString& expression, QString& baseExpression /Out/, QString& fieldName /Out/ ) /Factory/;
8591

92+
protected:
93+
94+
double transformNumeric( double input ) const;
8695
};
8796
class QgsGenericNumericTransformer : QgsPropertyTransformer
8897
{
@@ -98,6 +107,8 @@ class QgsGenericNumericTransformer : QgsPropertyTransformer
98107
double nullOutput = 0.0,
99108
double exponent = 1.0 );
100109

110+
QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other );
111+
101112
virtual Type transformerType() const;
102113
virtual QgsGenericNumericTransformer* clone() /Factory/;
103114
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
@@ -140,6 +151,8 @@ class QgsSizeScaleTransformer : QgsPropertyTransformer
140151
double nullSize = 0.0,
141152
double exponent = 1.0 );
142153

154+
QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other );
155+
143156
virtual Type transformerType() const;
144157
virtual QgsSizeScaleTransformer* clone() /Factory/;
145158
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;

src/core/qgspropertytransformer.cpp

+111-19
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,32 @@ QgsPropertyTransformer::QgsPropertyTransformer( double minValue, double maxValue
5050
, mMaxValue( maxValue )
5151
{}
5252

53+
QgsPropertyTransformer::QgsPropertyTransformer( const QgsPropertyTransformer& other )
54+
: mMinValue( other.mMinValue )
55+
, mMaxValue( other.mMaxValue )
56+
, mCurveTransform( other.mCurveTransform ? new QgsCurveTransform( *other.mCurveTransform ) : nullptr )
57+
{}
58+
59+
QgsPropertyTransformer& QgsPropertyTransformer::operator=( const QgsPropertyTransformer & other )
60+
{
61+
mMinValue = other.mMinValue;
62+
mMaxValue = other.mMaxValue;
63+
mCurveTransform.reset( other.mCurveTransform ? new QgsCurveTransform( *other.mCurveTransform ) : nullptr );
64+
return *this;
65+
}
66+
5367
bool QgsPropertyTransformer::writeXml( QDomElement& transformerElem, QDomDocument& doc ) const
5468
{
5569
Q_UNUSED( doc );
5670
transformerElem.setAttribute( "minValue", QString::number( mMinValue ) );
5771
transformerElem.setAttribute( "maxValue", QString::number( mMaxValue ) );
72+
73+
if ( mCurveTransform )
74+
{
75+
QDomElement curveElement = doc.createElement( "curve" );
76+
mCurveTransform->writeXml( curveElement, doc );
77+
transformerElem.appendChild( curveElement );
78+
}
5879
return true;
5980
}
6081

@@ -69,11 +90,35 @@ QgsPropertyTransformer* QgsPropertyTransformer::fromExpression( const QString& e
6990
return nullptr;
7091
}
7192

93+
double QgsPropertyTransformer::transformNumeric( double input ) const
94+
{
95+
if ( !mCurveTransform )
96+
return input;
97+
98+
if ( qgsDoubleNear( mMaxValue, mMinValue ) )
99+
return input;
100+
101+
// convert input into target range
102+
double scaledInput = ( input - mMinValue ) / ( mMaxValue - mMinValue );
103+
104+
return mMinValue + ( mMaxValue - mMinValue ) * mCurveTransform->y( scaledInput );
105+
}
106+
72107
bool QgsPropertyTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
73108
{
74109
Q_UNUSED( doc );
75110
mMinValue = transformerElem.attribute( "minValue", "0.0" ).toDouble();
76111
mMaxValue = transformerElem.attribute( "maxValue", "1.0" ).toDouble();
112+
mCurveTransform.reset( nullptr );
113+
114+
QDomNodeList curveNodeList = transformerElem.elementsByTagName( "curve" );
115+
if ( !curveNodeList.isEmpty() )
116+
{
117+
QDomElement curveElem = curveNodeList.at( 0 ).toElement();
118+
mCurveTransform.reset( new QgsCurveTransform() );
119+
mCurveTransform->readXml( curveElem, doc );
120+
}
121+
77122
return true;
78123
}
79124

@@ -89,14 +134,35 @@ QgsGenericNumericTransformer::QgsGenericNumericTransformer( double minValue, dou
89134
, mExponent( exponent )
90135
{}
91136

137+
QgsGenericNumericTransformer::QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other )
138+
: QgsPropertyTransformer( other )
139+
, mMinOutput( other.mMinOutput )
140+
, mMaxOutput( other.mMaxOutput )
141+
, mNullOutput( other.mNullOutput )
142+
, mExponent( other.mExponent )
143+
{}
144+
145+
QgsGenericNumericTransformer& QgsGenericNumericTransformer::operator=( const QgsGenericNumericTransformer & other )
146+
{
147+
QgsPropertyTransformer::operator=( other );
148+
mMinOutput = other.mMinOutput;
149+
mMaxOutput = other.mMaxOutput;
150+
mNullOutput = other.mNullOutput;
151+
mExponent = other.mExponent;
152+
return *this;
153+
}
154+
92155
QgsGenericNumericTransformer *QgsGenericNumericTransformer::clone()
93156
{
94-
return new QgsGenericNumericTransformer( mMinValue,
95-
mMaxValue,
96-
mMinOutput,
97-
mMaxOutput,
98-
mNullOutput,
99-
mExponent );
157+
std::unique_ptr< QgsGenericNumericTransformer > t( new QgsGenericNumericTransformer( mMinValue,
158+
mMaxValue,
159+
mMinOutput,
160+
mMaxOutput,
161+
mNullOutput,
162+
mExponent ) );
163+
if ( mCurveTransform )
164+
t->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
165+
return t.release();
100166
}
101167

102168
bool QgsGenericNumericTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
@@ -145,7 +211,7 @@ QVariant QgsGenericNumericTransformer::transform( const QgsExpressionContext& co
145211
if ( ok )
146212
{
147213
//apply scaling to value
148-
return value( dblValue );
214+
return value( transformNumeric( dblValue ) );
149215
}
150216
else
151217
{
@@ -257,15 +323,38 @@ QgsSizeScaleTransformer::QgsSizeScaleTransformer( ScaleType type, double minValu
257323
setType( type );
258324
}
259325

326+
QgsSizeScaleTransformer::QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other )
327+
: QgsPropertyTransformer( other )
328+
, mType( other.mType )
329+
, mMinSize( other.mMinSize )
330+
, mMaxSize( other.mMaxSize )
331+
, mNullSize( other.mNullSize )
332+
, mExponent( other.mExponent )
333+
{}
334+
335+
QgsSizeScaleTransformer& QgsSizeScaleTransformer::operator=( const QgsSizeScaleTransformer & other )
336+
{
337+
QgsPropertyTransformer::operator=( other );
338+
mType = other.mType;
339+
mMinSize = other.mMinSize;
340+
mMaxSize = other.mMaxSize;
341+
mNullSize = other.mNullSize;
342+
mExponent = other.mExponent;
343+
return *this;
344+
}
345+
260346
QgsSizeScaleTransformer *QgsSizeScaleTransformer::clone()
261347
{
262-
return new QgsSizeScaleTransformer( mType,
263-
mMinValue,
264-
mMaxValue,
265-
mMinSize,
266-
mMaxSize,
267-
mNullSize,
268-
mExponent );
348+
std::unique_ptr< QgsSizeScaleTransformer > t( new QgsSizeScaleTransformer( mType,
349+
mMinValue,
350+
mMaxValue,
351+
mMinSize,
352+
mMaxSize,
353+
mNullSize,
354+
mExponent ) );
355+
if ( mCurveTransform )
356+
t->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
357+
return t.release();
269358
}
270359

271360
bool QgsSizeScaleTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
@@ -344,7 +433,7 @@ QVariant QgsSizeScaleTransformer::transform( const QgsExpressionContext& context
344433
if ( ok )
345434
{
346435
//apply scaling to value
347-
return size( dblValue );
436+
return size( transformNumeric( dblValue ) );
348437
}
349438
else
350439
{
@@ -483,6 +572,7 @@ QgsColorRampTransformer::QgsColorRampTransformer( const QgsColorRampTransformer
483572

484573
QgsColorRampTransformer &QgsColorRampTransformer::operator=( const QgsColorRampTransformer & other )
485574
{
575+
QgsPropertyTransformer::operator=( other );
486576
mMinValue = other.mMinValue;
487577
mMaxValue = other.mMaxValue;
488578
mGradientRamp.reset( other.mGradientRamp ? other.mGradientRamp->clone() : nullptr );
@@ -493,11 +583,13 @@ QgsColorRampTransformer &QgsColorRampTransformer::operator=( const QgsColorRampT
493583

494584
QgsColorRampTransformer* QgsColorRampTransformer::clone()
495585
{
496-
QgsColorRampTransformer* c = new QgsColorRampTransformer( mMinValue, mMaxValue,
586+
std::unique_ptr< QgsColorRampTransformer > c( new QgsColorRampTransformer( mMinValue, mMaxValue,
497587
mGradientRamp ? mGradientRamp->clone() : nullptr,
498-
mNullColor );
588+
mNullColor ) );
499589
c->setRampName( mRampName );
500-
return c;
590+
if ( mCurveTransform )
591+
c->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
592+
return c.release();
501593
}
502594

503595
bool QgsColorRampTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
@@ -546,7 +638,7 @@ QVariant QgsColorRampTransformer::transform( const QgsExpressionContext &context
546638
if ( ok )
547639
{
548640
//apply scaling to value
549-
return color( dblValue );
641+
return color( transformNumeric( dblValue ) );
550642
}
551643
else
552644
{

src/core/qgspropertytransformer.h

+42
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ class CORE_EXPORT QgsPropertyTransformer
177177
*/
178178
QgsPropertyTransformer( double minValue = 0.0, double maxValue = 1.0 );
179179

180+
/**
181+
* Copy constructor.
182+
*/
183+
QgsPropertyTransformer( const QgsPropertyTransformer& other );
184+
QgsPropertyTransformer& operator=( const QgsPropertyTransformer& other );
185+
180186
virtual ~QgsPropertyTransformer() = default;
181187

182188
/**
@@ -235,6 +241,21 @@ class CORE_EXPORT QgsPropertyTransformer
235241
*/
236242
void setMaxValue( double max ) { mMaxValue = max; }
237243

244+
/**
245+
* Returns the curve transform applied to input values before they are transformed
246+
* by the individual transform subclasses.
247+
* @see setCurveTransform()
248+
*/
249+
QgsCurveTransform* curveTransform() const { return mCurveTransform.get(); }
250+
251+
/**
252+
* Sets a curve transform to apply to input values before they are transformed
253+
* by the individual transform subclasses. Ownership of \a transform is transferred
254+
* to the property transformer.
255+
* @see curveTransform()
256+
*/
257+
void setCurveTransform( QgsCurveTransform* transform ) { mCurveTransform.reset( transform ); }
258+
238259
/**
239260
* Calculates the transform of a value. Derived classes must implement this to perform their transformations
240261
* on input values
@@ -271,6 +292,15 @@ class CORE_EXPORT QgsPropertyTransformer
271292
//! Maximum value expected by the transformer
272293
double mMaxValue;
273294

295+
//! Optional curve transform
296+
std::unique_ptr< QgsCurveTransform > mCurveTransform;
297+
298+
/**
299+
* Applies base class numeric transformations. Derived classes should call this
300+
* to transform an \a input numeric value before they apply any transform to the result.
301+
* This applies any curve transforms which may exist on the transformer.
302+
*/
303+
double transformNumeric( double input ) const;
274304
};
275305

276306
/**
@@ -300,6 +330,12 @@ class CORE_EXPORT QgsGenericNumericTransformer : public QgsPropertyTransformer
300330
double nullOutput = 0.0,
301331
double exponent = 1.0 );
302332

333+
/**
334+
* Copy constructor.
335+
*/
336+
QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other );
337+
QgsGenericNumericTransformer& operator=( const QgsGenericNumericTransformer& other );
338+
303339
virtual Type transformerType() const override { return GenericNumericTransformer; }
304340
virtual QgsGenericNumericTransformer* clone() override;
305341
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const override;
@@ -430,6 +466,12 @@ class CORE_EXPORT QgsSizeScaleTransformer : public QgsPropertyTransformer
430466
double nullSize = 0.0,
431467
double exponent = 1.0 );
432468

469+
/**
470+
* Copy constructor.
471+
*/
472+
QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other );
473+
QgsSizeScaleTransformer& operator=( const QgsSizeScaleTransformer& other );
474+
433475
virtual Type transformerType() const override { return SizeScaleTransformer; }
434476
virtual QgsSizeScaleTransformer* clone() override;
435477
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const override;

0 commit comments

Comments
 (0)