50  : mMinValue( minValue )
 
   51  , mMaxValue( maxValue )
 
 
   55  : mMinValue( other.mMinValue )
 
   56  , mMaxValue( other.mMaxValue )
 
   57  , mCurveTransform( other.mCurveTransform ? new 
QgsCurveTransform( *other.mCurveTransform ) : nullptr )
 
 
   72  QVariantMap transformerMap = transformer.toMap();
 
   74  mMinValue = transformerMap.value( QStringLiteral( 
"minValue" ), 0.0 ).toDouble();
 
   75  mMaxValue = transformerMap.value( QStringLiteral( 
"maxValue" ), 1.0 ).toDouble();
 
   78  QVariantMap curve = transformerMap.value( QStringLiteral( 
"curve" ) ).toMap();
 
   80  if ( !curve.isEmpty() )
 
 
   91  QVariantMap transformerMap;
 
   93  transformerMap.insert( QStringLiteral( 
"minValue" ), 
mMinValue );
 
   94  transformerMap.insert( QStringLiteral( 
"maxValue" ), 
mMaxValue );
 
   98    transformerMap.insert( QStringLiteral( 
"curve" ), 
mCurveTransform->toVariant() );
 
  100  return transformerMap;
 
 
  105  baseExpression.clear();
 
 
  135  , mMinOutput( minOutput )
 
  136  , mMaxOutput( maxOutput )
 
  137  , mNullOutput( nullOutput )
 
  138  , mExponent( exponent )
 
 
  158  transformerMap.insert( QStringLiteral( 
"minOutput" ), mMinOutput );
 
  159  transformerMap.insert( QStringLiteral( 
"maxOutput" ), mMaxOutput );
 
  160  transformerMap.insert( QStringLiteral( 
"nullOutput" ), mNullOutput );
 
  161  transformerMap.insert( QStringLiteral( 
"exponent" ), mExponent );
 
  163  return transformerMap;
 
 
  170  QVariantMap transformerMap = transformer.toMap();
 
  172  mMinOutput = transformerMap.value( QStringLiteral( 
"minOutput" ), 0.0 ).toDouble();
 
  173  mMaxOutput = transformerMap.value( QStringLiteral( 
"maxOutput" ), 1.0 ).toDouble();
 
  174  mNullOutput = transformerMap.value( QStringLiteral( 
"nullOutput" ), 0.0 ).toDouble();
 
  175  mExponent = transformerMap.value( QStringLiteral( 
"exponent" ), 1.0 ).toDouble();
 
 
  182    return std::clamp( input, mMinOutput, mMaxOutput );
 
 
  199  double dblValue = v.toDouble( &ok );
 
  204    return value( dblValue );
 
 
  214  QString minValueString = QString::number( 
mMinValue );
 
  215  QString maxValueString = QString::number( 
mMaxValue );
 
  216  QString minOutputString = QString::number( mMinOutput );
 
  217  QString maxOutputString = QString::number( mMaxOutput );
 
  218  QString nullOutputString = QString::number( mNullOutput );
 
  219  QString exponentString = QString::number( mExponent );
 
  222    return QStringLiteral( 
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, nullOutputString );
 
  224    return QStringLiteral( 
"coalesce(scale_polynomial(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, exponentString, nullOutputString );
 
 
  231  double nullValue = 0.0;
 
  234  baseExpression.clear();
 
  246  QList<QgsExpressionNode *> args = f->
args()->
list();
 
  295    baseExpression = args[0]->
dump();
 
 
  307  , mMinSize( minSize )
 
  308  , mMaxSize( maxSize )
 
  309  , mNullSize( nullSize )
 
  310  , mExponent( exponent )
 
 
  333  transformerMap.insert( QStringLiteral( 
"scaleType" ), 
static_cast< int >( mType ) );
 
  334  transformerMap.insert( QStringLiteral( 
"minSize" ), mMinSize );
 
  335  transformerMap.insert( QStringLiteral( 
"maxSize" ), mMaxSize );
 
  336  transformerMap.insert( QStringLiteral( 
"nullSize" ), mNullSize );
 
  337  transformerMap.insert( QStringLiteral( 
"exponent" ), mExponent );
 
  339  return transformerMap;
 
 
  346  QVariantMap transformerMap = transformer.toMap();
 
  348  mType = 
static_cast< ScaleType >( transformerMap.value( QStringLiteral( 
"scaleType" ), 
Linear ).toInt() );
 
  349  mMinSize = transformerMap.value( QStringLiteral( 
"minSize" ), 0.0 ).toDouble();
 
  350  mMaxSize = transformerMap.value( QStringLiteral( 
"maxSize" ), 1.0 ).toDouble();
 
  351  mNullSize = transformerMap.value( QStringLiteral( 
"nullSize" ), 0.0 ).toDouble();
 
  352  mExponent = transformerMap.value( QStringLiteral( 
"exponent" ), 1.0 ).toDouble();
 
 
  403  double dblValue = value.toDouble( &ok );
 
  408    return size( dblValue );
 
 
  418  QString minValueString = QString::number( 
mMinValue );
 
  419  QString maxValueString = QString::number( 
mMaxValue );
 
  420  QString minSizeString = QString::number( mMinSize );
 
  421  QString maxSizeString = QString::number( mMaxSize );
 
  422  QString nullSizeString = QString::number( mNullSize );
 
  423  QString exponentString = QString::number( mExponent );
 
  428      return QStringLiteral( 
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, nullSizeString );
 
  433      return QStringLiteral( 
"coalesce(scale_polynomial(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, exponentString, nullSizeString );
 
 
  447  baseExpression.clear();
 
  459  QList<QgsExpressionNode *> args = f->
args()->
list();
 
  516    baseExpression = args[0]->
dump();
 
 
  528    const QColor &nullColor,
 
  529    const QString &rampName )
 
  531  , mGradientRamp( ramp )
 
  532  , mNullColor( nullColor )
 
  533  , mRampName( rampName )
 
 
  540  , mGradientRamp( other.mGradientRamp ? other.mGradientRamp->clone() : nullptr )
 
  541  , mNullColor( other.mNullColor )
 
  542  , mRampName( other.mRampName )
 
 
  552  mGradientRamp.reset( other.mGradientRamp ? other.mGradientRamp->clone() : nullptr );
 
  553  mNullColor = other.mNullColor;
 
  554  mRampName = other.mRampName;
 
 
  561      mGradientRamp ? mGradientRamp->clone() : 
nullptr,
 
  563  c->setRampName( mRampName );
 
 
  578  transformerMap.insert( QStringLiteral( 
"rampName" ), mRampName );
 
  580  return transformerMap;
 
 
  585  QVariantMap transformerMap = definition.toMap();
 
  589  mGradientRamp.reset( 
nullptr );
 
  590  if ( transformerMap.contains( QStringLiteral( 
"colorramp" ) ) )
 
  596  mRampName = transformerMap.value( QStringLiteral( 
"rampName" ) ).toString();
 
 
  608  double dblValue = value.toDouble( &ok );
 
  613    return color( dblValue );
 
 
  623  if ( !mGradientRamp )
 
  626  QString minValueString = QString::number( 
mMinValue );
 
  627  QString maxValueString = QString::number( 
mMaxValue );
 
  628  QString nullColorString = mNullColor.name();
 
  630  return QStringLiteral( 
"coalesce(ramp_color('%1',scale_linear(%2, %3, %4, 0, 1)), '%5')" ).arg( !mRampName.isEmpty() ? mRampName : QStringLiteral( 
"custom ramp" ),
 
  631         baseExpression, minValueString, maxValueString, nullColorString );
 
 
  639  if ( !mGradientRamp )
 
  642  return mGradientRamp->color( scaledVal );
 
 
  647  return mGradientRamp.get();
 
 
  652  mGradientRamp.reset( ramp );
 
 
  662  return a.
x() < b.
x();
 
 
  668  calcSecondDerivativeArray();
 
 
  672  : mControlPoints( controlPoints )
 
  674  std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  675  calcSecondDerivativeArray();
 
 
  680  delete [] mSecondDerivativeArray;
 
 
  684  : mControlPoints( other.mControlPoints )
 
  686  if ( other.mSecondDerivativeArray )
 
  688    mSecondDerivativeArray = 
new double[ mControlPoints.count()];
 
  689    memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray, 
sizeof( 
double ) * mControlPoints.count() );
 
 
  695  if ( 
this != &other )
 
  697    mControlPoints = other.mControlPoints;
 
  698    if ( other.mSecondDerivativeArray )
 
  700      delete [] mSecondDerivativeArray;
 
  701      mSecondDerivativeArray = 
