49   : mMinValue( minValue )
 
   50   , mMaxValue( maxValue )
 
   54   : mMinValue( other.mMinValue )
 
   55   , mMaxValue( other.mMaxValue )
 
   56   , mCurveTransform( other.mCurveTransform ? new 
QgsCurveTransform( *other.mCurveTransform ) : nullptr )
 
   71   QVariantMap transformerMap = transformer.toMap();
 
   73   mMinValue = transformerMap.value( QStringLiteral( 
"minValue" ), 0.0 ).toDouble();
 
   74   mMaxValue = transformerMap.value( QStringLiteral( 
"maxValue" ), 1.0 ).toDouble();
 
   77   QVariantMap curve = transformerMap.value( QStringLiteral( 
"curve" ) ).toMap();
 
   79   if ( !curve.isEmpty() )
 
   90   QVariantMap transformerMap;
 
   92   transformerMap.insert( QStringLiteral( 
"minValue" ), 
mMinValue );
 
   93   transformerMap.insert( QStringLiteral( 
"maxValue" ), 
mMaxValue );
 
   97     transformerMap.insert( QStringLiteral( 
"curve" ), 
mCurveTransform->toVariant() );
 
   99   return transformerMap;
 
  104   baseExpression.clear();
 
  134   , mMinOutput( minOutput )
 
  135   , mMaxOutput( maxOutput )
 
  136   , mNullOutput( nullOutput )
 
  137   , mExponent( exponent )
 
  157   transformerMap.insert( QStringLiteral( 
"minOutput" ), mMinOutput );
 
  158   transformerMap.insert( QStringLiteral( 
"maxOutput" ), mMaxOutput );
 
  159   transformerMap.insert( QStringLiteral( 
"nullOutput" ), mNullOutput );
 
  160   transformerMap.insert( QStringLiteral( 
"exponent" ), mExponent );
 
  162   return transformerMap;
 
  169   QVariantMap transformerMap = transformer.toMap();
 
  171   mMinOutput = transformerMap.value( QStringLiteral( 
"minOutput" ), 0.0 ).toDouble();
 
  172   mMaxOutput = transformerMap.value( QStringLiteral( 
"maxOutput" ), 1.0 ).toDouble();
 
  173   mNullOutput = transformerMap.value( QStringLiteral( 
"nullOutput" ), 0.0 ).toDouble();
 
  174   mExponent = transformerMap.value( QStringLiteral( 
"exponent" ), 1.0 ).toDouble();
 
  181     return std::clamp( input, mMinOutput, mMaxOutput );
 
  198   double dblValue = v.toDouble( &ok );
 
  203     return value( dblValue );
 
  213   QString minValueString = QString::number( 
mMinValue );
 
  214   QString maxValueString = QString::number( 
mMaxValue );
 
  215   QString minOutputString = QString::number( mMinOutput );
 
  216   QString maxOutputString = QString::number( mMaxOutput );
 
  217   QString nullOutputString = QString::number( mNullOutput );
 
  218   QString exponentString = QString::number( mExponent );
 
  221     return QStringLiteral( 
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, nullOutputString );
 
  223     return QStringLiteral( 
"coalesce(scale_exp(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, exponentString, nullOutputString );
 
  230   double nullValue = 0.0;
 
  233   baseExpression.clear();
 
  245   QList<QgsExpressionNode *> args = f->
args()->
list();
 
  294     baseExpression = args[0]->
dump();
 
  306   , mMinSize( minSize )
 
  307   , mMaxSize( maxSize )
 
  308   , mNullSize( nullSize )
 
  309   , mExponent( exponent )
 
  332   transformerMap.insert( QStringLiteral( 
"scaleType" ), 
static_cast< int >( mType ) );
 
  333   transformerMap.insert( QStringLiteral( 
"minSize" ), mMinSize );
 
  334   transformerMap.insert( QStringLiteral( 
"maxSize" ), mMaxSize );
 
  335   transformerMap.insert( QStringLiteral( 
"nullSize" ), mNullSize );
 
  336   transformerMap.insert( QStringLiteral( 
"exponent" ), mExponent );
 
  338   return transformerMap;
 
  345   QVariantMap transformerMap = transformer.toMap();
 
  347   mType = 
static_cast< ScaleType >( transformerMap.value( QStringLiteral( 
"scaleType" ), 
Linear ).toInt() );
 
  348   mMinSize = transformerMap.value( QStringLiteral( 
"minSize" ), 0.0 ).toDouble();
 
  349   mMaxSize = transformerMap.value( QStringLiteral( 
"maxSize" ), 1.0 ).toDouble();
 
  350   mNullSize = transformerMap.value( QStringLiteral( 
"nullSize" ), 0.0 ).toDouble();
 
  351   mExponent = transformerMap.value( QStringLiteral( 
"exponent" ), 1.0 ).toDouble();
 
  398   if ( value.isNull() )
 
  402   double dblValue = value.toDouble( &ok );
 
  407     return size( dblValue );
 
  417   QString minValueString = QString::number( 
mMinValue );
 
  418   QString maxValueString = QString::number( 
mMaxValue );
 
  419   QString minSizeString = QString::number( mMinSize );
 
  420   QString maxSizeString = QString::number( mMaxSize );
 
  421   QString nullSizeString = QString::number( mNullSize );
 
  422   QString exponentString = QString::number( mExponent );
 
  427       return QStringLiteral( 
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, nullSizeString );
 
  432       return QStringLiteral( 
"coalesce(scale_exp(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, exponentString, nullSizeString );
 
  446   baseExpression.clear();
 
  458   QList<QgsExpressionNode *> args = f->
args()->
list();
 
  515     baseExpression = args[0]->
dump();
 
  527     const QColor &nullColor )
 
  529   , mGradientRamp( ramp )
 
  530   , mNullColor( nullColor )
 
  537   , mGradientRamp( other.mGradientRamp ? other.mGradientRamp->clone() : nullptr )
 
  538   , mNullColor( other.mNullColor )
 
  539   , mRampName( other.mRampName )
 
  549   mGradientRamp.reset( other.mGradientRamp ? other.mGradientRamp->clone() : 
nullptr );
 
  550   mNullColor = other.mNullColor;
 
  551   mRampName = other.mRampName;
 
  558       mGradientRamp ? mGradientRamp->clone() : 
nullptr,
 
  560   c->setRampName( mRampName );
 
  575   transformerMap.insert( QStringLiteral( 
"rampName" ), mRampName );
 
  577   return transformerMap;
 
  582   QVariantMap transformerMap = definition.toMap();
 
  586   mGradientRamp.reset( 
nullptr );
 
  587   if ( transformerMap.contains( QStringLiteral( 
"colorramp" ) ) )
 
  593   mRampName = transformerMap.value( QStringLiteral( 
"rampName" ) ).toString();
 
  601   if ( value.isNull() )
 
  605   double dblValue = value.toDouble( &ok );
 
  610     return color( dblValue );
 
  620   if ( !mGradientRamp )
 
  623   QString minValueString = QString::number( 
mMinValue );
 
  624   QString maxValueString = QString::number( 
mMaxValue );
 
  625   QString nullColorString = mNullColor.name();
 
  627   return QStringLiteral( 
"coalesce(ramp_color('%1',scale_linear(%2, %3, %4, 0, 1)), '%5')" ).arg( !mRampName.isEmpty() ? mRampName : QStringLiteral( 
"custom ramp" ),
 
  628          baseExpression, minValueString, maxValueString, nullColorString );
 
  636   if ( !mGradientRamp )
 
  639   return mGradientRamp->color( scaledVal );
 
  644   return mGradientRamp.get();
 
  649   mGradientRamp.reset( ramp );
 
  659   return a.
x() < b.
x();
 
  665   calcSecondDerivativeArray();
 
  669   : mControlPoints( controlPoints )
 
  671   std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  672   calcSecondDerivativeArray();
 
  677   delete [] mSecondDerivativeArray;
 
  681   : mControlPoints( other.mControlPoints )
 
  683   if ( other.mSecondDerivativeArray )
 
  685     mSecondDerivativeArray = 
new double[ mControlPoints.count()];
 
  686     memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray, 
sizeof( 
double ) * mControlPoints.count() );
 
  692   if ( 
this != &other )
 
  694     mControlPoints = other.mControlPoints;
 
  695     if ( other.mSecondDerivativeArray )
 
  697       delete [] mSecondDerivativeArray;
 
  698       mSecondDerivativeArray = 
