Skip to content

Commit

Permalink
Allow QgsPropertyTransformers to have an associated QgsCurveTransform
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 22, 2017
1 parent 5c3198d commit dcf6104
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 19 deletions.
13 changes: 13 additions & 0 deletions python/core/qgspropertytransformer.sip
Expand Up @@ -60,6 +60,8 @@ class QgsPropertyTransformer

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

QgsPropertyTransformer( const QgsPropertyTransformer& other );

virtual ~QgsPropertyTransformer();

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

void setMaxValue( double max );

QgsCurveTransform* curveTransform() const;

void setCurveTransform( QgsCurveTransform* transform /Transfer/ );

virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const = 0;
virtual QString toExpression( const QString& baseExpression ) const = 0;

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

protected:

double transformNumeric( double input ) const;
};
class QgsGenericNumericTransformer : QgsPropertyTransformer
{
Expand All @@ -98,6 +107,8 @@ class QgsGenericNumericTransformer : QgsPropertyTransformer
double nullOutput = 0.0,
double exponent = 1.0 );

QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other );

virtual Type transformerType() const;
virtual QgsGenericNumericTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
Expand Down Expand Up @@ -140,6 +151,8 @@ class QgsSizeScaleTransformer : QgsPropertyTransformer
double nullSize = 0.0,
double exponent = 1.0 );

QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other );