new double[ mControlPoints.count()];
 
  702      memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray, 
sizeof( 
double ) * mControlPoints.count() );
 
 
  710  mControlPoints = points;
 
  711  std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  712  for ( 
int i = 0; i < mControlPoints.count(); ++i )
 
  714    mControlPoints[ i ] = 
QgsPointXY( std::clamp( mControlPoints.at( i ).x(), 0.0, 1.0 ),
 
  715                                      std::clamp( mControlPoints.at( i ).y(), 0.0, 1.0 ) );
 
  717  calcSecondDerivativeArray();
 
 
  723  if ( mControlPoints.contains( point ) )
 
  726  mControlPoints << point;
 
  727  std::sort( mControlPoints.begin(), mControlPoints.end(), 
sortByX );
 
  728  calcSecondDerivativeArray();
 
 
  733  for ( 
int i = 0; i < mControlPoints.count(); ++i )
 
  738      mControlPoints.removeAt( i );
 
  742  calcSecondDerivativeArray();
 
 
  751  int n = mControlPoints.count();
 
  753    return std::clamp( x,  0.0, 1.0 ); 
 
  757    if ( x <= mControlPoints.at( 0 ).x() )
 
  758      return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
 
  759    else if ( x >= mControlPoints.at( n - 1 ).x() )
 
  760      return std::clamp( mControlPoints.at( 1 ).y(), 0.0, 1.0 );
 
  763      double dx = mControlPoints.at( 1 ).x() - mControlPoints.at( 0 ).x();
 
  764      double dy = mControlPoints.at( 1 ).y() - mControlPoints.at( 0 ).y();
 
  765      return std::clamp( ( x - mControlPoints.at( 0 ).x() ) * ( dy / dx ) + mControlPoints.at( 0 ).y(), 0.0,  1.0 );
 
  770  if ( x <= mControlPoints.at( 0 ).x() )
 
  771    return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
 
  772  if ( x >= mControlPoints.at( n - 1 ).x() )
 
  773    return std::clamp( mControlPoints.at( n - 1 ).y(), 0.0, 1.0 );
 
  776  QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  781  for ( 
int i = 0; i < n - 1; ++i )
 
  783    if ( x < nextControlPoint.
x() )
 
  786      double h = nextControlPoint.