new double[ mControlPoints.count()];
 
  699       memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray, 
sizeof( 
double ) * mControlPoints.count() );
 
  707   mControlPoints = points;
 
  708   std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  709   for ( 
int i = 0; i < mControlPoints.count(); ++i )
 
  711     mControlPoints[ i ] = 
QgsPointXY( std::clamp( mControlPoints.at( i ).x(), 0.0, 1.0 ),
 
  712                                       std::clamp( mControlPoints.at( i ).y(), 0.0, 1.0 ) );
 
  714   calcSecondDerivativeArray();
 
  720   if ( mControlPoints.contains( point ) )
 
  723   mControlPoints << point;
 
  724   std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  725   calcSecondDerivativeArray();
 
  730   for ( 
int i = 0; i < mControlPoints.count(); ++i )
 
  735       mControlPoints.removeAt( i );
 
  739   calcSecondDerivativeArray();
 
  748   int n = mControlPoints.count();
 
  750     return std::clamp( x,  0.0, 1.0 ); 
 
  754     if ( x <= mControlPoints.at( 0 ).x() )
 
  755       return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
 
  756     else if ( x >= mControlPoints.at( n - 1 ).x() )
 
  757       return std::clamp( mControlPoints.at( 1 ).y(), 0.0, 1.0 );
 
  760       double dx = mControlPoints.at( 1 ).x() - mControlPoints.at( 0 ).x();
 
  761       double dy = mControlPoints.at( 1 ).y() - mControlPoints.at( 0 ).y();
 
  762       return std::clamp( ( x - mControlPoints.at( 0 ).x() ) * ( dy / dx ) + mControlPoints.at( 0 ).y(), 0.0,  1.0 );
 
  767   if ( x <= mControlPoints.at( 0 ).x() )
 
  768     return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
 
  769   if ( x >= mControlPoints.at( n - 1 ).x() )
 
  770     return std::clamp( mControlPoints.at( n - 1 ).y(), 0.0, 1.0 );
 
  773   QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  778   for ( 
int i = 0; i < n - 1; ++i )
 
  780     if ( x < nextControlPoint.
x() )
 
  783       double h = nextControlPoint.
