@@ -442,29 +442,69 @@ static QVariant fcnRnd( const QVariantList& values, QgsFeature* , QgsExpression*
442
442
static QVariant fcnLinearScale ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
443
443
{
444
444
double val = getDoubleValue ( values.at ( 0 ), parent );
445
- double domain_min = getDoubleValue ( values.at ( 1 ), parent );
446
- double domain_max = getDoubleValue ( values.at ( 2 ), parent );
447
- double range_min = getDoubleValue ( values.at ( 3 ), parent );
448
- double range_max = getDoubleValue ( values.at ( 4 ), parent );
445
+ double domainMin = getDoubleValue ( values.at ( 1 ), parent );
446
+ double domainMax = getDoubleValue ( values.at ( 2 ), parent );
447
+ double rangeMin = getDoubleValue ( values.at ( 3 ), parent );
448
+ double rangeMax = getDoubleValue ( values.at ( 4 ), parent );
449
+
450
+ if ( domainMin >= domainMax )
451
+ {
452
+ parent->setEvalErrorString ( QObject::tr ( " Domain max must be greater than domain min" ) );
453
+ return QVariant ();
454
+ }
449
455
450
456
// outside of domain?
451
- if ( val >= domain_max )
457
+ if ( val >= domainMax )
452
458
{
453
- return range_max ;
459
+ return rangeMax ;
454
460
}
455
- else if ( val <= domain_min )
461
+ else if ( val <= domainMin )
456
462
{
457
- return range_min ;
463
+ return rangeMin ;
458
464
}
459
465
460
466
// calculate linear scale
461
- double m = ( range_max - range_min ) / ( domain_max - domain_min );
462
- double c = range_min - ( domain_min * m );
467
+ double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
468
+ double c = rangeMin - ( domainMin * m );
463
469
464
470
// Return linearly scaled value
465
471
return QVariant ( m * val + c );
466
472
}
467
473
474
+ static QVariant fcnExpScale ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
475
+ {
476
+ double val = getDoubleValue ( values.at ( 0 ), parent );
477
+ double domainMin = getDoubleValue ( values.at ( 1 ), parent );
478
+ double domainMax = getDoubleValue ( values.at ( 2 ), parent );
479
+ double rangeMin = getDoubleValue ( values.at ( 3 ), parent );
480
+ double rangeMax = getDoubleValue ( values.at ( 4 ), parent );
481
+ double exponent = getDoubleValue ( values.at ( 5 ), parent );
482
+
483
+ if ( domainMin >= domainMax )
484
+ {
485
+ parent->setEvalErrorString ( QObject::tr ( " Domain max must be greater than domain min" ) );
486
+ return QVariant ();
487
+ }
488
+ if ( exponent <= 0 )
489
+ {
490
+ parent->setEvalErrorString ( QObject::tr ( " Exponent must be greater than 0" ) );
491
+ return QVariant ();
492
+ }
493
+
494
+ // outside of domain?
495
+ if ( val >= domainMax )
496
+ {
497
+ return rangeMax;
498
+ }
499
+ else if ( val <= domainMin )
500
+ {
501
+ return rangeMin;
502
+ }
503
+
504
+ // Return exponentially scaled value
505
+ return QVariant ((( rangeMax - rangeMin ) / pow ( domainMax - domainMin, exponent ) ) * pow ( val - domainMin, exponent ) + rangeMin );
506
+ }
507
+
468
508
static QVariant fcnMax ( const QVariantList& values, QgsFeature* , QgsExpression *parent )
469
509
{
470
510
// initially set max as first value
@@ -501,6 +541,27 @@ static QVariant fcnMin( const QVariantList& values, QgsFeature* , QgsExpression
501
541
return QVariant ( minVal );
502
542
}
503
543
544
+ static QVariant fcnClamp ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
545
+ {
546
+ double minValue = getDoubleValue ( values.at ( 0 ), parent );
547
+ double testValue = getDoubleValue ( values.at ( 1 ), parent );
548
+ double maxValue = getDoubleValue ( values.at ( 2 ), parent );
549
+
550
+ // force testValue to sit inside the range specified by the min and max value
551
+ if ( testValue <= minValue )
552
+ {
553
+ return QVariant ( minValue );
554
+ }
555
+ else if ( testValue >= maxValue )
556
+ {
557
+ return QVariant ( maxValue );
558
+ }
559
+ else
560
+ {
561
+ return QVariant ( testValue );
562
+ }
563
+ }
564
+
504
565
static QVariant fcnFloor ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
505
566
{
506
567
double x = getDoubleValue ( values.at ( 0 ), parent );
@@ -1342,8 +1403,8 @@ const QStringList &QgsExpression::BuiltinFunctions()
1342
1403
<< " abs" << " sqrt" << " cos" << " sin" << " tan"
1343
1404
<< " asin" << " acos" << " atan" << " atan2"
1344
1405
<< " exp" << " ln" << " log10" << " log"
1345
- << " round" << " rand" << " randf" << " max" << " min"
1346
- << " scale_linear" << " floor" << " ceil"
1406
+ << " round" << " rand" << " randf" << " max" << " min" << " clamp "
1407
+ << " scale_linear" << " scale_exp " << " floor" << " ceil"
1347
1408
<< " toint" << " toreal" << " tostring"
1348
1409
<< " todatetime" << " todate" << " totime" << " tointerval"
1349
1410
<< " coalesce" << " regexp_match" << " $now" << " age" << " year"
@@ -1389,7 +1450,9 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
1389
1450
<< new StaticFunction ( " randf" , 2 , fcnRndF, QObject::tr ( " Math" ) )
1390
1451
<< new StaticFunction ( " max" , -1 , fcnMax, QObject::tr ( " Math" ) )
1391
1452
<< new StaticFunction ( " min" , -1 , fcnMin, QObject::tr ( " Math" ) )
1453
+ << new StaticFunction ( " clamp" , 3 , fcnClamp, QObject::tr ( " Math" ) )
1392
1454
<< new StaticFunction ( " scale_linear" , 5 , fcnLinearScale, QObject::tr ( " Math" ) )
1455
+ << new StaticFunction ( " scale_exp" , 6 , fcnExpScale, QObject::tr ( " Math" ) )
1393
1456
<< new StaticFunction ( " floor" , 1 , fcnFloor, QObject::tr ( " Math" ) )
1394
1457
<< new StaticFunction ( " ceil" , 1 , fcnCeil, QObject::tr ( " Math" ) )
1395
1458
<< new StaticFunction ( " $pi" , 0 , fcnPi, QObject::tr ( " Math" ) )
0 commit comments