x() - currentControlPoint.
x();
 
  787      double t = ( x - currentControlPoint.
x() ) / h;
 
  791      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] ),
 
  796    if ( pointIt == mControlPoints.constEnd() )
 
  799    currentControlPoint = nextControlPoint;
 
  800    nextControlPoint = *pointIt;
 
  804  return std::clamp( x, 0.0, 1.0 );
 
 
  813  QVector<double> result;
 
  815  int n = mControlPoints.count();
 
  819    const auto constX = x;
 
  820    for ( 
double i : constX )
 
  827  QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  833  double currentX = x.at( xIndex );
 
  835  while ( currentX <= currentControlPoint.
x() )
 
  837    result << std::clamp( currentControlPoint.
y(), 0.0, 1.0 );
 
  839    currentX = x.at( xIndex );
 
  842  for ( 
int i = 0; i < n - 1; ++i )
 
  844    while ( currentX < nextControlPoint.
x() )
 
  847      double h = nextControlPoint.
x() - currentControlPoint.
x();
 
  849      double t = ( currentX - currentControlPoint.
x() ) / h;
 
  853      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 );
 
  855      if ( xIndex == x.count() )
 
  858      currentX = x.at( xIndex );
 
  862    if ( pointIt == mControlPoints.constEnd() )
 
  865    currentControlPoint = nextControlPoint;
 
  866    nextControlPoint = *pointIt;
 
  870  while ( xIndex < x.count() )
 
  872    result << std::clamp( nextControlPoint.
y(), 0.0, 1.0 );
 
 
  881  QString xString = elem.attribute( QStringLiteral( 
"x" ) );
 
  882  QString yString = elem.attribute( QStringLiteral( 
"y" ) );
 
  884  QStringList xVals = xString.split( 
',' );
 
  885  QStringList yVals = yString.split( 
',' );
 
  886  if ( xVals.count() != yVals.count() )
 
  889  QList< QgsPointXY > newPoints;
 
  891  for ( 
int i = 0; i < xVals.count(); ++i )
 
  893    double x = xVals.at( i ).toDouble( &ok );
 
  896    double y = yVals.at( i ).toDouble( &ok );
 
 
  909  const auto constMControlPoints = mControlPoints;
 
  910  for ( 
const QgsPointXY &p : constMControlPoints )
 
  916  transformElem.setAttribute( QStringLiteral( 
"x" ), x.join( 
',' ) );
 
  917  transformElem.setAttribute( QStringLiteral( 
"y" ), 
y.join( 
',' ) );
 
 
  924  QVariantMap transformMap;
 
  928  const auto constMControlPoints = mControlPoints;
 
  929  for ( 
const QgsPointXY &p : constMControlPoints )
 
  935  transformMap.insert( QStringLiteral( 
"x" ), x.join( 
',' ) );
 
  936  transformMap.insert( QStringLiteral( 
"y" ), 
y.join( 
',' ) );
 
 
  943  QVariantMap transformMap = transformer.toMap();
 
  945  QString xString = transformMap.value( QStringLiteral( 
"x" ) ).toString();
 
  946  QString yString = transformMap.value( QStringLiteral( 
"y" ) ).toString();
 
  948  QStringList xVals = xString.split( 
',' );
 
  949  QStringList yVals = yString.split( 
',' );
 
  950  if ( xVals.count() != yVals.count() )
 
  953  QList< QgsPointXY > newPoints;
 
  955  for ( 
int i = 0; i < xVals.count(); ++i )
 
  957    double x = xVals.at( i ).toDouble( &ok );
 
  960    double y = yVals.at( i ).toDouble( &ok );
 
 
  973void QgsCurveTransform::calcSecondDerivativeArray()
 
  975  int n = mControlPoints.count();
 
  979  delete[] mSecondDerivativeArray;
 
  981  double *matrix = 