x() - currentControlPoint.
x();
 
  784       double t = ( x - currentControlPoint.
x() ) / h;
 
  788       return std::clamp( a * currentControlPoint.
y() + t * nextControlPoint.
y() + ( h * h / 6 ) * ( ( a * a * a - a ) * mSecondDerivativeArray[i] + ( t * t * t - t ) * mSecondDerivativeArray[i + 1] ),
 
  793     if ( pointIt == mControlPoints.constEnd() )
 
  796     currentControlPoint = nextControlPoint;
 
  797     nextControlPoint = *pointIt;
 
  801   return std::clamp( x, 0.0, 1.0 );
 
  810   QVector<double> result;
 
  812   int n = mControlPoints.count();
 
  816     const auto constX = x;
 
  817     for ( 
double i : constX )
 
  824   QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  830   double currentX = x.at( xIndex );
 
  832   while ( currentX <= currentControlPoint.
x() )
 
  834     result << std::clamp( currentControlPoint.
y(), 0.0, 1.0 );
 
  836     currentX = x.at( xIndex );
 
  839   for ( 
int i = 0; i < n - 1; ++i )
 
  841     while ( currentX < nextControlPoint.
x() )
 
  844       double h = nextControlPoint.
x() - currentControlPoint.
x();
 
  846       double t = ( currentX - currentControlPoint.
x() ) / h;
 
  850       result << std::clamp( a * currentControlPoint.
y() + t * nextControlPoint.
y() + ( h * h / 6 ) * ( ( a * a * a - a )*mSecondDerivativeArray[i] + ( t * t * t - t )*mSecondDerivativeArray[i + 1] ), 0.0, 1.0 );
 
  852       if ( xIndex == x.count() )
 
  855       currentX = x.at( xIndex );
 
  859     if ( pointIt == mControlPoints.constEnd() )
 
  862     currentControlPoint = nextControlPoint;
 
  863     nextControlPoint = *pointIt;
 
  867   while ( xIndex < x.count() )
 
  869     result << std::clamp( nextControlPoint.
y(), 0.0, 1.0 );
 
  878   QString xString = elem.attribute( QStringLiteral( 
"x" ) );
 
  879   QString yString = elem.attribute( QStringLiteral( 
"y" ) );
 
  881   QStringList xVals = xString.split( 
',' );
 
  882   QStringList yVals = yString.split( 
',' );
 
  883   if ( xVals.count() != yVals.count() )
 
  886   QList< QgsPointXY > newPoints;
 
  888   for ( 
int i = 0; i < xVals.count(); ++i )
 
  890     double x = xVals.at( i ).toDouble( &ok );
 
  893     double y = yVals.at( i ).toDouble( &ok );
 
  906   const auto constMControlPoints = mControlPoints;
 
  907   for ( 
const QgsPointXY &p : constMControlPoints )
 
  913   transformElem.setAttribute( QStringLiteral( 
"x" ), x.join( 
',' ) );
 
  914   transformElem.setAttribute( QStringLiteral( 
"y" ), 
y.join( 
',' ) );
 
  921   QVariantMap transformMap;
 
  925   const auto constMControlPoints = mControlPoints;
 
  926   for ( 
const QgsPointXY &p : constMControlPoints )
 
  932   transformMap.insert( QStringLiteral( 
"x" ), x.join( 
',' ) );
 
  933   transformMap.insert( QStringLiteral( 
"y" ), 
y.join( 
',' ) );
 
  940   QVariantMap transformMap = transformer.toMap();
 
  942   QString xString = transformMap.value( QStringLiteral( 
"x" ) ).toString();
 
  943   QString yString = transformMap.value( QStringLiteral( 
"y" ) ).toString();
 
  945   QStringList xVals = xString.split( 
',' );
 
  946   QStringList yVals = yString.split( 
',' );
 
  947   if ( xVals.count() != yVals.count() )
 
  950   QList< QgsPointXY > newPoints;
 
  952   for ( 
int i = 0; i < xVals.count(); ++i )
 
  954     double x = xVals.at( i ).toDouble( &ok );
 
  957     double y = yVals.at( i ).toDouble( &ok );
 
  970 void QgsCurveTransform::calcSecondDerivativeArray()
 
  972   int n = mControlPoints.count();
 
  976   delete[] mSecondDerivativeArray;
 
  978   double *matrix = 
new double[ n * 3 ];
 
  979   double *result = 
new double[ n ];
 
  984   QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  991   for ( 
int i = 1; i < n - 1; ++i )
 
  993     matrix[i * 3 + 0 ] = ( pointI.
x() - pointIm1.
x() ) / 6.0;
 
  994     matrix[i * 3 + 1 ] = ( pointIp1.
x() - pointIm1.
x() ) / 3.0;
 
  995     matrix[i * 3 + 2 ] = ( pointIp1.
x() - pointI.
x() ) / 6.0;
 
  996     result[i] = ( pointIp1.
y() - pointI.
y() ) / ( pointIp1.
x() - pointI.
x() ) - ( pointI.
y() - pointIm1.
y() ) / ( pointI.
x() - pointIm1.
x() );
 
 1002     if ( pointIt == mControlPoints.constEnd() )
 
 1005     pointIp1 = *pointIt;
 
 1007   matrix[( n - 1 ) * 3 + 0] = 0;
 
 1008   matrix[( n - 1 ) * 3 + 1] = 1;
 
 1009   matrix[( n - 1 ) * 3 + 2] = 0;
 
 1013   for ( 
int i = 1; i < n; ++i )
 
 1015     double k = matrix[i * 3 + 0] / matrix[( i - 1 ) * 3 + 1];
 
 1016     matrix[i * 3 + 1] -= k * matrix[( i - 1 ) * 3 + 2];
 
 1017     matrix[i * 3 + 0] = 0;
 
 1018     result[i] -= k * result[i - 1];
 
 1021   for ( 
int i = n - 2; i >= 0; --i )
 
 1023     double k = matrix[i * 3 + 2] / matrix[( i + 1 ) * 3 + 1];
 
 1024     matrix[i * 3 + 1] -= k * matrix[( i + 1 ) * 3 + 0];
 
 1025     matrix[i * 3 + 2] = 0;
 
 1026     result[i] -= k * result[i + 1];
 
 1030   mSecondDerivativeArray = 
new double[n];
 
 1031   for ( 
int i = 0; i < n; ++i )
 
 1033     mSecondDerivativeArray[i] = result[i] / matrix[( i * 3 ) + 1];
 
Abstract base class for color ramps.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
An expression node which takes it value from a feature's field.
QString dump() const override
Dump this node into a serialized (part) of an expression.
An expression node for expression functions.
int fnIndex() const
Returns the index of the node's function.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Class for parsing and evaluation of expressions (formerly called "search strings").
static const QList< QgsExpressionFunction * > & Functions()
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
QVariant evaluate()
Evaluate the feature and return the result.
A class to represent a 2D point.
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
static QColor decodeColor(const QString &str)
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QString encodeColor(const QColor &color)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)