76 QVariantMap transformerMap = transformer.toMap();
78 mMinValue = transformerMap.value( QStringLiteral(
"minValue" ), 0.0 ).toDouble();
79 mMaxValue = transformerMap.value( QStringLiteral(
"maxValue" ), 1.0 ).toDouble();
82 QVariantMap curve = transformerMap.value( QStringLiteral(
"curve" ) ).toMap();
84 if ( !curve.isEmpty() )
95 QVariantMap transformerMap;
97 transformerMap.insert( QStringLiteral(
"minValue" ),
mMinValue );
98 transformerMap.insert( QStringLiteral(
"maxValue" ),
mMaxValue );
102 transformerMap.insert( QStringLiteral(
"curve" ),
mCurveTransform->toVariant() );
104 return transformerMap;
109 baseExpression.clear();
139 , mMinOutput( minOutput )
140 , mMaxOutput( maxOutput )
141 , mNullOutput( nullOutput )
162 transformerMap.insert( QStringLiteral(
"minOutput" ), mMinOutput );
163 transformerMap.insert( QStringLiteral(
"maxOutput" ), mMaxOutput );
164 transformerMap.insert( QStringLiteral(
"nullOutput" ), mNullOutput );
165 transformerMap.insert( QStringLiteral(
"exponent" ), mExponent );
167 return transformerMap;
174 QVariantMap transformerMap = transformer.toMap();
176 mMinOutput = transformerMap.value( QStringLiteral(
"minOutput" ), 0.0 ).toDouble();
177 mMaxOutput = transformerMap.value( QStringLiteral(
"maxOutput" ), 1.0 ).toDouble();
178 mNullOutput = transformerMap.value( QStringLiteral(
"nullOutput" ), 0.0 ).toDouble();
179 mExponent = transformerMap.value( QStringLiteral(
"exponent" ), 1.0 ).toDouble();
186 return std::clamp( input, mMinOutput, mMaxOutput );
203 double dblValue = v.toDouble( &ok );
208 return value( dblValue );
218 QString minValueString = QString::number(
mMinValue );
219 QString maxValueString = QString::number(
mMaxValue );
220 QString minOutputString = QString::number( mMinOutput );
221 QString maxOutputString = QString::number( mMaxOutput );
222 QString nullOutputString = QString::number( mNullOutput );
223 QString exponentString = QString::number( mExponent );
226 return QStringLiteral(
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, nullOutputString );
228 return QStringLiteral(
"coalesce(scale_polynomial(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minOutputString, maxOutputString, exponentString, nullOutputString );
235 double nullValue = 0.0;
238 baseExpression.clear();
250 QList<QgsExpressionNode *> args = f->
args()->
list();
299 baseExpression = args[0]->dump();
337 transformerMap.insert( QStringLiteral(
"scaleType" ),
static_cast< int >( mType ) );
338 transformerMap.insert( QStringLiteral(
"minSize" ), mMinSize );
339 transformerMap.insert( QStringLiteral(
"maxSize" ), mMaxSize );
340 transformerMap.insert( QStringLiteral(
"nullSize" ), mNullSize );
341 transformerMap.insert( QStringLiteral(
"exponent" ), mExponent );
343 return transformerMap;
350 QVariantMap transformerMap = transformer.toMap();
352 mType =
static_cast< ScaleType >( transformerMap.value( QStringLiteral(
"scaleType" ),
Linear ).toInt() );
353 mMinSize = transformerMap.value( QStringLiteral(
"minSize" ), 0.0 ).toDouble();
354 mMaxSize = transformerMap.value( QStringLiteral(
"maxSize" ), 1.0 ).toDouble();
355 mNullSize = transformerMap.value( QStringLiteral(
"nullSize" ), 0.0 ).toDouble();
356 mExponent = transformerMap.value( QStringLiteral(
"exponent" ), 1.0 ).toDouble();
407 double dblValue = value.toDouble( &ok );
412 return size( dblValue );
422 QString minValueString = QString::number(
mMinValue );
423 QString maxValueString = QString::number(
mMaxValue );
424 QString minSizeString = QString::number( mMinSize );
425 QString maxSizeString = QString::number( mMaxSize );
426 QString nullSizeString = QString::number( mNullSize );
427 QString exponentString = QString::number( mExponent );
432 return QStringLiteral(
"coalesce(scale_linear(%1, %2, %3, %4, %5), %6)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, nullSizeString );
437 return QStringLiteral(
"coalesce(scale_polynomial(%1, %2, %3, %4, %5, %6), %7)" ).arg( baseExpression, minValueString, maxValueString, minSizeString, maxSizeString, exponentString, nullSizeString );
451 baseExpression.clear();
463 QList<QgsExpressionNode *> args = f->
args()->
list();
520 baseExpression = args[0]->dump();
535 , mGradientRamp( ramp )
544 , mGradientRamp( other.mGradientRamp ? other.mGradientRamp->
clone() : nullptr )
545 , mNullColor( other.mNullColor )
546 , mRampName( other.mRampName )
553 if ( &other ==
this )
559 mGradientRamp.reset( other.mGradientRamp ? other.mGradientRamp->clone() :
nullptr );
560 mNullColor = other.mNullColor;
561 mRampName = other.mRampName;
568 mGradientRamp ? mGradientRamp->clone() :
nullptr,
570 c->setRampName( mRampName );
585 transformerMap.insert( QStringLiteral(
"rampName" ), mRampName );
587 return transformerMap;
592 QVariantMap transformerMap = definition.toMap();
596 mGradientRamp.reset(
nullptr );
597 if ( transformerMap.contains( QStringLiteral(
"colorramp" ) ) )
603 mRampName = transformerMap.value( QStringLiteral(
"rampName" ) ).toString();
615 double dblValue = value.toDouble( &ok );
620 return color( dblValue );
630 if ( !mGradientRamp )
633 QString minValueString = QString::number(
mMinValue );
634 QString maxValueString = QString::number(
mMaxValue );
635 QString nullColorString = mNullColor.name();
637 return QStringLiteral(
"coalesce(ramp_color('%1',scale_linear(%2, %3, %4, 0, 1)), '%5')" ).arg( !mRampName.isEmpty() ? mRampName : QStringLiteral(
"custom ramp" ),
638 baseExpression, minValueString, maxValueString, nullColorString );
646 if ( !mGradientRamp )
649 return mGradientRamp->color( scaledVal );
654 return mGradientRamp.get();
659 mGradientRamp.reset( ramp );
669 return a.
x() < b.
x();
675 calcSecondDerivativeArray();
681 std::sort( mControlPoints.begin(), mControlPoints.end(),
sortByX );
682 calcSecondDerivativeArray();
687 delete [] mSecondDerivativeArray;
691 : mControlPoints( other.mControlPoints )
693 if ( other.mSecondDerivativeArray )
695 mSecondDerivativeArray = new double[ mControlPoints.count()];
696 memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray, sizeof( double ) * mControlPoints.count() );
702 if (
this != &other )
704 mControlPoints = other.mControlPoints;
705 if ( other.mSecondDerivativeArray )
707 delete [] mSecondDerivativeArray;
708 mSecondDerivativeArray =
new double[ mControlPoints.count()];
709 memcpy( mSecondDerivativeArray, other.mSecondDerivativeArray,
sizeof(
double ) * mControlPoints.count() );
717 mControlPoints = points;
718 std::sort( mControlPoints.begin(), mControlPoints.end(),
sortByX );
719 for (
int i = 0; i < mControlPoints.count(); ++i )
721 mControlPoints[ i ] =
QgsPointXY( std::clamp( mControlPoints.at( i ).x(), 0.0, 1.0 ),
722 std::clamp( mControlPoints.at( i ).y(), 0.0, 1.0 ) );
724 calcSecondDerivativeArray();
730 if ( mControlPoints.contains( point ) )
733 mControlPoints << point;
734 std::sort( mControlPoints.begin(), mControlPoints.end(),
sortByX );
735 calcSecondDerivativeArray();
740 for (
int i = 0; i < mControlPoints.count(); ++i )
745 mControlPoints.removeAt( i );
749 calcSecondDerivativeArray();
758 int n = mControlPoints.count();
760 return std::clamp( x, 0.0, 1.0 );
764 if ( x <= mControlPoints.at( 0 ).x() )
765 return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
766 else if ( x >= mControlPoints.at( n - 1 ).x() )
767 return std::clamp( mControlPoints.at( 1 ).y(), 0.0, 1.0 );
770 double dx = mControlPoints.at( 1 ).x() - mControlPoints.at( 0 ).x();
771 double dy = mControlPoints.at( 1 ).y() - mControlPoints.at( 0 ).y();
772 return std::clamp( ( x - mControlPoints.at( 0 ).x() ) * ( dy / dx ) + mControlPoints.at( 0 ).y(), 0.0, 1.0 );
777 if ( x <= mControlPoints.at( 0 ).x() )
778 return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 );
779 if ( x >= mControlPoints.at( n - 1 ).x() )
780 return std::clamp( mControlPoints.at( n - 1 ).y(), 0.0, 1.0 );
783 QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
788 for (
int i = 0; i < n - 1; ++i )
790 if ( x < nextControlPoint.
x() )
793 double h = nextControlPoint.
x() - currentControlPoint.
x();
794 double t = ( x - currentControlPoint.
x() ) / h;
798 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] ),
803 if ( pointIt == mControlPoints.constEnd() )
806 currentControlPoint = nextControlPoint;
807 nextControlPoint = *pointIt;
811 return std::clamp( x, 0.0, 1.0 );
820 QVector<double> result;
822 int n = mControlPoints.count();
826 const auto constX = x;
827 for (
double i : constX )
834 QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
840 double currentX = x.at( xIndex );
842 while ( currentX <= currentControlPoint.
x() )
844 result << std::clamp( currentControlPoint.
y(), 0.0, 1.0 );
846 currentX = x.at( xIndex );
849 for (
int i = 0; i < n - 1; ++i )
851 while ( currentX < nextControlPoint.
x() )
854 double h = nextControlPoint.
x() - currentControlPoint.
x();
856 double t = ( currentX - currentControlPoint.
x() ) / h;
860 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 );
862 if ( xIndex == x.count() )
865 currentX = x.at( xIndex );
869 if ( pointIt == mControlPoints.constEnd() )
872 currentControlPoint = nextControlPoint;
873 nextControlPoint = *pointIt;
877 while ( xIndex < x.count() )
879 result << std::clamp( nextControlPoint.
y(), 0.0, 1.0 );
888 QString xString = elem.attribute( QStringLiteral(
"x" ) );
889 QString yString = elem.attribute( QStringLiteral(
"y" ) );
891 QStringList xVals = xString.split(
',' );
892 QStringList yVals = yString.split(
',' );
893 if ( xVals.count() != yVals.count() )
896 QList< QgsPointXY > newPoints;
898 for (
int i = 0; i < xVals.count(); ++i )
900 double x = xVals.at( i ).toDouble( &ok );
903 double y = yVals.at( i ).toDouble( &ok );
916 const auto constMControlPoints = mControlPoints;
917 for (
const QgsPointXY &p : constMControlPoints )
923 transformElem.setAttribute( QStringLiteral(
"x" ), x.join(
',' ) );
924 transformElem.setAttribute( QStringLiteral(
"y" ),
y.join(
',' ) );
931 QVariantMap transformMap;
935 const auto constMControlPoints = mControlPoints;
936 for (
const QgsPointXY &p : constMControlPoints )
942 transformMap.insert( QStringLiteral(
"x" ), x.join(
',' ) );
943 transformMap.insert( QStringLiteral(
"y" ),
y.join(
',' ) );
950 QVariantMap transformMap = transformer.toMap();
952 QString xString = transformMap.value( QStringLiteral(
"x" ) ).toString();
953 QString yString = transformMap.value( QStringLiteral(
"y" ) ).toString();
955 QStringList xVals = xString.split(
',' );
956 QStringList yVals = yString.split(
',' );
957 if ( xVals.count() != yVals.count() )
960 QList< QgsPointXY > newPoints;
962 for (
int i = 0; i < xVals.count(); ++i )
964 double x = xVals.at( i ).toDouble( &ok );
967 double y = yVals.at( i ).toDouble( &ok );
980void QgsCurveTransform::calcSecondDerivativeArray()
982 int n = mControlPoints.count();
986 delete[] mSecondDerivativeArray;
988 double *matrix =
new double[ n * 3 ];
989 double *result =
new double[ n ];
994 QList<QgsPointXY>::const_iterator pointIt = mControlPoints.constBegin();
1001 for (
int i = 1; i < n - 1; ++i )
1003 matrix[i * 3 + 0 ] = ( pointI.
x() - pointIm1.
x() ) / 6.0;
1004 matrix[i * 3 + 1 ] = ( pointIp1.
x() - pointIm1.
x() ) / 3.0;
1005 matrix[i * 3 + 2 ] = ( pointIp1.
x() - pointI.
x() ) / 6.0;
1006 result[i] = ( pointIp1.
y() - pointI.
y() ) / ( pointIp1.
x() - pointI.
x() ) - ( pointI.
y() - pointIm1.
y() ) / ( pointI.
x() - pointIm1.
x() );
1012 if ( pointIt == mControlPoints.constEnd() )
1015 pointIp1 = *pointIt;
1017 matrix[( n - 1 ) * 3 + 0] = 0;
1018 matrix[( n - 1 ) * 3 + 1] = 1;
1019 matrix[( n - 1 ) * 3 + 2] = 0;
1023 for (
int i = 1; i < n; ++i )
1025 double k = matrix[i * 3 + 0] / matrix[( i - 1 ) * 3 + 1];
1026 matrix[i * 3 + 1] -= k * matrix[( i - 1 ) * 3 + 2];
1027 matrix[i * 3 + 0] = 0;
1028 result[i] -= k * result[i - 1];
1031 for (
int i = n - 2; i >= 0; --i )
1033 double k = matrix[i * 3 + 2] / matrix[( i + 1 ) * 3 + 1];
1034 matrix[i * 3 + 1] -= k * matrix[( i + 1 ) * 3 + 0];
1035 matrix[i * 3 + 2] = 0;
1036 result[i] -= k * result[i + 1];
1040 mSecondDerivativeArray =
new double[n];
1041 for (
int i = 0; i < n; ++i )
1043 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.
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).