new double[ n * 3 ];
 
  982  double *result = 
new double[ n ];
 
  987  QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
 
  994  for ( 
int i = 1; i < n - 1; ++i )
 
  996    matrix[i * 3 + 0 ] = ( pointI.
x() - pointIm1.
x() ) / 6.0;
 
  997    matrix[i * 3 + 1 ] = ( pointIp1.
x() - pointIm1.
x() ) / 3.0;
 
  998    matrix[i * 3 + 2 ] = ( pointIp1.
x() - pointI.
x() ) / 6.0;
 
  999    result[i] = ( pointIp1.
y() - pointI.
y() ) / ( pointIp1.
x() - pointI.
x() ) - ( pointI.
y() - pointIm1.
y() ) / ( pointI.
x() - pointIm1.
x() );
 
 1005    if ( pointIt == mControlPoints.constEnd() )
 
 1008    pointIp1 = *pointIt;
 
 1010  matrix[( n - 1 ) * 3 + 0] = 0;
 
 1011  matrix[( n - 1 ) * 3 + 1] = 1;
 
 1012  matrix[( n - 1 ) * 3 + 2] = 0;
 
 1016  for ( 
int i = 1; i < n; ++i )
 
 1018    double k = matrix[i * 3 + 0] / matrix[( i - 1 ) * 3 + 1];
 
 1019    matrix[i * 3 + 1] -= k * matrix[( i - 1 ) * 3 + 2];
 
 1020    matrix[i * 3 + 0] = 0;
 
 1021    result[i] -= k * result[i - 1];
 
 1024  for ( 
int i = n - 2; i >= 0; --i )
 
 1026    double k = matrix[i * 3 + 2] / matrix[( i + 1 ) * 3 + 1];
 
 1027    matrix[i * 3 + 1] -= k * matrix[( i + 1 ) * 3 + 0];
 
 1028    matrix[i * 3 + 2] = 0;
 
 1029    result[i] -= k * result[i + 1];
 
 1033  mSecondDerivativeArray = 
new double[n];
 
 1034  for ( 
int i = 0; i < n; ++i )
 
 1036    mSecondDerivativeArray[i] = result[i] / matrix[( i * 3 ) + 1];
 
Abstract base class for color ramps.
 
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
 
static QString colorToString(const QColor &color)
Encodes a color into a string value.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
An expression node which takes its 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.
 
Handles 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.
 
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
 
static std::unique_ptr< QgsColorRamp > loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
 
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
 
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)