virtual Type transformerType() const;
virtual QgsSizeScaleTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
Expand Down
130 changes: 111 additions & 19 deletions src/core/qgspropertytransformer.cpp
Expand Up @@ -50,11 +50,32 @@ QgsPropertyTransformer::QgsPropertyTransformer( double minValue, double maxValue
, mMaxValue( maxValue )
{}

QgsPropertyTransformer::QgsPropertyTransformer( const QgsPropertyTransformer& other )
: mMinValue( other.mMinValue )
, mMaxValue( other.mMaxValue )
, mCurveTransform( other.mCurveTransform ? new QgsCurveTransform( *other.mCurveTransform ) : nullptr )
{}

QgsPropertyTransformer& QgsPropertyTransformer::operator=( const QgsPropertyTransformer & other )
{
mMinValue = other.mMinValue;
mMaxValue = other.mMaxValue;
mCurveTransform.reset( other.mCurveTransform ? new QgsCurveTransform( *other.mCurveTransform ) : nullptr );
return *this;
}

bool QgsPropertyTransformer::writeXml( QDomElement& transformerElem, QDomDocument& doc ) const
{
Q_UNUSED( doc );
transformerElem.setAttribute( "minValue", QString::number( mMinValue ) );
transformerElem.setAttribute( "maxValue", QString::number( mMaxValue ) );

if ( mCurveTransform )
{
QDomElement curveElement = doc.createElement( "curve" );
mCurveTransform->writeXml( curveElement, doc );
transformerElem.appendChild( curveElement );
}
return true;
}

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

double QgsPropertyTransformer::transformNumeric( double input ) const
{
if ( !mCurveTransform )
return input;

if ( qgsDoubleNear( mMaxValue, mMinValue ) )
return input;

// convert input into target range
double scaledInput = ( input - mMinValue ) / ( mMaxValue - mMinValue );

return mMinValue + ( mMaxValue - mMinValue ) * mCurveTransform->y( scaledInput );
}

bool QgsPropertyTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
{
Q_UNUSED( doc );
mMinValue = transformerElem.attribute( "minValue", "0.0" ).toDouble();
mMaxValue = transformerElem.attribute( "maxValue", "1.0" ).toDouble();
mCurveTransform.reset( nullptr );

QDomNodeList curveNodeList = transformerElem.elementsByTagName( "curve" );
if ( !curveNodeList.isEmpty() )
{
QDomElement curveElem = curveNodeList.at( 0 ).toElement();
mCurveTransform.reset( new QgsCurveTransform() );
mCurveTransform->readXml( curveElem, doc );
}

return true;
}

Expand All @@ -89,14 +134,35 @@ QgsGenericNumericTransformer::QgsGenericNumericTransformer( double minValue, dou
, mExponent( exponent )
{}

QgsGenericNumericTransformer::QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other )
: QgsPropertyTransformer( other )
, mMinOutput( other.mMinOutput )
, mMaxOutput( other.mMaxOutput )
, mNullOutput( other.mNullOutput )
, mExponent( other.mExponent )
{}

QgsGenericNumericTransformer& QgsGenericNumericTransformer::operator=( const QgsGenericNumericTransformer & other )
{
QgsPropertyTransformer::operator=( other );
mMinOutput = other.mMinOutput;
mMaxOutput = other.mMaxOutput;
mNullOutput = other.mNullOutput;
mExponent = other.mExponent;
return *this;
}

QgsGenericNumericTransformer *QgsGenericNumericTransformer::clone()
{
return new QgsGenericNumericTransformer( mMinValue,
mMaxValue,
mMinOutput,
mMaxOutput,
mNullOutput,
mExponent );
std::unique_ptr< QgsGenericNumericTransformer > t( new QgsGenericNumericTransformer( mMinValue,
mMaxValue,
mMinOutput,
mMaxOutput,
mNullOutput,
mExponent ) );
if ( mCurveTransform )
t->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
return t.release();
}

bool QgsGenericNumericTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
Expand Down Expand Up @@ -145,7 +211,7 @@ QVariant QgsGenericNumericTransformer::transform( const QgsExpressionContext& co
if ( ok )
{
//apply scaling to value
return value( dblValue );
return value( transformNumeric( dblValue ) );
}
else
{
Expand Down Expand Up @@ -257,15 +323,38 @@ QgsSizeScaleTransformer::QgsSizeScaleTransformer( ScaleType type, double minValu
setType( type );
}

QgsSizeScaleTransformer::QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other )
: QgsPropertyTransformer( other )
, mType( other.mType )
, mMinSize( other.mMinSize )
, mMaxSize( other.mMaxSize )
, mNullSize( other.mNullSize )
, mExponent( other.mExponent )
{}

QgsSizeScaleTransformer& QgsSizeScaleTransformer::operator=( const QgsSizeScaleTransformer & other )
{
QgsPropertyTransformer::operator=( other );
mType = other.mType;
mMinSize = other.mMinSize;
mMaxSize = other.mMaxSize;
mNullSize = other.mNullSize;
mExponent = other.mExponent;
return *this;
}

QgsSizeScaleTransformer *QgsSizeScaleTransformer::clone()
{
return new QgsSizeScaleTransformer( mType,
mMinValue,
mMaxValue,
mMinSize,
mMaxSize,
mNullSize,
mExponent );
std::unique_ptr< QgsSizeScaleTransformer > t( new QgsSizeScaleTransformer( mType,
mMinValue,
mMaxValue,
mMinSize,
mMaxSize,
mNullSize,
mExponent ) );
if ( mCurveTransform )
t->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
return t.release();
}

bool QgsSizeScaleTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
Expand Down Expand Up @@ -344,7 +433,7 @@ QVariant QgsSizeScaleTransformer::transform( const QgsExpressionContext& context
if ( ok )
{
//apply scaling to value
return size( dblValue );
return size( transformNumeric( dblValue ) );
}
else
{
Expand Down Expand Up @@ -483,6 +572,7 @@ QgsColorRampTransformer::QgsColorRampTransformer( const QgsColorRampTransformer

QgsColorRampTransformer &QgsColorRampTransformer::operator=( const QgsColorRampTransformer & other )
{
QgsPropertyTransformer::operator=( other );
mMinValue = other.mMinValue;
mMaxValue = other.mMaxValue;
mGradientRamp.reset( other.mGradientRamp ? other.mGradientRamp->clone() : nullptr );
Expand All @@ -493,11 +583,13 @@ QgsColorRampTransformer &QgsColorRampTransformer::operator=( const QgsColorRampT

QgsColorRampTransformer* QgsColorRampTransformer::clone()
{
QgsColorRampTransformer* c = new QgsColorRampTransformer( mMinValue, mMaxValue,
std::unique_ptr< QgsColorRampTransformer > c( new QgsColorRampTransformer( mMinValue, mMaxValue,
mGradientRamp ? mGradientRamp->clone() : nullptr,
mNullColor );
mNullColor ) );
c->setRampName( mRampName );
return c;
if ( mCurveTransform )
c->setCurveTransform( new QgsCurveTransform( *mCurveTransform ) );
return c.release();
}

bool QgsColorRampTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
Expand Down Expand Up @@ -546,7 +638,7 @@ QVariant QgsColorRampTransformer::transform( const QgsExpressionContext &context
if ( ok )
{
//apply scaling to value
return color( dblValue );
return color( transformNumeric( dblValue ) );
}
else
{
Expand Down
42 changes: 42 additions & 0 deletions src/core/qgspropertytransformer.h
Expand Up @@ -177,6 +177,12 @@ class CORE_EXPORT QgsPropertyTransformer
*/
QgsPropertyTransformer( double minValue = 0.0, double maxValue = 1.0 );

/**
* Copy constructor.
*/
QgsPropertyTransformer( const QgsPropertyTransformer& other );
QgsPropertyTransformer& operator=( const QgsPropertyTransformer& other );

virtual ~QgsPropertyTransformer() = default;

/**
Expand Down Expand Up @@ -235,6 +241,21 @@ class CORE_EXPORT QgsPropertyTransformer
*/
void setMaxValue( double max ) { mMaxValue = max; }

/**
* Returns the curve transform applied to input values before they are transformed
* by the individual transform subclasses.
* @see setCurveTransform()
*/
QgsCurveTransform* curveTransform() const { return mCurveTransform.get(); }

/**
* Sets a curve transform to apply to input values before they are transformed
* by the individual transform subclasses. Ownership of \a transform is transferred
* to the property transformer.
* @see curveTransform()
*/
void setCurveTransform( QgsCurveTransform* transform ) { mCurveTransform.reset( transform ); }

/**
* Calculates the transform of a value. Derived classes must implement this to perform their transformations
* on input values
Expand Down Expand Up @@ -271,6 +292,15 @@ class CORE_EXPORT QgsPropertyTransformer
//! Maximum value expected by the transformer
double mMaxValue;

//! Optional curve transform
std::unique_ptr< QgsCurveTransform > mCurveTransform;

/**
* Applies base class numeric transformations. Derived classes should call this
* to transform an \a input numeric value before they apply any transform to the result.
* This applies any curve transforms which may exist on the transformer.
*/
double transformNumeric( double input ) const;
};

/**
Expand Down Expand Up @@ -300,6 +330,12 @@ class CORE_EXPORT QgsGenericNumericTransformer : public QgsPropertyTransformer
double nullOutput = 0.0,
double exponent = 1.0 );

/**
* Copy constructor.
*/
QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other );
QgsGenericNumericTransformer& operator=( const QgsGenericNumericTransformer& other );

virtual Type transformerType() const override { return GenericNumericTransformer; }
virtual QgsGenericNumericTransformer* clone() override;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const override;
Expand Down Expand Up @@ -430,6 +466,12 @@ class CORE_EXPORT QgsSizeScaleTransformer : public QgsPropertyTransformer
double nullSize = 0.0,
double exponent = 1.0 );

/**
* Copy constructor.
*/
QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other );
QgsSizeScaleTransformer& operator=( const QgsSizeScaleTransformer& other );

virtual Type transformerType() const override { return SizeScaleTransformer; }
virtual QgsSizeScaleTransformer* clone() override;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const override;
Expand Down

0 comments on commit dcf6104

Please sign in to comment.