70#include <QCryptographicHash>
71#include <QMimeDatabase>
72#include <QProcessEnvironment>
73#include <QRegularExpression>
78using namespace Qt::StringLiterals;
99 QVariantList argValues;
103 const QList< QgsExpressionNode * > argList = args->
list();
104 argValues.reserve( argList.size() );
111 v = QVariant::fromValue( n );
115 v = n->eval( parent, context );
117 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
118 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
121 argValues.append( v );
126 return func( argValues, context, parent, node );
137 return QStringList();
164 return mGroups.isEmpty() ? false : mGroups.contains( u
"deprecated"_s );
169 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
180 const QString &fnname,
183 const QString &group,
184 const QString &helpText,
188 const QStringList &aliases,
193 , mAliases( aliases )
194 , mUsesGeometry( false )
195 , mUsesGeometryFunc( usesGeometry )
196 , mReferencedColumnsFunc( referencedColumns )
207 if ( mUsesGeometryFunc )
208 return mUsesGeometryFunc( node );
210 return mUsesGeometry;
220 if ( mReferencedColumnsFunc )
221 return mReferencedColumnsFunc( node );
223 return mReferencedColumns;
229 return mIsStaticFunc( node, parent, context );
237 return mPrepareFunc( node, parent, context );
249 mIsStaticFunc =
nullptr;
255 mPrepareFunc = prepareFunc;
260 if ( node && node->
args() )
262 const QList< QgsExpressionNode * > argList = node->
args()->
list();
265 if ( !argNode->isStatic( parent, context ) )
275 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
276 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
277 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
279 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
286 double current = start + step;
287 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
310 return QVariant::fromValue( geom );
321 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
323 if ( name ==
"feature"_L1 )
325 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
327 else if ( name ==
"id"_L1 )
329 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
331 else if ( name ==
"geometry"_L1 )
333 return fcnGeometry( values, context, parent, node );
343 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
352 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
354 return expression.evaluate( context );
359 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
360 return QVariant( std::sqrt( x ) );
365 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
366 return QVariant( std::fabs( val ) );
371 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
372 return ( deg * M_PI ) / 180;
376 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
377 return ( 180 * rad ) / M_PI;
381 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
382 return QVariant( std::sin( x ) );
386 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
387 return QVariant( std::cos( x ) );
391 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
392 return QVariant( std::tan( x ) );
396 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
397 return QVariant( std::asin( x ) );
401 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::acos( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
407 return QVariant( std::atan( x ) );
411 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
412 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
413 return QVariant( std::atan2( y, x ) );
417 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
418 return QVariant( std::exp( x ) );
422 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
425 return QVariant( std::log( x ) );
429 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
432 return QVariant( log10( x ) );
436 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
437 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
438 if ( x <= 0 || b <= 0 )
440 return QVariant( std::log( x ) / std::log( b ) );
444 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
445 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
449 std::random_device rd;
450 std::mt19937_64 generator( rd() );
452 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
455 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
458 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
463 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
464 std::hash<std::string> hasher;
465 seed = hasher( seedStr.toStdString() );
467 generator.seed( seed );
471 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
472 return QVariant( min + f * ( max - min ) );
476 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
477 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
481 std::random_device rd;
482 std::mt19937_64 generator( rd() );
484 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
487 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
490 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
495 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
496 std::hash<std::string> hasher;
497 seed = hasher( seedStr.toStdString() );
499 generator.seed( seed );
502 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
503 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
504 return QVariant( randomInteger );
507 return QVariant(
int( randomInteger ) );
512 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
513 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
514 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
515 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
516 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
518 if ( domainMin >= domainMax )
520 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
525 if ( val >= domainMax )
529 else if ( val <= domainMin )
535 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
536 double c = rangeMin - ( domainMin * m );
539 return QVariant( m * val +
c );
544 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
545 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
546 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
547 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
548 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
549 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
551 if ( domainMin >= domainMax )
553 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
563 if ( val >= domainMax )
567 else if ( val <= domainMin )
573 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
578 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
579 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
580 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
581 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
582 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
583 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
585 if ( domainMin >= domainMax )
587 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
597 if ( val >= domainMax )
601 else if ( val <= domainMin )
607 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
608 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
613 const double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
614 const double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
615 const double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
616 const double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
617 const double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
619 const double x1 = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
620 const double y1 = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
621 const double x2 = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
622 const double y2 = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
624 if ( x1 < 0.0 || x1 > 1.0 || y1 < 0.0 || y1 > 1.0 || x2 < 0.0 || x2 > 1.0 || y2 < 0.0 || y2 > 1.0 )
626 parent->
setEvalErrorString( QObject::tr(
"Cubic bezier control points must be between 0 and 1" ) );
630 if ( domainMin >= domainMax )
632 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
637 if ( val >= domainMax )
641 else if ( val <= domainMin )
647 const double t = ( val - domainMin ) / ( domainMax - domainMin );
650 const double cx = 3.0 * x1;
651 const double bx = 3.0 * ( x2 - x1 ) - cx;
652 const double ax = 1.0 - cx - bx;
653 const double cy = 3.0 * y1;
654 const double by = 3.0 * ( y2 - y1 ) - cy;
655 const double ay = 1.0 - cy - by;
657 constexpr double epsilon = 1e-6;
662 for (
int i = 0; i < 8; ++i )
664 const double x2val = ( ( ax * s + bx ) * s + cx ) * s - t;
665 if ( std::fabs( x2val ) < epsilon )
670 const double d2 = ( 3.0 * ax * s + 2.0 * bx ) * s + cx;
671 if ( std::fabs( d2 ) < 1e-6 )
694 while ( !solved && t0 < t1 )
696 const double x2val = ( ( ax * s + bx ) * s + cx ) * s;
697 if ( std::fabs( x2val - t ) < epsilon )
706 s = ( t1 - t0 ) * 0.5 + t0;
710 const double easedT = ( ( ay * s + by ) * s + cy ) * s;
711 return QVariant( ( rangeMax - rangeMin ) * easedT + rangeMin );
717 double maxVal = std::numeric_limits<double>::quiet_NaN();
718 for (
const QVariant &val : values )
721 if ( std::isnan( maxVal ) )
725 else if ( !std::isnan( testVal ) )
727 maxVal = std::max( maxVal, testVal );
731 if ( !std::isnan( maxVal ) )
733 result = QVariant( maxVal );
741 double minVal = std::numeric_limits<double>::quiet_NaN();
742 for (
const QVariant &val : values )
745 if ( std::isnan( minVal ) )
749 else if ( !std::isnan( testVal ) )
751 minVal = std::min( minVal, testVal );
755 if ( !std::isnan( minVal ) )
757 result = QVariant( minVal );
769 QVariant value = node->
eval( parent, context );
774 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
778 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
783 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
785 value = node->
eval( parent, context );
791 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
796 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
798 QString subExpression = node->
dump();
802 if ( values.count() > 3 )
804 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
807 if ( !nl || nl->value().isValid() )
812 if ( values.count() > 4 )
814 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
816 value = node->
eval( parent, context );
823 if ( values.count() > 5 )
825 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
828 if ( !nl || nl->value().isValid() )
830 orderBy = node->
dump();
835 QString aggregateError;
843 const QSet< QString > filterVars = filterExp.referencedVariables();
844 const QSet< QString > subExpVars = subExp.referencedVariables();
845 QSet<QString> allVars = filterVars + subExpVars;
847 bool isStatic =
true;
848 if ( filterVars.contains( u
"parent"_s ) || filterVars.contains( QString() ) || subExpVars.contains( u
"parent"_s ) || subExpVars.contains( QString() ) )
854 for (
const QString &varName : allVars )
857 if ( scope && !scope->
isStatic( varName ) )
865 if ( isStatic && !parameters.
orderBy.isEmpty() )
867 for (
const auto &orderByClause : std::as_const( parameters.
orderBy ) )
869 const QgsExpression &orderByExpression { orderByClause.expression() };
881 const QString contextHash = context->
uniqueHash( ok, allVars );
884 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
889 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
900 subContext.appendScope( subScope );
901 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
913 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
917 if ( !aggregateError.isEmpty() )
918 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
920 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
931 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
939 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
943 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
952 QVariant value = node->
eval( parent, context );
954 QString relationId = value.toString();
961 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
963 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
968 relation = relations.at( 0 );
975 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
977 value = node->
eval( parent, context );
983 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
988 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
990 QString subExpression = node->
dump();
994 if ( values.count() > 3 )
996 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
998 value = node->
eval( parent, context );
1000 parameters.
delimiter = value.toString();
1005 if ( values.count() > 4 )
1007 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
1010 if ( !nl || nl->value().isValid() )
1012 orderBy = node->
dump();
1023 const QString
cacheKey = u
"relagg:%1%:%2:%3:%4:%5:%6"_s.arg( relationId, vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1033 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1037 if ( !error.isEmpty() )
1038 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1040 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1050static QVariant fcnAggregateGeneric(
1056 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1064 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
1068 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1075 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1077 QString subExpression = node->
dump();
1081 if ( values.count() > 1 )
1083 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
1086 if ( !nl || nl->value().isValid() )
1087 groupBy = node->
dump();
1091 if ( values.count() > 2 )
1093 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
1096 if ( !nl || nl->value().isValid() )
1102 if ( orderByPos >= 0 && values.count() > orderByPos )
1104 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
1107 if ( !nl || nl->value().isValid() )
1109 orderBy = node->
dump();
1117 if ( !groupBy.isEmpty() )
1120 QVariant groupByValue = groupByExp.evaluate( context );
1122 if ( !parameters.
filter.isEmpty() )
1123 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1125 parameters.
filter = groupByClause;
1131 bool isStatic =
true;
1132 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1133 for (
const QString &varName : refVars )
1136 if ( scope && !scope->
isStatic( varName ) )
1147 const QString contextHash = context->
uniqueHash( ok, refVars );
1150 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
1155 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1167 subContext.appendScope( subScope );
1169 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1173 if ( !error.isEmpty() )
1174 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1176 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1281 if ( values.count() > 3 )
1283 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1285 QVariant value = node->
eval( parent, context );
1287 parameters.
delimiter = value.toString();
1298 if ( values.count() > 3 )
1300 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1302 QVariant value = node->
eval( parent, context );
1304 parameters.
delimiter = value.toString();
1320 QVariant scale = context->
variable( u
"map_scale"_s );
1325 const double v = scale.toDouble( &ok );
1333 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1334 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1335 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1338 if ( testValue <= minValue )
1340 return QVariant( minValue );
1342 else if ( testValue >= maxValue )
1344 return QVariant( maxValue );
1348 return QVariant( testValue );
1354 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1355 return QVariant( std::floor( x ) );
1360 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1361 return QVariant( std::ceil( x ) );
1366 const QVariant value = values.at( 0 );
1367 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1369 return QVariant(
false );
1371 else if ( value.userType() == QMetaType::QString )
1374 return QVariant( !value.toString().isEmpty() );
1376 else if ( QgsExpressionUtils::isList( value ) )
1378 return !value.toList().isEmpty();
1380 return QVariant( value.toBool() );
1384 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1388 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1392 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1397 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1398 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1399 if ( format.isEmpty() && !language.isEmpty() )
1401 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1402 return QVariant( QDateTime() );
1405 if ( format.isEmpty() && language.isEmpty() )
1406 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1408 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1409 QLocale locale = QLocale();
1410 if ( !language.isEmpty() )
1412 locale = QLocale( language );
1415 QDateTime datetime = locale.toDateTime( datetimestring, format );
1416 if ( !datetime.isValid() )
1418 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1419 datetime = QDateTime();
1421 return QVariant( datetime );
1426 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1427 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1428 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1430 const QDate date( year, month, day );
1431 if ( !date.isValid() )
1433 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1436 return QVariant( date );
1441 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1442 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1443 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1445 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1446 if ( !time.isValid() )
1448 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1451 return QVariant( time );
1456 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1457 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1458 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1459 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1460 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1461 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1463 const QDate date( year, month, day );
1464 if ( !date.isValid() )
1466 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1469 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1470 if ( !time.isValid() )
1472 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1475 return QVariant( QDateTime( date, time ) );
1480 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1484#if QT_FEATURE_timezone > 0
1485 if ( !timeZoneId.isEmpty() )
1487 tz = QTimeZone( timeZoneId.toUtf8() );
1490 if ( !tz.isValid() )
1492 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1497 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1499 return QVariant::fromValue( tz );
1504#if QT_FEATURE_timezone > 0
1505 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1506 if ( datetime.isValid() )
1508 return QVariant::fromValue( datetime.timeZone() );
1513 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1520#if QT_FEATURE_timezone > 0
1521 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1522 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1523 if ( datetime.isValid() && tz.isValid() )
1525 datetime.setTimeZone( tz );
1526 return QVariant::fromValue( datetime );
1531 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1538#if QT_FEATURE_timezone > 0
1539 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1540 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1541 if ( datetime.isValid() && tz.isValid() )
1543 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1548 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1555#if QT_FEATURE_timezone > 0
1556 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1557 if ( timeZone.isValid() )
1559 return QString( timeZone.id() );
1564 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1571 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1572 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1573 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1574 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1575 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1576 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1577 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1579 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1584 for (
const QVariant &value : values )
1595 const QVariant val1 = values.at( 0 );
1596 const QVariant val2 = values.at( 1 );
1606 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1607 return QVariant( str.toLower() );
1611 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1612 return QVariant( str.toUpper() );
1616 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1617 QStringList elems = str.split(
' ' );
1618 for (
int i = 0; i < elems.size(); i++ )
1620 if ( elems[i].size() > 1 )
1621 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1623 return QVariant( elems.join(
' '_L1 ) );
1628 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1629 return QVariant( str.trimmed() );
1634 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1636 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1638 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1639 str.replace( re, QString() );
1640 return QVariant( str );
1645 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1647 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1649 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1650 str.replace( re, QString() );
1651 return QVariant( str );
1656 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1657 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1663 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1664 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1670 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1671 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1678 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1684 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1685 return QVariant( QString( character ) );
1690 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1692 if ( value.isEmpty() )
1697 int res = value.at( 0 ).unicode();
1698 return QVariant( res );
1703 if ( values.length() == 2 || values.length() == 3 )
1705 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1706 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1708 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1721 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1725 return QVariant( geom.
length() );
1731 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1732 return QVariant( str.length() );
1737 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1742 double totalLength = 0;
1747 totalLength += line->length3D();
1752 totalLength += segmentized->length3D();
1762 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1763 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1764 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1769 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1771 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1772 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1773 QVector< QPair< QString, QString > > mapItems;
1775 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1777 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1781 std::sort( mapItems.begin(), mapItems.end(), [](
const QPair< QString, QString > &pair1,
const QPair< QString, QString > &pair2 ) { return ( pair1.first.length() > pair2.first.length() ); } );
1783 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1785 str = str.replace( it->first, it->second );
1788 return QVariant( str );
1790 else if ( values.count() == 3 )
1792 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1793 QVariantList before;
1795 bool isSingleReplacement =
false;
1797 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1799 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1803 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1806 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1808 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1809 isSingleReplacement =
true;
1813 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1816 if ( !isSingleReplacement && before.length() != after.length() )
1818 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1822 for (
int i = 0; i < before.length(); i++ )
1824 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1827 return QVariant( str );
1831 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1838 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1839 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1840 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1842 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1843 if ( !re.isValid() )
1845 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1848 return QVariant( str.replace( re, after ) );
1853 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1854 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1856 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1857 if ( !re.isValid() )
1859 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1862 return QVariant( ( str.indexOf( re ) + 1 ) );
1867 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1868 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1869 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1871 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1872 if ( !re.isValid() )
1874 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1878 QRegularExpressionMatch matches = re.match( str );
1879 if ( matches.hasMatch() )
1882 QStringList list = matches.capturedTexts();
1885 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1887 array += ( !( *it ).isEmpty() ) ? *it : empty;
1890 return QVariant( array );
1900 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1901 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1903 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1904 if ( !re.isValid() )
1906 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1911 QRegularExpressionMatch match = re.match( str );
1912 if ( match.hasMatch() )
1915 if ( match.lastCapturedIndex() > 0 )
1918 return QVariant( match.captured( 1 ) );
1923 return QVariant( match.captured( 0 ) );
1928 return QVariant(
"" );
1934 QString uuid = QUuid::createUuid().toString();
1935 if ( values.at( 0 ).toString().compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1936 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1937 else if ( values.at( 0 ).toString().compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1938 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1944 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1947 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1948 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1951 if ( values.at( 2 ).isValid() )
1952 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1958 from = str.size() + from;
1964 else if ( from > 0 )
1972 len = str.size() + len - from;
1979 return QVariant( str.mid( from, len ) );
1984 return QVariant( f.
id() );
1989 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1990 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1991 bool foundLayer =
false;
1992 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
1997 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1998 if ( !layer || !layer->dataProvider() )
2000 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2004 if ( bandNb < 1 || bandNb > layer->bandCount() )
2006 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
2012 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
2019 QgsMultiPointXY multiPoint = geom.asMultiPoint();
2020 if ( multiPoint.count() == 1 )
2022 point = multiPoint[0];
2031 double value = layer->dataProvider()->sample( point, bandNb );
2032 return std::isnan( value ) ? QVariant() : value;
2039 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2050 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2051 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2053 bool foundLayer =
false;
2054 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2058 [parent, bandNb, value](
QgsMapLayer *mapLayer ) -> QVariant {
2059 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
2060 if ( !layer || !layer->dataProvider() )
2062 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2066 if ( bandNb < 1 || bandNb > layer->bandCount() )
2068 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
2072 if ( std::isnan( value ) )
2074 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
2078 if ( !layer->dataProvider()->attributeTable( bandNb ) )
2083 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
2084 if ( data.isEmpty() )
2090 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
2091 for (
int idx = 0; idx < static_cast<int>( fields.count() ) && idx < static_cast<int>( data.count() ); ++idx )
2098 result.insert( fields.at( idx ).name, data.at( idx ) );
2108 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2129 if ( values.size() == 1 )
2131 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2134 else if ( values.size() == 2 )
2136 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2137 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2141 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2150 QString table { R
"html(
2153 <tr><th>%1</th></tr>
2156 <tr><td>%2</td></tr>
2160 if ( values.size() == 1 )
2162 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2166 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2170 if ( dict.isEmpty() )
2175 QStringList headers;
2178 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2180 headers.push_back( it.key().toHtmlEscaped() );
2181 cells.push_back( it.value().toString().toHtmlEscaped() );
2184 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2189 QString table { R
"html(
2194 if ( values.size() == 1 )
2196 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2200 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2204 if ( dict.isEmpty() )
2211 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2213 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2216 return table.arg( rows );
2224 layer = context->
variable( u
"layer"_s );
2229 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2231 layer = node->
eval( parent, context );
2242 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2246 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2247 if ( strength ==
"hard"_L1 )
2251 else if ( strength ==
"soft"_L1 )
2256 bool foundLayer =
false;
2257 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2261 [parent, feature, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2262 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2265 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2271 for (
int i = 0; i < fields.
size(); i++ )
2288 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2300 layer = context->
variable( u
"layer"_s );
2305 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2307 layer = node->
eval( parent, context );
2318 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2322 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2323 if ( strength ==
"hard"_L1 )
2327 else if ( strength ==
"soft"_L1 )
2332 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2334 bool foundLayer =
false;
2335 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2339 [parent, feature, attributeName, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2340 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2347 if ( fieldIndex == -1 )
2349 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2362 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2378 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2383 for (
int i = 0; i < fields.
count(); ++i )
2397 if ( values.isEmpty() )
2400 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2402 else if ( values.size() == 1 )
2404 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2405 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2407 else if ( values.size() == 2 )
2409 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2410 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2414 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2421 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2427 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2433 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2435 const QString fieldName { fields.
at( fieldIndex ).
name() };
2436 const QVariant attributeVal = feature.
attribute( fieldIndex );
2437 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2440 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2449 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2461 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2463 result.insert( fields.
at( fieldIndex ).
name(), value );
2478 bool evaluate =
true;
2482 if ( values.isEmpty() )
2485 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2487 else if ( values.size() == 1 )
2489 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2490 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2492 else if ( values.size() == 2 )
2494 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2495 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2497 else if ( values.size() == 3 )
2499 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2500 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2501 evaluate = values.value( 2 ).toBool();
2507 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2511 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2543 subContext.setFeature( feature );
2552 exp.prepare( &subContext );
2553 return exp.evaluate( &subContext ).toString();
2559 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2564 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2571 if ( values.isEmpty() )
2574 layer = context->
variable( u
"layer"_s );
2576 else if ( values.size() == 1 )
2578 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2579 layer = context->
variable( u
"layer"_s );
2581 else if ( values.size() == 2 )
2583 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2584 layer = values.at( 0 );
2588 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2592 bool foundLayer =
false;
2593 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2598 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2599 if ( !layer || !feature.
isValid() )
2618 if ( values.isEmpty() )
2619 layer = context->
variable( u
"layer"_s );
2620 else if ( values.count() == 1 )
2621 layer = values.at( 0 );
2624 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2628 bool foundLayer =
false;
2629 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2634 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2652 static QMap<QString, qlonglong> counterCache;
2653 QVariant functionResult;
2655 auto fetchAndIncrementFunc = [values, parent, &functionResult](
QgsMapLayer *mapLayer,
const QString &databaseArgument ) {
2658 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2663 database = decodedUri.value( u
"path"_s ).toString();
2664 if ( database.isEmpty() )
2666 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2671 database = databaseArgument;
2674 const QString table = values.at( 1 ).toString();
2675 const QString idColumn = values.at( 2 ).toString();
2676 const QString filterAttribute = values.at( 3 ).toString();
2677 const QVariant filterValue = values.at( 4 ).toString();
2678 const QVariantMap defaultValues = values.at( 5 ).toMap();
2684 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2687 functionResult = QVariant();
2691 QString errorMessage;
2692 QString currentValSql;
2694 qlonglong nextId = 0;
2695 bool cachedMode =
false;
2696 bool valueRetrieved =
false;
2698 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2705 auto cachedCounter = counterCache.find( cacheString );
2707 if ( cachedCounter != counterCache.end() )
2709 qlonglong &cachedValue = cachedCounter.value();
2710 nextId = cachedValue;
2712 cachedValue = nextId;
2713 valueRetrieved =
true;
2718 if ( !cachedMode || !valueRetrieved )
2720 int result = SQLITE_ERROR;
2723 if ( !filterAttribute.isNull() )
2728 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2730 if ( result == SQLITE_OK )
2733 if ( sqliteStatement.
step() == SQLITE_ROW )
2739 if ( cachedMode && result == SQLITE_OK )
2741 counterCache.insert( cacheString, nextId );
2743 QObject::connect( layer->
dataProvider()->
transaction(), &QgsTransaction::destroyed, [cacheString]() { counterCache.remove( cacheString ); } );
2745 valueRetrieved =
true;
2749 if ( valueRetrieved )
2758 if ( !filterAttribute.isNull() )
2764 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2767 vals << iter.value().toString();
2770 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2771 upsertSql +=
" VALUES "_L1;
2772 upsertSql +=
'(' + vals.join(
',' ) +
')';
2774 int result = SQLITE_ERROR;
2778 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2785 result = sqliteDb.
exec( upsertSql, errorMessage );
2787 if ( result == SQLITE_OK )
2789 functionResult = QVariant( nextId );
2794 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2795 functionResult = QVariant();
2800 functionResult = QVariant();
2803 bool foundLayer =
false;
2804 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer *layer ) { fetchAndIncrementFunc( layer, QString() ); }, foundLayer );
2807 const QString databasePath = values.at( 0 ).toString();
2811 return functionResult;
2824 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2829 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2832 return QVariant::fromValue( crs );
2838 for (
const QVariant &value : values )
2841 concat += QgsExpressionUtils::getStringValue( value, parent );
2848 if ( values.length() < 2 )
2850 parent->
setEvalErrorString( QObject::tr(
"Function concat_ws requires at least 2 arguments" ) );
2854 const QString separator = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2856 QStringList stringValues;
2857 stringValues.reserve( values.size() - 1 );
2858 for (
int i = 1; i < values.size(); ++i )
2860 const QVariant value = values.at( i );
2863 stringValues.append( QgsExpressionUtils::getStringValue( value, parent ) );
2867 return stringValues.join( separator );
2872 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2873 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2881 if ( values.isEmpty() || values[0].isNull() )
2890 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2891 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2892 return string.right( pos );
2897 if ( values.length() < 2 || values.length() > 3 )
2900 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2901 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2903 bool overlapping =
false;
2904 if ( values.length() == 3 )
2906 overlapping = values.at( 2 ).toBool();
2909 if ( substring.isEmpty() )
2910 return QVariant( 0 );
2915 count = input.count( substring );
2920 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2923 pos += substring.length();
2927 return QVariant( count );
2932 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2933 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2934 return string.left( pos );
2939 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2940 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2941 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2942 return string.leftJustified( length, fill.at( 0 ),
true );
2947 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2948 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2949 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2950 return string.rightJustified( length, fill.at( 0 ),
true );
2955 if ( values.size() < 1 )
2957 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2961 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2962 for (
int n = 1; n < values.length(); n++ )
2964 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2972 return QVariant( QDateTime::currentDateTime() );
2977 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2978 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2979 if ( format.isEmpty() && !language.isEmpty() )
2981 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2982 return QVariant( QDate() );
2985 if ( format.isEmpty() && language.isEmpty() )
2986 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2988 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2989 QLocale locale = QLocale();
2990 if ( !language.isEmpty() )
2992 locale = QLocale( language );
2995 QDate date = locale.toDate( datestring, format );
2996 if ( !date.isValid() )
2998 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
3001 return QVariant( date );
3006 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3007 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3008 if ( format.isEmpty() && !language.isEmpty() )
3010 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
3011 return QVariant( QTime() );
3014 if ( format.isEmpty() && language.isEmpty() )
3015 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
3017 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3018 QLocale locale = QLocale();
3019 if ( !language.isEmpty() )
3021 locale = QLocale( language );
3024 QTime time = locale.toTime( timestring, format );
3025 if ( !time.isValid() )
3027 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
3030 return QVariant( time );
3035 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
3044 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3045 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3046 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3048 QString formatString;
3049 if ( values.count() > 3 )
3050 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
3053 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
3057 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
3061 else if ( !formatString.isEmpty() )
3063 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
3067 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
3071 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
3077 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
3085 return floatToDegreeFormat( format, values, context, parent, node );
3092 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
3094 return ok ? QVariant( value ) : QVariant();
3100 return floatToDegreeFormat( format, values, context, parent, node );
3105 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3106 return static_cast< int >( decimalDegrees );
3111 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3112 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3113 return static_cast< int >( remainder * 60 );
3118 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3119 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3120 const double remainderInMinutes = remainder * 60;
3121 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
3123 return remainderSecondsFraction * 60;
3128 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3129 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3130 qint64 seconds = d2.secsTo( d1 );
3131 return QVariant::fromValue(
QgsInterval( seconds ) );
3136 if ( !values.at( 0 ).canConvert<QDate>() )
3139 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
3140 if ( !date.isValid() )
3145 return date.dayOfWeek() % 7;
3150 QVariant value = values.at( 0 );
3151 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3154 return QVariant( inter.
days() );
3158 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3159 return QVariant( d1.date().day() );
3165 QVariant value = values.at( 0 );
3166 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3169 return QVariant( inter.
years() );
3173 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3174 return QVariant( d1.date().year() );
3180 QVariant value = values.at( 0 );
3181 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3184 return QVariant( inter.
months() );
3188 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3189 return QVariant( d1.date().month() );
3195 QVariant value = values.at( 0 );
3196 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3199 return QVariant( inter.
weeks() );
3203 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3204 return QVariant( d1.date().weekNumber() );
3210 QVariant value = values.at( 0 );
3211 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3214 return QVariant( inter.
hours() );
3218 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3219 return QVariant( t1.hour() );
3225 QVariant value = values.at( 0 );
3226 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3229 return QVariant( inter.
minutes() );
3233 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3234 return QVariant( t1.minute() );
3240 QVariant value = values.at( 0 );
3241 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3244 return QVariant( inter.
seconds() );
3248 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3249 return QVariant( t1.second() );
3255 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3258 return QVariant( dt.toMSecsSinceEpoch() );
3268 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3270 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3275 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3278 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3281 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3287 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3290 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3299 if ( !dateTime.isValid() )
3304 const int year = dateTime.date().year();
3305 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3306 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3307 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3308 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3309 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3314 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3315 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3318 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3321 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3326 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3331 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3336 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3341 double declination = 0;
3348 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3360 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3361 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3364 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3367 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3372 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3377 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3382 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3387 double inclination = 0;
3394 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3406 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3407 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3410 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3413 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3418 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3423 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3428 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3433 double declination = 0;
3441 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3451 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3457 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3463 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3468 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3475 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3476 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3479 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3482 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3487 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3492 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3497 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3502 double declination = 0;
3510 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3520 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3526 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3532 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3537 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3542#define ENSURE_GEOM_TYPE( f, g, geomtype ) \
3543 if ( !( f ).hasGeometry() ) \
3544 return QVariant(); \
3545 QgsGeometry g = ( f ).geometry(); \
3546 if ( ( g ).type() != ( geomtype ) ) \
3553 if ( g.isMultipart() )
3555 return g.asMultiPoint().at( 0 ).x();
3559 return g.asPoint().x();
3567 if ( g.isMultipart() )
3569 return g.asMultiPoint().at( 0 ).y();
3573 return g.asPoint().y();
3587 if ( g.isEmpty() || !abGeom->
is3D() )
3600 if ( collection->numGeometries() > 0 )
3613 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3619 return QVariant( isValid );
3624 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3628 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3629#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
3634 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3636 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3639 const bool keepCollapsed = values.value( 2 ).toBool();
3644 valid = geom.
makeValid( method, keepCollapsed );
3648 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3652 return QVariant::fromValue( valid );
3657 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3663 for (
int i = 0; i < multiGeom.size(); ++i )
3665 array += QVariant::fromValue( multiGeom.at( i ) );
3673 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3685 QVariant result( centroid.
asPoint().
x() );
3691 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3703 QVariant result( centroid.
asPoint().
y() );
3709 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3727 if ( collection->numGeometries() == 1 )
3740 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3758 if ( collection->numGeometries() == 1 )
3771 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3776 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3803 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3820 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3837 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3842 bool ignoreClosing =
false;
3843 if ( values.length() > 1 )
3845 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3855 bool skipLast =
false;
3856 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3861 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++i )
3873 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3884 for (
int i = 0; i < line->numPoints() - 1; ++i )
3898 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3908 if ( collection->numGeometries() == 1 )
3915 if ( !curvePolygon )
3919 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3925 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3931 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3941 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3947 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3953 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3962 return QVariant::fromValue(
QgsGeometry( boundary ) );
3967 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3976 return QVariant::fromValue( merged );
3981 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3985 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3990 if ( sharedPaths.
isNull() )
3993 return QVariant::fromValue( sharedPaths );
3999 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4004 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4007 if ( simplified.
isNull() )
4015 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4020 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4025 if ( simplified.
isNull() )
4033 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4038 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
4039 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
4040 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4041 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
4043 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
4052 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4057 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4058 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4059 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4070 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4075 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4076 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4077 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4078 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4079 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4090 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4095 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4096 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4097 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4108 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4113 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4114 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4115 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4116 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4117 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4128 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4133 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4134 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4135 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4146 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4151 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4152 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4153 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4154 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4155 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4166 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4171 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4172 QVector< double > dashPattern;
4173 dashPattern.reserve( pattern.size() );
4174 for (
const QVariant &value : std::as_const( pattern ) )
4177 double v = value.toDouble( &ok );
4189 if ( dashPattern.size() % 2 != 0 )
4191 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4195 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4197 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4199 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4201 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4203 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4205 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4209 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4213 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4215 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4217 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4219 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4221 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4223 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4227 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4231 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4233 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4235 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4237 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4241 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4245 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4256 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4261 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4263 if ( densified.
isNull() )
4271 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4276 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4278 if ( densified.
isNull() )
4287 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4289 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4296 QVector< QgsGeometry > parts;
4297 parts.reserve( list.size() );
4298 for (
const QVariant &value : std::as_const( list ) )
4300 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4311 if ( values.count() < 2 || values.count() > 4 )
4313 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4317 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4318 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4319 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4320 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4321 switch ( values.count() )
4335 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4336 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4337 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4343 if ( values.empty() )
4348 QVector<QgsPoint> points;
4349 points.reserve( values.count() );
4351 auto addPoint = [&points](
const QgsGeometry &geom ) {
4365 for (
const QVariant &value : values )
4367 if ( value.userType() == QMetaType::Type::QVariantList )
4369 const QVariantList list = value.toList();
4370 for (
const QVariant &v : list )
4372 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4377 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4381 if ( points.count() < 2 )
4389 if ( values.count() < 1 )
4391 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4395 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4403 auto polygon = std::make_unique< QgsPolygon >();
4417 if ( !exteriorRing )
4420 polygon->setExteriorRing( exteriorRing->
segmentize() );
4423 for (
int i = 1; i < values.count(); ++i )
4425 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4447 polygon->addInteriorRing( ring->
segmentize() );
4450 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4455 auto tr = std::make_unique<QgsTriangle>();
4456 auto lineString = std::make_unique<QgsLineString>();
4457 lineString->clear();
4459 for (
const QVariant &value : values )
4461 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4483 lineString->addVertex( *point );
4486 tr->setExteriorRing( lineString.release() );
4488 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4493 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4500 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4501 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4523 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4528 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4535 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4536 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4537 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4538 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4558 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4559 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4564 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4571 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4578 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4581 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4588 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4627 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4633 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4648 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4654 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4660 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4669 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4693 return QVariant::fromValue( geom.
vertexAt( idx ) );
4701 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4703 const QVariant v = pointAt( geom, idx, parent );
4706 return QVariant( v.value<
QgsPoint>().
x() );
4712 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4714 return fcnOldXat( values, f, parent, node );
4716 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4718 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4721 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4727 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4729 const QVariant v = pointAt( geom, vertexNumber, parent );
4731 return QVariant( v.value<
QgsPoint>().
x() );
4741 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4743 const QVariant v = pointAt( geom, idx, parent );
4746 return QVariant( v.value<
QgsPoint>().
y() );
4752 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4754 return fcnOldYat( values, f, parent, node );
4756 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4758 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4761 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4767 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4769 const QVariant v = pointAt( geom, vertexNumber, parent );
4771 return QVariant( v.value<
QgsPoint>().
y() );
4778 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4784 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4786 const QVariant v = pointAt( geom, vertexNumber, parent );
4788 return QVariant( v.value<
QgsPoint>().
z() );
4795 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4801 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4803 const QVariant v = pointAt( geom, vertexNumber, parent );
4805 return QVariant( v.value<
QgsPoint>().
m() );
4813 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4815 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4821 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4827 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4832 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4839 ogcContext.
layer = mapLayerPtr.data();
4844 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4859 return QVariant( area );
4863 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4875 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4880 return QVariant( geom.
area() );
4894 return QVariant( len );
4898 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4919 return QVariant( len );
4923 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4929 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4935 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4941 return QVariant( geom.
length() );
4946 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4952 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4961 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4970 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4986 if ( !curvePolygon )
4998 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5005 return QVariant( curvePolygon->
ringCount() );
5007 bool foundPoly =
false;
5016 if ( !curvePolygon )
5027 return QVariant( ringCount );
5032 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5034 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
5040 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5046 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5052 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5061 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5067 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5073 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5079 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5085 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5093 double max = std::numeric_limits< double >::lowest();
5097 double z = ( *it ).z();
5103 if ( max == std::numeric_limits< double >::lowest() )
5106 return QVariant( max );
5111 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5119 double min = std::numeric_limits< double >::max();
5123 double z = ( *it ).z();
5129 if ( min == std::numeric_limits< double >::max() )
5132 return QVariant( min );
5137 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5145 double min = std::numeric_limits< double >::max();
5149 double m = ( *it ).m();
5155 if ( min == std::numeric_limits< double >::max() )
5158 return QVariant( min );
5163 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5171 double max = std::numeric_limits< double >::lowest();
5175 double m = ( *it ).m();
5181 if ( max == std::numeric_limits< double >::lowest() )
5184 return QVariant( max );
5189 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5193 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5202 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5206 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5215 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5220 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5230 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5234 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5236 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5241 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5260 return QVariant::fromValue( curve->
isClosed() );
5265 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5278 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5279 closedLine->close();
5281 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5295 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5296 closedLine->close();
5298 closed->addGeometry( closedLine.release() );
5301 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5309 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5313 return QVariant::fromValue( fGeom.
isEmpty() );
5319 return QVariant::fromValue(
true );
5321 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5322 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5327 if ( values.length() < 2 || values.length() > 3 )
5330 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5331 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5338 if ( values.length() == 2 )
5341 QString result = engine->relate( sGeom.
constGet() );
5342 return QVariant::fromValue( result );
5347 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5348 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5349 return QVariant::fromValue( result );
5355 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5356 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5361 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5362 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5363 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5367 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5368 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5369 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5373 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5374 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5375 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5379 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5380 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5381 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5385 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5386 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5387 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5391 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5392 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5393 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5397 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5398 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5399 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5404 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5405 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5411 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5412 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5413 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5418 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5420 QVariant ret = TVL_False;
5423 ret = fGeom.
isExactlyEqual( sGeom, backend ) ? TVL_True : TVL_False;
5434 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5435 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5436 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5441 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5443 QVariant ret = TVL_False;
5457 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5458 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5459 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5464 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5466 double epsilon = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5468 QVariant ret = TVL_False;
5471 ret = fGeom.
isFuzzyEqual( sGeom, epsilon, backend ) ? TVL_True : TVL_False;
5482 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5483 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5484 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5485 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5486 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5487 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5490 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5492 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5496 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5498 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5502 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5508 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5510 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5515 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5517 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5522 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5524 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5529 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5544 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5548 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5549 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5550 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5551 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5554 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5560 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5563 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5567 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5568 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5569 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5572 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5578 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5581 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5585 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5588 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5594 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5595 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5596 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5597 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5598 if ( joinInt < 1 || joinInt > 3 )
5602 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5605 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5611 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5612 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5613 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5615 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5616 if ( joinInt < 1 || joinInt > 3 )
5620 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5623 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5629 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5630 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5631 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5634 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5640 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5641 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5642 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5644 return QVariant::fromValue( fGeom );
5649 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5650 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5652 const bool perPart = values.value( 3 ).toBool();
5659 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5660 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5662 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5663 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5664 t.rotate( -rotation );
5665 t.translate( -partCenter.x(), -partCenter.y() );
5666 ( *it )->transform( t );
5668 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5680 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5688 fGeom.
rotate( rotation, pt );
5689 return QVariant::fromValue( fGeom );
5695 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5696 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5697 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5698 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent ) :
QgsGeometry();
5704 pt = fGeom.boundingBox().center();
5708 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5713 pt = center.asPoint();
5716 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5717 t.scale( xScale, yScale );
5718 t.translate( -pt.
x(), -pt.
y() );
5720 return QVariant::fromValue( fGeom );
5725 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5731 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5732 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5734 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5736 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5737 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5739 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5740 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5741 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5742 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5753 QTransform transform;
5754 transform.translate( deltaX, deltaY );
5755 transform.rotate( rotationZ );
5756 transform.scale( scaleX, scaleY );
5757 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5759 return QVariant::fromValue( fGeom );
5765 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5767 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5772 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5774 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5780 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5781 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5783 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5789 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5791 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5795#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
5800 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5801 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5802 const bool allowHoles = values.value( 2 ).toBool();
5804 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5817 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5819 if ( values.length() == 2 )
5820 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5828 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5834 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5836 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5842 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5848 double area,
angle, width, height;
5861 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5862 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5864 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5875 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5886 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5896 reversed->addGeometry( curve->
reversed() );
5903 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5909 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5910 std::reverse(
string.begin(),
string.end() );
5916 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5936 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5942 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5943 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5944 return QVariant( fGeom.
distance( sGeom ) );
5949 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5950 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5953 if ( values.length() == 3 && values.at( 2 ).isValid() )
5955 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5956 densify = std::clamp( densify, 0.0, 1.0 );
5964 return res > -1 ? QVariant( res ) : QVariant();
5969 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5970 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5972 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5977 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5978 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5980 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5985 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5986 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5988 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5994 if ( values.length() < 1 || values.length() > 2 )
5997 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5999 if ( values.length() == 2 )
6000 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6001 QString wkt = fGeom.
asWkt( prec );
6002 return QVariant( wkt );
6007 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6008 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
6013 if ( values.length() != 2 )
6015 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
6019 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6020 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6048 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
6055 if ( pt1->
y() < pt2->
y() )
6057 else if ( pt1->
y() > pt2->
y() )
6065 if ( pt1->
x() < pt2->
x() )
6067 else if ( pt1->
x() > pt2->
x() )
6068 return M_PI + ( M_PI_2 );
6073 if ( pt1->
x() < pt2->
x() )
6075 if ( pt1->
y() < pt2->
y() )
6077 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
6081 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI_2 );
6087 if ( pt1->
y() > pt2->
y() )
6089 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) ) + M_PI;
6093 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI + ( M_PI_2 ) );
6100 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6101 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6103 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
6107 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
6115 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
6129 if ( ellipsoid.isEmpty() )
6131 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
6137 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
6145 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
6151 const double bearing = da.
bearing( point1, point2 );
6152 if ( std::isfinite( bearing ) )
6154 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
6167 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6175 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6176 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6177 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
6180 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6187 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6188 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6215 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6224 if ( values.length() != 3 )
6227 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6228 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6229 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6233 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6239 if ( values.length() < 2 )
6242 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6245 return values.at( 0 );
6247 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6248 QVariant cachedExpression;
6253 if ( cachedExpression.isValid() )
6260 bool asc = values.value( 2 ).toBool();
6278 Q_ASSERT( collection );
6282 QgsExpressionSorter sorter( orderBy );
6284 QList<QgsFeature> partFeatures;
6285 partFeatures.reserve( collection->
partCount() );
6286 for (
int i = 0; i < collection->
partCount(); ++i )
6292 sorter.sortFeatures( partFeatures, unconstedContext );
6296 Q_ASSERT( orderedGeom );
6301 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6306 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6309 delete unconstedContext;
6316 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6317 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6321 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6327 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6328 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6332 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6338 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6339 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6343 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6349 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6350 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6351 const bool use3DDistance = values.at( 2 ).toBool();
6353 double x, y, z, distance;
6376 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6379 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6399 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6400 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6402 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6404 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6409 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6410 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6417 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6418 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6423 vertex = count + vertex;
6431 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6432 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6437 vertex = count + vertex;
6445 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6446 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6450 return distance >= 0 ? distance : QVariant();
6455 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6456 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6457 const bool use3DDistance = values.at( 2 ).toBool();
6459 double x, y, z, distance;
6468 return found ? distance : QVariant();
6473 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6475 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6476 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6479 if ( values.length() >= 1 )
6481 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6482 return QVariant( qlonglong( std::round( number ) ) );
6497 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6498 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6499 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6506 const bool omitGroupSeparator = values.value( 3 ).toBool();
6507 const bool trimTrailingZeros = values.value( 4 ).toBool();
6509 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6510 if ( !omitGroupSeparator )
6511 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6513 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6515 QString res = locale.toString( value,
'f', places );
6517 if ( trimTrailingZeros )
6519 const QChar decimal = locale.decimalPoint().at( 0 );
6520 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6522 if ( res.contains( decimal ) )
6524 int trimPoint = res.length() - 1;
6526 while ( res.at( trimPoint ) == zeroDigit )
6529 if ( res.at( trimPoint ) == decimal )
6532 res.truncate( trimPoint + 1 );
6541 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6542 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6543 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6546 if ( format.indexOf(
"Z" ) > 0 )
6547 datetime = datetime.toUTC();
6549 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6550 return locale.toString( datetime, format );
6555 const QVariant variant = values.at( 0 );
6557 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6558 if ( !color.isValid() )
6561 const float alpha = color.alphaF();
6562 if ( color.spec() == QColor::Spec::Cmyk )
6564 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() )
6566 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6570 const float avg = ( color.redF() + color.greenF() + color.blueF() )
6572 color.setRgbF( avg, avg, avg, alpha );
6575 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6582 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6587 else if ( ratio < 0 )
6592 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6593 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6594 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6595 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6597 QColor newColor( red, green, blue, alpha );
6604 const QVariant variant1 = values.at( 0 );
6605 const QVariant variant2 = values.at( 1 );
6607 if ( variant1.userType() != variant2.userType() )
6609 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6614 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6615 if ( !color1.isValid() )
6618 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6619 if ( !color2.isValid() )
6622 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6624 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6628 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6634 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6635 if ( color1.spec() == QColor::Spec::Cmyk )
6637 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6638 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6639 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6640 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6641 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6645 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6646 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6647 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6648 newColor = QColor::fromRgbF( red, green, blue, alpha );
6653 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6658 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6659 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6660 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6661 QColor color = QColor( red, green, blue );
6662 if ( !color.isValid() )
6664 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6665 color = QColor( 0, 0, 0 );
6668 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6673 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6674 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6675 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6676 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6677 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6678 if ( !color.isValid() )
6680 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6689 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6690 QVariant value = node->
eval( parent, context );
6694 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6696 value = node->
eval( parent, context );
6704 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6706 QVariant value = node->
eval( parent, context );
6708 if ( value.toBool() )
6710 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6712 value = node->
eval( parent, context );
6717 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6719 value = node->
eval( parent, context );
6727 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6728 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6729 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6730 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6731 QColor color = QColor( red, green, blue, alpha );
6732 if ( !color.isValid() )
6734 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6735 color = QColor( 0, 0, 0 );
6744 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6746 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6751 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6755 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6760 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6761 QColor color = ramp->
color( value );
6774 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6776 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6778 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6780 QColor color = QColor::fromHslF( hue, saturation, lightness );
6782 if ( !color.isValid() )
6784 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6785 color = QColor( 0, 0, 0 );
6788 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6794 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6796 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6798 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6800 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6802 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6803 if ( !color.isValid() )
6805 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6806 color = QColor( 0, 0, 0 );
6813 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6814 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6815 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6816 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6818 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6819 if ( !color.isValid() )
6821 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6831 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6833 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6835 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6837 QColor color = QColor::fromHsvF( hue, saturation, value );
6839 if ( !color.isValid() )
6841 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6842 color = QColor( 0, 0, 0 );
6845 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6851 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6853 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6855 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6857 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6859 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6860 if ( !color.isValid() )
6862 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6863 color = QColor( 0, 0, 0 );
6870 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6871 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6872 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6873 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6874 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6876 if ( !color.isValid() )
6878 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6887 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6888 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6889 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6890 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6891 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6893 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6894 if ( !color.isValid() )
6896 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6906 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6908 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6910 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6912 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6914 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6916 if ( !color.isValid() )
6918 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6919 color = QColor( 0, 0, 0 );
6922 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6928 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6930 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6932 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6934 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6936 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6938 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6939 if ( !color.isValid() )
6941 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6942 color = QColor( 0, 0, 0 );
6949 const QVariant variant = values.at( 0 );
6951 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6952 if ( !color.isValid() )
6955 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6956 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6958 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6959 return color.green();
6960 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6961 return color.blue();
6962 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6963 return color.alpha();
6964 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6965 return static_cast< double >( color.hsvHueF() * 360 );
6966 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6967 return static_cast< double >( color.hsvSaturationF() * 100 );
6968 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6969 return static_cast< double >( color.valueF() * 100 );
6970 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6971 return static_cast< double >( color.hslHueF() * 360 );
6972 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6973 return static_cast< double >( color.hslSaturationF() * 100 );
6974 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6975 return static_cast< double >( color.lightnessF() * 100 );
6976 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6977 return static_cast< double >( color.cyanF() * 100 );
6978 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6979 return static_cast< double >( color.magentaF() * 100 );
6980 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6981 return static_cast< double >( color.yellowF() * 100 );
6982 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6983 return static_cast< double >( color.blackF() * 100 );
6985 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6991 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6994 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
6998 QList< QColor > colors;
7000 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7003 if ( !colors.last().isValid() )
7005 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
7009 double step = it.key().toDouble();
7010 if ( it == map.constBegin() )
7015 else if ( it == map.constEnd() )
7025 bool discrete = values.at( 1 ).toBool();
7027 if ( colors.empty() )
7030 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
7035 const QVariant variant = values.at( 0 );
7037 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7038 if ( !color.isValid() )
7041 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7042 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7043 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7044 color.setRed( std::clamp( value, 0, 255 ) );
7045 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7046 color.setGreen( std::clamp( value, 0, 255 ) );
7047 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7048 color.setBlue( std::clamp( value, 0, 255 ) );
7049 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7050 color.setAlpha( std::clamp( value, 0, 255 ) );
7051 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7052 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
7053 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7054 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
7055 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7056 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7057 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7058 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
7059 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7060 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
7061 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7062 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7063 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7064 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
7065 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7066 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
7067 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7068 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
7069 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7070 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7073 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7076 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7081 const QVariant variant = values.at( 0 );
7083 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7084 if ( !color.isValid() )
7087 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7089 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7094 const QVariant variant = values.at( 0 );
7096 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7097 if ( !color.isValid() )
7100 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7102 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7107 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7110 return QVariant::fromValue( geom );
7116 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7124 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
7129 return QVariant::fromValue( fGeom );
7132 return QVariant::fromValue( fGeom );
7141 return QVariant::fromValue( fGeom );
7154 bool foundLayer =
false;
7155 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7158 if ( !featureSource || !foundLayer )
7163 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
7176 result = QVariant::fromValue( fet );
7184 bool foundLayer =
false;
7185 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7188 if ( !featureSource || !foundLayer )
7193 QString cacheValueKey;
7194 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7196 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7198 QMap<QString, QVariant>::const_iterator i = attributeMap.constBegin();
7199 QString filterString;
7200 for ( ; i != attributeMap.constEnd(); ++i )
7202 if ( !filterString.isEmpty() )
7204 filterString.append(
" AND " );
7208 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7217 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7218 int attributeId = featureSource->fields().lookupField( attribute );
7219 if ( attributeId == -1 )
7224 const QVariant &attVal = values.at( 2 );
7226 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7249 res = QVariant::fromValue( fet );
7264 if ( !values.isEmpty() )
7267 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7268 fieldName = col->
name();
7269 else if ( values.size() == 2 )
7270 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7273 QVariant value = values.at( 0 );
7278 if ( fieldIndex == -1 )
7280 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7286 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7289 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7298 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7316 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7324 const QVariant data = values.at( 0 );
7325 const QMimeDatabase db;
7326 return db.mimeTypeForData( data.toByteArray() ).name();
7331 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7333 bool translate =
true;
7334 if ( values.length() >= 3 )
7336 translate = QgsExpressionUtils::getTVLValue( values.at( 2 ), parent ) == QgsExpressionUtils::TVL::True;
7339 bool foundLayer =
false;
7340 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7344 [layerProperty, translate](
QgsMapLayer *layer ) -> QVariant {
7349 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7350 return layer->name();
7351 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7353 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7354 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7355 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7356 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7357 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7359 QStringList keywords;
7360 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7361 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7363 keywords.append( it.value() );
7365 if ( !keywords.isEmpty() )
7367 return layer->serverProperties()->keywordList();
7369 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7371 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7373 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7375 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7377 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7379 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7381 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7383 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7385 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7387 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7389 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7391 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7393 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7396 QVariant result = QVariant::fromValue( extentGeom );
7399 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7401 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7404 return decodedUri.value( u
"path"_s );
7406 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7408 switch ( layer->
type() )
7411 return translate ? QCoreApplication::translate(
"expressions",
"Vector" ) : u
"Vector"_s;
7413 return translate ? QCoreApplication::translate(
"expressions",
"Raster" ) : u
"Raster"_s;
7415 return translate ? QCoreApplication::translate(
"expressions",
"Mesh" ) : u
"Mesh"_s;
7417 return translate ? QCoreApplication::translate(
"expressions",
"Vector Tile" ) : u
"Vector Tile"_s;
7419 return translate ? QCoreApplication::translate(
"expressions",
"Plugin" ) : u
"Plugin"_s;
7421 return translate ? QCoreApplication::translate(
"expressions",
"Annotation" ) : u
"Annotation"_s;
7423 return translate ? QCoreApplication::translate(
"expressions",
"Point Cloud" ) : u
"Point Cloud"_s;
7425 return translate ? QCoreApplication::translate(
"expressions",
"Group" ) : u
"Group"_s;
7427 return translate ? QCoreApplication::translate(
"expressions",
"Tiled Scene" ) : u
"Tiled Scene"_s;
7433 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7436 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7438 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7440 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7458 const QString uriPart = values.at( 1 ).toString();
7460 bool foundLayer =
false;
7462 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7466 [parent, uriPart](
QgsMapLayer *layer ) -> QVariant {
7467 if ( !layer->dataProvider() )
7469 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7475 if ( !uriPart.isNull() )
7477 return decodedUri.value( uriPart );
7489 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7500 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7501 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7503 bool foundLayer =
false;
7504 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7508 [parent, band, layerProperty](
QgsMapLayer *layer ) -> QVariant {
7509 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7513 if ( band < 1 || band > rl->bandCount() )
7515 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7521 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7523 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7525 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7527 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7529 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7531 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7535 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7565 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7582 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7583 bool ascending = values.value( 1 ).toBool();
7584 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7590 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7595 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7600 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7605 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7606 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7608 for (
const auto &item : listB )
7610 if ( listA.contains( item ) )
7614 return QVariant( match == listB.count() );
7619 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7624 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7625 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7626 if ( pos < list.length() && pos >= 0 )
7627 return list.at( pos );
7628 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7629 return list.at( list.length() + pos );
7635 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7636 return list.value( 0 );
7641 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7642 return list.value( list.size() - 1 );
7647 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7648 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7653 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7654 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7659 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7662 for (
const QVariant &item : list )
7664 switch ( item.userType() )
7666 case QMetaType::Int:
7667 case QMetaType::UInt:
7668 case QMetaType::LongLong:
7669 case QMetaType::ULongLong:
7670 case QMetaType::Float:
7671 case QMetaType::Double:
7672 total += item.toDouble();
7677 return i == 0 ? QVariant() : total / i;
7682 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7683 QVariantList numbers;
7684 for (
const auto &item : list )
7686 switch ( item.userType() )
7688 case QMetaType::Int:
7689 case QMetaType::UInt:
7690 case QMetaType::LongLong:
7691 case QMetaType::ULongLong:
7692 case QMetaType::Float:
7693 case QMetaType::Double:
7694 numbers.append( item );
7698 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7699 const int count = numbers.count();
7704 else if ( count % 2 )
7706 return numbers.at( count / 2 );
7710 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7716 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7719 for (
const QVariant &item : list )
7721 switch ( item.userType() )
7723 case QMetaType::Int:
7724 case QMetaType::UInt:
7725 case QMetaType::LongLong:
7726 case QMetaType::ULongLong:
7727 case QMetaType::Float:
7728 case QMetaType::Double:
7729 total += item.toDouble();
7734 return i == 0 ? QVariant() : total;
7737static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7739 QVariant result = value;
7740 ( void ) result.convert(
static_cast<int>( type ) );
7746 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7747 QHash< QVariant, int > hash;
7748 for (
const auto &item : list )
7752 const QList< int > occurrences = hash.values();
7753 if ( occurrences.empty() )
7754 return QVariantList();
7756 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7758 const QString option = values.at( 1 ).toString();
7759 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7761 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7763 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7765 if ( hash.isEmpty() )
7768 return QVariant( hash.key( maxValue ) );
7770 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7772 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7774 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7776 if ( maxValue * 2 <= list.size() )
7779 return QVariant( hash.key( maxValue ) );
7790 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7791 QHash< QVariant, int > hash;
7792 for (
const auto &item : list )
7796 const QList< int > occurrences = hash.values();
7797 if ( occurrences.empty() )
7798 return QVariantList();
7800 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7802 const QString option = values.at( 1 ).toString();
7803 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7805 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7807 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7809 if ( hash.isEmpty() )
7812 return QVariant( hash.key( minValue ) );
7814 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7816 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7818 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7820 if ( hash.isEmpty() )
7824 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7825 if ( maxValue * 2 > list.size() )
7826 hash.remove( hash.key( maxValue ) );
7828 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7839 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7840 list.append( values.at( 1 ) );
7841 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7846 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7847 list.prepend( values.at( 1 ) );
7848 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7853 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7854 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7855 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7860 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7861 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7863 position = position + list.length();
7864 if ( position >= 0 && position < list.length() )
7865 list.removeAt( position );
7866 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7874 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7876 const QVariant toRemove = values.at( 1 );
7879 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant &element ) { return QgsVariantUtils::isNull( element ); } ), list.end() );
7883 list.removeAll( toRemove );
7885 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7890 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7892 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7894 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7895 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7897 int index = list.indexOf( it.key() );
7898 while ( index >= 0 )
7900 list.replace( index, it.value() );
7901 index = list.indexOf( it.key() );
7905 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7907 else if ( values.count() == 3 )
7909 QVariantList before;
7911 bool isSingleReplacement =
false;
7913 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7915 before = QVariantList() << values.at( 1 );
7919 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7922 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7924 after = QVariantList() << values.at( 2 );
7925 isSingleReplacement =
true;
7929 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7932 if ( !isSingleReplacement && before.length() != after.length() )
7934 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7938 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7939 for (
int i = 0; i < before.length(); i++ )
7941 int index = list.indexOf( before.at( i ) );
7942 while ( index >= 0 )
7944 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7945 index = list.indexOf( before.at( i ) );
7949 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7953 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7960 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7961 QVariantList list_new;
7963 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
7965 while ( list.removeOne( cur ) )
7967 list_new.append( cur );
7971 list_new.append( list );
7973 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7979 for (
const QVariant &cur : values )
7981 list += QgsExpressionUtils::getListValue( cur, parent );
7983 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7988 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7989 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7990 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7991 int slice_length = 0;
7993 if ( start_pos < 0 )
7995 start_pos = list.length() + start_pos;
7999 slice_length = end_pos - start_pos + 1;
8003 slice_length = list.length() + end_pos - start_pos + 1;
8006 if ( slice_length < 0 )
8010 list = list.mid( start_pos, slice_length );
8016 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8017 std::reverse( list.begin(), list.end() );
8023 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8024 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
8025 for (
const QVariant &cur : array2 )
8027 if ( array1.contains( cur ) )
8028 return QVariant(
true );
8030 return QVariant(
false );
8035 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8037 QVariantList distinct;
8039 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8041 if ( !distinct.contains( *it ) )
8043 distinct += ( *it );
8052 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8053 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8054 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8058 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8060 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
8061 if ( it != ( array.constEnd() - 1 ) )
8067 return QVariant( str );
8072 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8073 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8074 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8076 QStringList list = str.split( delimiter );
8079 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
8081 array += ( !( *it ).isEmpty() ) ? *it : empty;
8089 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8090 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
8091 if ( document.isNull() )
8094 return document.toVariant();
8100 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
8101 return QString( document.toJson( QJsonDocument::Compact ) );
8106 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8107 if ( str.isEmpty() )
8108 return QVariantMap();
8109 str = str.trimmed();
8116 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8123 for (
int i = 0; i + 1 < values.length(); i += 2 )
8125 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
8132 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8133 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8134 QVariantMap resultMap;
8136 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8138 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
8146 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
8151 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
8156 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8157 map.remove( values.at( 1 ).toString() );
8163 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8164 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
8171 for (
const QVariant &cur : values )
8173 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
8174 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
8175 result.insert( it.key(), it.value() );
8182 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
8187 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
8192 const QString envVarName = values.at( 0 ).toString();
8193 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
8196 return QProcessEnvironment::systemEnvironment().value( envVarName );
8201 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8204 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
8207 return QFileInfo( file ).completeBaseName();
8212 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8215 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8218 return QFileInfo( file ).completeSuffix();
8223 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8226 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8229 return QFileInfo::exists( file );
8234 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8237 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8240 return QFileInfo( file ).fileName();
8245 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8248 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8251 return QFileInfo( file ).isFile();
8256 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8259 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8262 return QFileInfo( file ).isDir();
8267 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8270 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8273 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8278 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8281 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8284 return QFileInfo( file ).size();
8287static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8289 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8295 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8296 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8298 if ( method ==
"md4"_L1 )
8300 hash = fcnHash( str, QCryptographicHash::Md4 );
8302 else if ( method ==
"md5"_L1 )
8304 hash = fcnHash( str, QCryptographicHash::Md5 );
8306 else if ( method ==
"sha1"_L1 )
8308 hash = fcnHash( str, QCryptographicHash::Sha1 );
8310 else if ( method ==
"sha224"_L1 )
8312 hash = fcnHash( str, QCryptographicHash::Sha224 );
8314 else if ( method ==
"sha256"_L1 )
8316 hash = fcnHash( str, QCryptographicHash::Sha256 );
8318 else if ( method ==
"sha384"_L1 )
8320 hash = fcnHash( str, QCryptographicHash::Sha384 );
8322 else if ( method ==
"sha512"_L1 )
8324 hash = fcnHash( str, QCryptographicHash::Sha512 );
8326 else if ( method ==
"sha3_224"_L1 )
8328 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8330 else if ( method ==
"sha3_256"_L1 )
8332 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8334 else if ( method ==
"sha3_384"_L1 )
8336 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8338 else if ( method ==
"sha3_512"_L1 )
8340 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8342 else if ( method ==
"keccak_224"_L1 )
8344 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8346 else if ( method ==
"keccak_256"_L1 )
8348 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8350 else if ( method ==
"keccak_384"_L1 )
8352 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8354 else if ( method ==
"keccak_512"_L1 )
8356 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8360 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8367 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8372 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8377 const QByteArray input = values.at( 0 ).toByteArray();
8378 return QVariant( QString( input.toBase64() ) );
8383 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8385 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8387 query.addQueryItem( it.key(), it.value().toString() );
8389 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8394 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8395 const QByteArray base64 = value.toLocal8Bit();
8396 const QByteArray decoded = QByteArray::fromBase64( base64 );
8397 return QVariant( decoded );
8403static QVariant executeGeomOverlay(
8404 const QVariantList &values,
8408 bool invert =
false,
8409 double bboxGrow = 0,
8410 bool isNearestFunc =
false,
8411 bool isIntersectsFunc =
false
8416 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8420 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8423 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8432 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8435 const bool layerCanBeCached = node->
isStatic( parent, context );
8436 QVariant targetLayerValue = node->
eval( parent, context );
8440 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8442 QString subExpString = node->dump();
8444 bool testOnly = ( subExpString ==
"NULL" );
8447 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8451 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8456 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8458 QString filterString = node->dump();
8459 if ( filterString !=
"NULL" )
8461 request.setFilterExpression( filterString );
8465 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8467 QVariant limitValue = node->eval( parent, context );
8469 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8471 double max_distance = 0;
8472 bool cacheEnabled =
false;
8474 double minOverlap { -1 };
8475 double minInscribedCircleRadius { -1 };
8476 bool returnDetails =
false;
8477 bool sortByMeasure =
false;
8478 bool sortAscending =
false;
8479 bool requireMeasures =
false;
8480 bool overlapOrRadiusFilter =
false;
8484 if ( isNearestFunc )
8487 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8489 QVariant distanceValue = node->eval( parent, context );
8491 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8494 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8496 QVariant cacheValue = node->eval( parent, context );
8498 cacheEnabled = cacheValue.toBool();
8503 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8505 QVariant cacheValue = node->eval( parent, context );
8507 cacheEnabled = cacheValue.toBool();
8510 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8512 const QVariant minOverlapValue = node->eval( parent, context );
8514 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8517 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8519 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8521 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8524 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8526 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8529 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8531 const QString sorting { node->eval( parent, context ).toString().toLower() };
8532 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8533 sortAscending = sorting.startsWith(
"asc" );
8534 requireMeasures = sortByMeasure || returnDetails;
8535 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8538 node = QgsExpressionUtils::getNode( values.at( 9 ), parent );
8540 const QString backendStr = node->eval( parent, context ).toString().toUpper();
8546 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
8552 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8555 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8558 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8561 if ( bboxGrow != 0 )
8563 intDomain.
grow( bboxGrow );
8566 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8572 QList<QgsFeature> features;
8573 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8577 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8578 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8582 cachedTarget = targetLayer->
materialize( request );
8583 if ( layerCanBeCached )
8584 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8594 if ( layerCanBeCached )
8595 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8602 QList<QgsFeatureId> fidsList;
8603 if ( isNearestFunc )
8605 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8609 fidsList = spatialIndex.
intersects( intDomain );
8612 QListIterator<QgsFeatureId> i( fidsList );
8613 while ( i.hasNext() )
8616 if ( sameLayers && feat.
id() == fId2 )
8618 features.append( cachedTarget->
getFeature( fId2 ) );
8625 request.setFilterRect( intDomain );
8630 if ( sameLayers && feat.
id() == feat2.
id() )
8632 features.append( feat2 );
8640 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8641 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8647 subExpression.
prepare( &subContext );
8660 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double &overlapValue ) ->
bool {
8661 bool testResult {
false };
8663 QVector<double> overlapValues;
8664 const QgsGeometry merged { intersection.mergeLines() };
8669 if ( minOverlap != -1 || requireMeasures )
8671 overlapValue = geom->
length();
8672 overlapValues.append( overlapValue );
8673 if ( minOverlap != -1 )
8675 if ( overlapValue >= minOverlap )
8687 if ( !overlapValues.isEmpty() )
8689 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8696 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double &radiusValue,
double &overlapValue ) ->
bool {
8698 bool testResult {
false };
8700 QVector<double> overlapValues;
8701 QVector<double> radiusValues;
8702 for (
auto it = intersection.const_parts_begin(); ( !testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8706 if ( minOverlap != -1 || requireMeasures )
8708 overlapValue = geom->
area();
8709 overlapValues.append( geom->
area() );
8710 if ( minOverlap != -1 )
8712 if ( overlapValue >= minOverlap )
8724 if ( minInscribedCircleRadius != -1 || requireMeasures )
8727 const double width = bbox.
width();
8728 const double height = bbox.
height();
8729 const double size = width > height ? width : height;
8730 const double tolerance = size / 100.0;
8732 testResult = radiusValue >= minInscribedCircleRadius;
8733 radiusValues.append( radiusValues );
8738 if ( !radiusValues.isEmpty() )
8740 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8743 if ( !overlapValues.isEmpty() )
8745 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8754 QVariantList results;
8756 QListIterator<QgsFeature> i( features );
8759 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8764 if ( relationFunction( geometry, feat2.
geometry(), values, backend ) )
8766 double overlapValue = -1;
8767 double radiusValue = -1;
8769 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8781 for (
const auto &geom : std::as_const( geometries ) )
8783 switch ( geom.type() )
8787 poly.append( geom.asPolygon() );
8792 line.append( geom.asPolyline() );
8797 point.append( geom.asPoint() );
8808 switch ( geometry.
type() )
8836 switch ( intersection.
type() )
8841 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8843 if ( !testResult && overlapOrRadiusFilter )
8855 if ( minInscribedCircleRadius != -1 )
8861 const bool testResult { testLinestring( intersection, overlapValue ) };
8863 if ( !testResult && overlapOrRadiusFilter )
8875 if ( minInscribedCircleRadius != -1 )
8880 bool testResult {
false };
8881 if ( minOverlap != -1 || requireMeasures )
8901 testResult = testLinestring( feat2.
geometry(), overlapValue );
8906 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8912 if ( !testResult && overlapOrRadiusFilter )
8939 const QVariant expResult = subExpression.
evaluate( &subContext );
8941 if ( requireMeasures )
8943 QVariantMap resultRecord;
8944 resultRecord.insert( u
"id"_s, feat2.
id() );
8945 resultRecord.insert( u
"result"_s, expResult );
8947 resultRecord.insert( u
"overlap"_s, overlapValue );
8949 if ( radiusValue != -1 )
8951 resultRecord.insert( u
"radius"_s, radiusValue );
8953 results.append( resultRecord );
8957 results.append( expResult );
8963 results.append( feat2.
id() );
8983 if ( requireMeasures )
8985 if ( sortByMeasure )
8987 std::sort( results.begin(), results.end(), [sortAscending](
const QVariant &recordA,
const QVariant &recordB ) ->
bool {
8988 return sortAscending ? recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
8989 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
8993 if ( limit > 0 && results.size() > limit )
8995 results.erase( results.begin() + limit );
8998 if ( !returnDetails )
9000 QVariantList expResults;
9001 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
9003 expResults.append( it->toMap().value( u
"result"_s ) );
9013 QVariantList disjoint_results;
9022 if ( !results.contains( feat2.
id() ) )
9025 disjoint_results.append( subExpression.
evaluate( &subContext ) );
9028 return disjoint_results;
9036 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
false,
true );
9042 return executeGeomOverlay( values, context, parent, geomFunction );
9048 return executeGeomOverlay( values, context, parent, geomFunction );
9056 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9064 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9072 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9078 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 10 ), parent );
9080 QVariant epsilonValue = node->
eval( parent, context );
9082 double epsilon = QgsExpressionUtils::getDoubleValue( epsilonValue, parent );
9085 return geometry.
isFuzzyEqual( other, epsilon, backend );
9087 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9093 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9099 return executeGeomOverlay( values, context, parent, geomFunction );
9105 return executeGeomOverlay( values, context, parent, geomFunction,
true, 0,
false,
true );
9113 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
true );
9122 QMutexLocker locker( &sFunctionsMutex );
9124 QList<QgsExpressionFunction *> &functions = *sFunctions();
9126 if ( functions.isEmpty() )
9129 << QgsExpressionFunction::Parameter( u
"expression"_s )
9130 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
9131 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
9134 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true ) << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9137 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9143 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnAzimuth, u
"GeometryGroup"_s )
9144 <<
new QgsStaticExpressionFunction(
9147 << QgsExpressionFunction::Parameter( u
"point1"_s )
9148 << QgsExpressionFunction::Parameter( u
"point2"_s )
9149 << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() )
9150 << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ),
9154 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnInclination, u
"GeometryGroup"_s )
9155 <<
new QgsStaticExpressionFunction(
9158 << QgsExpressionFunction::Parameter( u
"point"_s )
9159 << QgsExpressionFunction::Parameter( u
"distance"_s )
9160 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9161 << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ),
9172 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
9176 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
9177 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
9179 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction(
9181 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9186 functions << randFunc;
9188 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction(
9191 << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 )
9192 << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 )
9193 << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9198 functions << randfFunc;
9201 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9202 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9203 <<
new QgsStaticExpressionFunction( u
"clamp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ), fcnClamp, u
"Math"_s )
9204 <<
new QgsStaticExpressionFunction(
9207 << QgsExpressionFunction::Parameter( u
"value"_s )
9208 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9209 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9210 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9211 << QgsExpressionFunction::Parameter( u
"range_max"_s ),
9215 <<
new QgsStaticExpressionFunction(
9216 u
"scale_polynomial"_s,
9218 << QgsExpressionFunction::Parameter( u
"value"_s )
9219 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9220 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9221 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9222 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9223 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9230 QStringList() << u
"scale_exp"_s
9232 <<
new QgsStaticExpressionFunction(
9233 u
"scale_exponential"_s,
9235 << QgsExpressionFunction::Parameter( u
"value"_s )
9236 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9237 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9238 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9239 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9240 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9241 fcnExponentialScale,
9244 <<
new QgsStaticExpressionFunction(
9245 u
"scale_cubic_bezier"_s,
9247 << QgsExpressionFunction::Parameter( u
"value"_s )
9248 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9249 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9250 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9251 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9252 << QgsExpressionFunction::Parameter( u
"x1"_s )
9253 << QgsExpressionFunction::Parameter( u
"y1"_s )
9254 << QgsExpressionFunction::Parameter( u
"x2"_s )
9255 << QgsExpressionFunction::Parameter( u
"y2"_s ),
9256 fcnCubicBezierScale,
9261 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
9262 <<
new QgsStaticExpressionFunction( u
"to_bool"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToBool, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"tobool"_s,
true )
9263 <<
new QgsStaticExpressionFunction( u
"to_int"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToInt, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"toint"_s )
9264 <<
new QgsStaticExpressionFunction( u
"to_real"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToReal, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"toreal"_s )
9265 <<
new QgsStaticExpressionFunction(
9269 QStringList() << u
"Conversions"_s << u
"String"_s,
9274 QStringList() << u
"tostring"_s
9276 <<
new QgsStaticExpressionFunction(
9279 << QgsExpressionFunction::Parameter( u
"value"_s )
9280 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9281 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9283 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9288 QStringList() << u
"todatetime"_s
9290 <<
new QgsStaticExpressionFunction(
9293 << QgsExpressionFunction::Parameter( u
"value"_s )
9294 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9295 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9297 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9302 QStringList() << u
"todate"_s
9304 <<
new QgsStaticExpressionFunction(
9307 << QgsExpressionFunction::Parameter( u
"value"_s )
9308 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9309 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9311 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9316 QStringList() << u
"totime"_s
9318 <<
new QgsStaticExpressionFunction(
9322 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9327 QStringList() << u
"tointerval"_s
9329 <<
new QgsStaticExpressionFunction(
9332 << QgsExpressionFunction::Parameter( u
"value"_s )
9333 << QgsExpressionFunction::Parameter( u
"axis"_s )
9334 << QgsExpressionFunction::Parameter( u
"precision"_s )
9335 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9342 QStringList() << u
"todm"_s
9344 <<
new QgsStaticExpressionFunction(
9347 << QgsExpressionFunction::Parameter( u
"value"_s )
9348 << QgsExpressionFunction::Parameter( u
"axis"_s )
9349 << QgsExpressionFunction::Parameter( u
"precision"_s )
9350 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9351 fcnToDegreeMinuteSecond,
9357 QStringList() << u
"todms"_s
9359 <<
new QgsStaticExpressionFunction( u
"to_decimal"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToDecimal, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"todecimal"_s )
9360 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
9361 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
9362 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
9363 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9364 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
9365 <<
new QgsStaticExpressionFunction(
9368 << QgsExpressionFunction::Parameter( u
"condition"_s )
9369 << QgsExpressionFunction::Parameter( u
"result_when_true"_s )
9370 << QgsExpressionFunction::Parameter( u
"result_when_false"_s ),
9378 <<
new QgsStaticExpressionFunction(
9389 <<
new QgsStaticExpressionFunction(
9392 << QgsExpressionFunction::Parameter( u
"layer"_s )
9393 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9394 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9395 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9396 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9397 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9407 if ( !node->
args() )
9410 QSet<QString> referencedVars;
9413 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9419 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9422 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
9430 if ( !node->
args() )
9431 return QSet<QString>();
9433 QSet<QString> referencedCols;
9434 QSet<QString> referencedVars;
9438 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9444 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9449 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
9452 return referencedCols;
9457 <<
new QgsStaticExpressionFunction(
9458 u
"relation_aggregate"_s,
9460 << QgsExpressionFunction::Parameter( u
"relation"_s )
9461 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9462 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9463 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9464 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9465 fcnAggregateRelation,
9473 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9474 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9475 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9476 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9477 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9478 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9479 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9480 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9481 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9482 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9483 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9484 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9485 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9486 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9487 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9488 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9489 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9490 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9491 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9492 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9493 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9495 <<
new QgsStaticExpressionFunction( u
"regexp_match"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpMatch, QStringList() << u
"Conditionals"_s << u
"String"_s )
9496 <<
new QgsStaticExpressionFunction(
9497 u
"regexp_matches"_s,
9499 << QgsExpressionFunction::Parameter( u
"string"_s )
9500 << QgsExpressionFunction::Parameter( u
"regex"_s )
9501 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
9506 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9507 <<
new QgsStaticExpressionFunction( u
"age"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime1"_s ) << QgsExpressionFunction::Parameter( u
"datetime2"_s ), fcnAge, u
"Date and Time"_s )
9516 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9517 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9518 <<
new QgsStaticExpressionFunction( u
"make_date"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"year"_s ) << QgsExpressionFunction::Parameter( u
"month"_s ) << QgsExpressionFunction::Parameter( u
"day"_s ), fcnMakeDate, u
"Date and Time"_s )
9519 <<
new QgsStaticExpressionFunction(
9521 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hour"_s ) << QgsExpressionFunction::Parameter( u
"minute"_s ) << QgsExpressionFunction::Parameter( u
"second"_s ),
9525 <<
new QgsStaticExpressionFunction(
9528 << QgsExpressionFunction::Parameter( u
"year"_s )
9529 << QgsExpressionFunction::Parameter( u
"month"_s )
9530 << QgsExpressionFunction::Parameter( u
"day"_s )
9531 << QgsExpressionFunction::Parameter( u
"hour"_s )
9532 << QgsExpressionFunction::Parameter( u
"minute"_s )
9533 << QgsExpressionFunction::Parameter( u
"second"_s ),
9537 <<
new QgsStaticExpressionFunction(
9540 << QgsExpressionFunction::Parameter( u
"years"_s,
true, 0 )
9541 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9542 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9543 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9544 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9545 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9546 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9550 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9551 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9552 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9553 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9554 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9556 <<
new QgsStaticExpressionFunction(
9559 << QgsExpressionFunction::Parameter( u
"string"_s )
9560 << QgsExpressionFunction::Parameter( u
"substring"_s )
9561 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9568 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9569 <<
new QgsStaticExpressionFunction( u
"ltrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9570 <<
new QgsStaticExpressionFunction( u
"rtrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9571 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9572 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9573 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9577 <<
new QgsStaticExpressionFunction(
9580 << QgsExpressionFunction::Parameter( u
"text"_s )
9581 << QgsExpressionFunction::Parameter( u
"length"_s )
9582 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ),
9586 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9587 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9588 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s ) }, fcnRepeat, u
"String"_s )
9589 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9590 <<
new QgsStaticExpressionFunction(
9591 u
"regexp_replace"_s,
9592 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"replacement"_s ),
9596 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9597 <<
new QgsStaticExpressionFunction(
9599 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ),
9609 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9610 <<
new QgsStaticExpressionFunction( u
"concat_ws"_s, -1, fcnConcatWs, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9611 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9612 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9613 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9614 <<
new QgsStaticExpressionFunction( u
"rpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnRPad, u
"String"_s )
9615 <<
new QgsStaticExpressionFunction( u
"lpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnLPad, u
"String"_s )
9616 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9617 <<
new QgsStaticExpressionFunction(
9620 << QgsExpressionFunction::Parameter( u
"number"_s )
9621 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9622 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9623 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9624 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ),
9628 <<
new QgsStaticExpressionFunction(
9631 << QgsExpressionFunction::Parameter( u
"datetime"_s )
9632 << QgsExpressionFunction::Parameter( u
"format"_s )
9633 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9635 QStringList() << u
"String"_s << u
"Date and Time"_s
9637 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9638 <<
new QgsStaticExpressionFunction(
9640 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9644 <<
new QgsStaticExpressionFunction(
9646 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9650 <<
new QgsStaticExpressionFunction( u
"color_rgb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"red"_s ) << QgsExpressionFunction::Parameter( u
"green"_s ) << QgsExpressionFunction::Parameter( u
"blue"_s ), fcnColorRgb, u
"Color"_s )
9651 <<
new QgsStaticExpressionFunction(
9654 << QgsExpressionFunction::Parameter( u
"red"_s )
9655 << QgsExpressionFunction::Parameter( u
"green"_s )
9656 << QgsExpressionFunction::Parameter( u
"blue"_s )
9657 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9661 <<
new QgsStaticExpressionFunction(
9664 << QgsExpressionFunction::Parameter( u
"red"_s )
9665 << QgsExpressionFunction::Parameter( u
"green"_s )
9666 << QgsExpressionFunction::Parameter( u
"blue"_s )
9667 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9673 <<
new QgsStaticExpressionFunction( u
"create_ramp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ), fcnCreateRamp, u
"Color"_s )
9674 <<
new QgsStaticExpressionFunction(
9676 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9680 <<
new QgsStaticExpressionFunction(
9683 << QgsExpressionFunction::Parameter( u
"hue"_s )
9684 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9685 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9686 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9690 <<
new QgsStaticExpressionFunction(
9693 << QgsExpressionFunction::Parameter( u
"hue"_s )
9694 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9695 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9696 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9700 <<
new QgsStaticExpressionFunction(
9702 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9706 <<
new QgsStaticExpressionFunction(
9709 << QgsExpressionFunction::Parameter( u
"hue"_s )
9710 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9711 << QgsExpressionFunction::Parameter( u
"value"_s )
9712 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9716 <<
new QgsStaticExpressionFunction(
9719 << QgsExpressionFunction::Parameter( u
"hue"_s )
9720 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9721 << QgsExpressionFunction::Parameter( u
"value"_s )
9722 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9726 <<
new QgsStaticExpressionFunction(
9729 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9730 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9731 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9732 << QgsExpressionFunction::Parameter( u
"black"_s ),
9736 <<
new QgsStaticExpressionFunction(
9739 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9740 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9741 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9742 << QgsExpressionFunction::Parameter( u
"black"_s )
9743 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9747 <<
new QgsStaticExpressionFunction(
9750 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9751 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9752 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9753 << QgsExpressionFunction::Parameter( u
"black"_s )
9754 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9758 <<
new QgsStaticExpressionFunction( u
"color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ), fncColorPart, u
"Color"_s )
9759 <<
new QgsStaticExpressionFunction( u
"darker"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncDarker, u
"Color"_s )
9760 <<
new QgsStaticExpressionFunction( u
"lighter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncLighter, u
"Color"_s )
9761 <<
new QgsStaticExpressionFunction(
9762 u
"set_color_part"_s,
9763 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9769 <<
new QgsStaticExpressionFunction( u
"base_file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnBaseFileName, u
"Files and Paths"_s )
9770 <<
new QgsStaticExpressionFunction( u
"file_suffix"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSuffix, u
"Files and Paths"_s )
9771 <<
new QgsStaticExpressionFunction( u
"file_exists"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileExists, u
"Files and Paths"_s )
9772 <<
new QgsStaticExpressionFunction( u
"file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileName, u
"Files and Paths"_s )
9773 <<
new QgsStaticExpressionFunction( u
"is_file"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsFile, u
"Files and Paths"_s )
9774 <<
new QgsStaticExpressionFunction( u
"is_directory"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsDir, u
"Files and Paths"_s )
9775 <<
new QgsStaticExpressionFunction( u
"file_path"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFilePath, u
"Files and Paths"_s )
9776 <<
new QgsStaticExpressionFunction( u
"file_size"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSize, u
"Files and Paths"_s )
9778 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ), fcnExif, u
"Files and Paths"_s )
9779 <<
new QgsStaticExpressionFunction( u
"exif_geotag"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnExifGeoTag, u
"GeometryGroup"_s )
9782 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ), fcnGenericHash, u
"Conversions"_s )
9788 <<
new QgsStaticExpressionFunction( u
"from_base64"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnFromBase64, u
"Conversions"_s )
9791 <<
new QgsStaticExpressionFunction(
9792 u
"magnetic_declination"_s,
9794 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9795 << QgsExpressionFunction::Parameter( u
"date"_s )
9796 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9797 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9798 << QgsExpressionFunction::Parameter( u
"height"_s )
9799 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9800 fcnMagneticDeclination,
9803 <<
new QgsStaticExpressionFunction(
9804 u
"magnetic_inclination"_s,
9806 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9807 << QgsExpressionFunction::Parameter( u
"date"_s )
9808 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9809 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9810 << QgsExpressionFunction::Parameter( u
"height"_s )
9811 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9812 fcnMagneticInclination,
9815 <<
new QgsStaticExpressionFunction(
9816 u
"magnetic_declination_rate_of_change"_s,
9818 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9819 << QgsExpressionFunction::Parameter( u
"date"_s )
9820 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9821 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9822 << QgsExpressionFunction::Parameter( u
"height"_s )
9823 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9824 fcnMagneticDeclinationRateOfChange,
9827 <<
new QgsStaticExpressionFunction(
9828 u
"magnetic_inclination_rate_of_change"_s,
9830 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9831 << QgsExpressionFunction::Parameter( u
"date"_s )
9832 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9833 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9834 << QgsExpressionFunction::Parameter( u
"height"_s )
9835 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9836 fcnMagneticInclinationRateOfChange,
9843 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9845 functions << geomFunc;
9847 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9849 functions << areaFunc;
9851 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9853 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9855 functions << lengthFunc;
9857 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9859 functions << perimeterFunc;
9861 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9863 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnRoundness, u
"GeometryGroup"_s );
9865 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9869 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9873 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9877 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions {
9878 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9879 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9880 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9881 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9882 { u
"overlay_equals_exact"_s, fcnGeomOverlayEqualsExact },
9883 { u
"overlay_equals_topological"_s, fcnGeomOverlayEqualsTopological },
9884 { u
"overlay_equals_fuzzy"_s, fcnGeomOverlayEqualsFuzzy },
9885 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9886 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9887 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9889 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9890 while ( i.hasNext() )
9893 QString defaultBackend = i.key() ==
"overlay_equals"_L1 ? QString(
"QGIS" ) : QString(
"GEOS" );
9894 QgsStaticExpressionFunction *fcnGeomOverlayFunc =
new QgsStaticExpressionFunction(
9897 << QgsExpressionFunction::Parameter( u
"layer"_s )
9898 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9899 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9900 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9901 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9902 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9903 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9904 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9905 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false )
9906 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, defaultBackend,
false )
9907 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4,
false ),
9918 functions << fcnGeomOverlayFunc;
9921 QgsStaticExpressionFunction *fcnGeomOverlayNearestFunc =
new QgsStaticExpressionFunction(
9922 u
"overlay_nearest"_s,
9924 << QgsExpressionFunction::Parameter( u
"layer"_s )
9925 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9926 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9927 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9928 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9929 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9930 fcnGeomOverlayNearest,
9939 functions << fcnGeomOverlayNearestFunc;
9942 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9947 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9948 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9949 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9950 <<
new QgsStaticExpressionFunction( u
"nodes_to_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"ignore_closing_nodes"_s,
true,
false ), fcnNodesToPoints, u
"GeometryGroup"_s )
9951 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9952 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9953 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9954 <<
new QgsStaticExpressionFunction( u
"make_point_m"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ) << QgsExpressionFunction::Parameter( u
"m"_s ), fcnMakePointM, u
"GeometryGroup"_s )
9955 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
9956 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
9957 <<
new QgsStaticExpressionFunction(
9959 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ) << QgsExpressionFunction::Parameter( u
"point3"_s ),
9963 <<
new QgsStaticExpressionFunction(
9966 << QgsExpressionFunction::Parameter( u
"center"_s )
9967 << QgsExpressionFunction::Parameter( u
"radius"_s )
9968 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9972 <<
new QgsStaticExpressionFunction(
9975 << QgsExpressionFunction::Parameter( u
"center"_s )
9976 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
9977 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
9978 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9979 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9983 <<
new QgsStaticExpressionFunction(
9984 u
"make_regular_polygon"_s,
9986 << QgsExpressionFunction::Parameter( u
"center"_s )
9987 << QgsExpressionFunction::Parameter( u
"radius"_s )
9988 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
9989 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
9990 fcnMakeRegularPolygon,
9993 <<
new QgsStaticExpressionFunction( u
"make_square"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnMakeSquare, u
"GeometryGroup"_s )
9994 <<
new QgsStaticExpressionFunction(
9995 u
"make_rectangle_3points"_s,
9997 << QgsExpressionFunction::Parameter( u
"point1"_s )
9998 << QgsExpressionFunction::Parameter( u
"point2"_s )
9999 << QgsExpressionFunction::Parameter( u
"point3"_s )
10000 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
10001 fcnMakeRectangleFrom3Points,
10004 <<
new QgsStaticExpressionFunction(
10007 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10008#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
10009 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
10011 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
10013 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
10020 <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
10022 <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
10024 <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
10026 <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
10028 QgsStaticExpressionFunction *xAtFunc
10029 =
new QgsStaticExpressionFunction( u
"$x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnOldXat, u
"GeometryGroup"_s, QString(),
true, QSet<QString>(),
false, QStringList() << u
"xat"_s );
10031 functions << xAtFunc;
10034 QgsStaticExpressionFunction *yAtFunc
10035 =
new QgsStaticExpressionFunction( u
"$y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnOldYat, u
"GeometryGroup"_s, QString(),
true, QSet<QString>(),
false, QStringList() << u
"yat"_s );
10037 functions << yAtFunc;
10040 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
10041 <<
new QgsStaticExpressionFunction( u
"x_min"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnXMin, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"xmin"_s )
10042 <<
new QgsStaticExpressionFunction( u
"x_max"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnXMax, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"xmax"_s )
10043 <<
new QgsStaticExpressionFunction( u
"y_min"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnYMin, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"ymin"_s )
10044 <<
new QgsStaticExpressionFunction( u
"y_max"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnYMax, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"ymax"_s )
10045 <<
new QgsStaticExpressionFunction( u
"geom_from_wkt"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s ), fcnGeomFromWKT, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"geomFromWKT"_s )
10046 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10047 <<
new QgsStaticExpressionFunction( u
"geom_from_gml"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"gml"_s ), fcnGeomFromGML, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"geomFromGML"_s )
10048 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
10049 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
10050 <<
new QgsStaticExpressionFunction(
10051 u
"intersects_bbox"_s,
10054 u
"GeometryGroup"_s,
10059 QStringList() << u
"bbox"_s
10061 <<
new QgsStaticExpressionFunction( u
"disjoint"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDisjoint, u
"GeometryGroup"_s )
10062 <<
new QgsStaticExpressionFunction( u
"intersects"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersects, u
"GeometryGroup"_s )
10063 <<
new QgsStaticExpressionFunction( u
"touches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnTouches, u
"GeometryGroup"_s )
10064 <<
new QgsStaticExpressionFunction( u
"crosses"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCrosses, u
"GeometryGroup"_s )
10065 <<
new QgsStaticExpressionFunction( u
"contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnContains, u
"GeometryGroup"_s )
10066 <<
new QgsStaticExpressionFunction( u
"overlaps"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnOverlaps, u
"GeometryGroup"_s )
10067 <<
new QgsStaticExpressionFunction( u
"within"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnWithin, u
"GeometryGroup"_s )
10068 <<
new QgsStaticExpressionFunction( u
"equals"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnEquals, u
"GeometryGroup"_s )
10069 <<
new QgsStaticExpressionFunction(
10072 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10073 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10074 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s ),
10078 <<
new QgsStaticExpressionFunction(
10079 u
"equals_topological"_s,
10081 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10082 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10083 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"GEOS"_s ),
10084 fcnIsEqualsTopological,
10087 <<
new QgsStaticExpressionFunction(
10090 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10091 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10092 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s )
10093 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4 ),
10097 <<
new QgsStaticExpressionFunction( u
"translate"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnTranslate, u
"GeometryGroup"_s )
10098 <<
new QgsStaticExpressionFunction(
10101 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10102 << QgsExpressionFunction::Parameter( u
"rotation"_s )
10103 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
10104 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
10108 <<
new QgsStaticExpressionFunction(
10111 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10112 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
10113 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
10114 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
10118 <<
new QgsStaticExpressionFunction(
10119 u
"affine_transform"_s,
10121 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10122 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
10123 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
10124 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
10125 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
10126 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
10127 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
10128 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
10129 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
10130 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
10131 fcnAffineTransform,
10134 <<
new QgsStaticExpressionFunction(
10137 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10138 << QgsExpressionFunction::Parameter( u
"distance"_s )
10139 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
10140 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
10141 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
10142 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
10146 <<
new QgsStaticExpressionFunction( u
"force_rhr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForceRHR, u
"GeometryGroup"_s )
10147 <<
new QgsStaticExpressionFunction( u
"force_polygon_cw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCW, u
"GeometryGroup"_s )
10148 <<
new QgsStaticExpressionFunction( u
"force_polygon_ccw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCCW, u
"GeometryGroup"_s )
10149 <<
new QgsStaticExpressionFunction(
10152 << QgsExpressionFunction::Parameter( u
"center"_s )
10153 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10154 << QgsExpressionFunction::Parameter( u
"width"_s )
10155 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
10156 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ),
10160 <<
new QgsStaticExpressionFunction(
10161 u
"tapered_buffer"_s,
10163 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10164 << QgsExpressionFunction::Parameter( u
"start_width"_s )
10165 << QgsExpressionFunction::Parameter( u
"end_width"_s )
10166 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ),
10170 <<
new QgsStaticExpressionFunction( u
"buffer_by_m"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ), fcnBufferByM, u
"GeometryGroup"_s )
10171 <<
new QgsStaticExpressionFunction(
10174 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10175 << QgsExpressionFunction::Parameter( u
"distance"_s )
10176 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10178 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10182 <<
new QgsStaticExpressionFunction(
10183 u
"single_sided_buffer"_s,
10185 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10186 << QgsExpressionFunction::Parameter( u
"distance"_s )
10187 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10189 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10190 fcnSingleSidedBuffer,
10193 <<
new QgsStaticExpressionFunction(
10195 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10199 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
10200 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
10201 <<
new QgsStaticExpressionFunction( u
"pole_of_inaccessibility"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
10202 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
10203 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
10204 <<
new QgsStaticExpressionFunction( u
"interior_ring_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnInteriorRingN, u
"GeometryGroup"_s )
10205 <<
new QgsStaticExpressionFunction( u
"geometry_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnGeometryN, u
"GeometryGroup"_s )
10206 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
10207 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
10208 <<
new QgsStaticExpressionFunction( u
"shared_paths"_s,
QgsExpressionFunction::ParameterList { QgsExpressionFunction::Parameter( u
"geometry1"_s ), QgsExpressionFunction::Parameter( u
"geometry2"_s ) }, fcnSharedPaths, u
"GeometryGroup"_s )
10210 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
10211 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
10212 <<
new QgsStaticExpressionFunction(
10215 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10216 << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
10217 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
10218 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
10219 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ),
10223 <<
new QgsStaticExpressionFunction(
10224 u
"triangular_wave"_s,
10225 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10226 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10227 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10228 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10232 <<
new QgsStaticExpressionFunction(
10233 u
"triangular_wave_randomized"_s,
10234 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10235 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10236 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10237 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10238 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10239 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10240 fcnTriangularWaveRandomized,
10243 <<
new QgsStaticExpressionFunction(
10245 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10246 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10247 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10248 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10252 <<
new QgsStaticExpressionFunction(
10253 u
"square_wave_randomized"_s,
10254 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10255 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10256 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10257 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10258 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10259 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10260 fcnSquareWaveRandomized,
10263 <<
new QgsStaticExpressionFunction(
10265 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10266 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10267 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10268 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10272 <<
new QgsStaticExpressionFunction(
10273 u
"wave_randomized"_s,
10274 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10275 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10276 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10277 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10278 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10279 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10280 fcnRoundWaveRandomized,
10283 <<
new QgsStaticExpressionFunction(
10284 u
"apply_dash_pattern"_s,
10286 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10287 QgsExpressionFunction::Parameter( u
"pattern"_s ),
10288 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
10289 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
10290 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
10291 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
10293 fcnApplyDashPattern,
10296 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"vertices"_s ) }, fcnDensifyByCount, u
"GeometryGroup"_s )
10297 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"distance"_s ) }, fcnDensifyByDistance, u
"GeometryGroup"_s )
10298 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
10299 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
10300 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
10301 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
10302 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
10303 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
10304 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
10305 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
10306 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
10307 <<
new QgsStaticExpressionFunction(
10308 u
"is_empty_or_null"_s,
10311 u
"GeometryGroup"_s,
10319 <<
new QgsStaticExpressionFunction( u
"convex_hull"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnConvexHull, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"convexHull"_s )
10320#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
10321 <<
new QgsStaticExpressionFunction(
10324 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10325 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
10326 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ),
10331 <<
new QgsStaticExpressionFunction( u
"oriented_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnOrientedBBox, u
"GeometryGroup"_s )
10332 <<
new QgsStaticExpressionFunction( u
"main_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnMainAngle, u
"GeometryGroup"_s )
10333 <<
new QgsStaticExpressionFunction( u
"minimal_circle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ), fcnMinimalCircle, u
"GeometryGroup"_s )
10334 <<
new QgsStaticExpressionFunction( u
"difference"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDifference, u
"GeometryGroup"_s )
10335 <<
new QgsStaticExpressionFunction( u
"distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDistance, u
"GeometryGroup"_s )
10336 <<
new QgsStaticExpressionFunction(
10337 u
"hausdorff_distance"_s,
10339 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10340 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10341 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
10342 fcnHausdorffDistance,
10345 <<
new QgsStaticExpressionFunction( u
"intersection"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersection, u
"GeometryGroup"_s )
10346 <<
new QgsStaticExpressionFunction(
10347 u
"sym_difference"_s,
10350 u
"GeometryGroup"_s,
10355 QStringList() << u
"symDifference"_s
10357 <<
new QgsStaticExpressionFunction( u
"combine"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10358 <<
new QgsStaticExpressionFunction( u
"union"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10359 <<
new QgsStaticExpressionFunction(
10363 u
"GeometryGroup"_s,
10368 QStringList() << u
"geomToWKT"_s
10370 <<
new QgsStaticExpressionFunction( u
"geom_to_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10371 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
10372 <<
new QgsStaticExpressionFunction(
10374 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"source_auth_id"_s ) << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
10375 fcnTransformGeometry,
10378 <<
new QgsStaticExpressionFunction(
10380 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ),
10382 u
"GeometryGroup"_s,
10385 <<
new QgsStaticExpressionFunction( u
"is_multipart"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsMultipart, u
"GeometryGroup"_s )
10390 <<
new QgsStaticExpressionFunction( u
"sinuosity"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSinuosity, u
"GeometryGroup"_s )
10391 <<
new QgsStaticExpressionFunction( u
"straight_distance_2d"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStraightDistance2d, u
"GeometryGroup"_s );
10394 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction(
10397 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10398 << QgsExpressionFunction::Parameter( u
"orderby"_s )
10399 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
10401 u
"GeometryGroup"_s,
10406 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10407 for ( QgsExpressionNode *argNode : argList )
10409 if ( !argNode->isStatic( parent, context ) )
10415 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10417 QString expString = argNode->
eval( parent, context ).toString();
10421 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10431 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10432 QString
expression = argNode->
eval( parent, context ).toString();
10434 e.prepare( context );
10439 functions << orderPartsFunc;
10442 <<
new QgsStaticExpressionFunction( u
"closest_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnClosestPoint, u
"GeometryGroup"_s )
10443 <<
new QgsStaticExpressionFunction( u
"shortest_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnShortestLine, u
"GeometryGroup"_s )
10444 <<
new QgsStaticExpressionFunction( u
"line_interpolate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
10445 <<
new QgsStaticExpressionFunction(
10446 u
"line_interpolate_point_by_m"_s,
10448 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10449 << QgsExpressionFunction::Parameter( u
"m"_s )
10450 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10451 fcnLineInterpolatePointByM,
10454 <<
new QgsStaticExpressionFunction( u
"line_interpolate_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
10455 <<
new QgsStaticExpressionFunction( u
"line_locate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
10456 <<
new QgsStaticExpressionFunction(
10457 u
"line_locate_m"_s,
10459 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10460 << QgsExpressionFunction::Parameter( u
"m"_s )
10461 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10465 <<
new QgsStaticExpressionFunction( u
"angle_at_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
10466 <<
new QgsStaticExpressionFunction( u
"distance_to_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
10467 <<
new QgsStaticExpressionFunction(
10468 u
"line_substring"_s,
10469 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10477 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
10479 functions << idFunc;
10481 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
10483 functions << currentFeatureFunc;
10485 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction(
10489 u
"Record and Attributes"_s,
10494 QStringList() << u
"$uuid"_s
10497 functions << uuidFunc;
10500 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
10501 <<
new QgsStaticExpressionFunction(
10503 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
10505 u
"Record and Attributes"_s,
10510 QStringList() << u
"QgsExpressionUtils::getFeature"_s
10512 <<
new QgsStaticExpressionFunction(
10513 u
"get_feature_by_id"_s,
10516 u
"Record and Attributes"_s,
10523 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction(
10527 u
"Record and Attributes"_s,
10533 functions << attributesFunc;
10534 QgsStaticExpressionFunction *representAttributesFunc
10535 =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1, fcnRepresentAttributes, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10537 functions << representAttributesFunc;
10539 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction(
10540 u
"is_feature_valid"_s,
10542 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10543 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10544 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10545 fcnValidateFeature,
10546 u
"Record and Attributes"_s,
10552 functions << validateFeature;
10554 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction(
10555 u
"is_attribute_valid"_s,
10557 << QgsExpressionFunction::Parameter( u
"attribute"_s,
false )
10559 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10560 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10561 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10562 fcnValidateAttribute,
10563 u
"Record and Attributes"_s,
10569 functions << validateAttribute;
10571 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction( u
"maptip"_s, -1, fcnFeatureMaptip, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10573 functions << maptipFunc;
10575 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction( u
"display_expression"_s, -1, fcnFeatureDisplayExpression, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10577 functions << displayFunc;
10579 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction( u
"is_selected"_s, -1, fcnIsSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10581 functions << isSelectedFunc;
10583 functions <<
new QgsStaticExpressionFunction( u
"num_selected"_s, -1, fcnNumSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10585 functions <<
new QgsStaticExpressionFunction(
10586 u
"sqlite_fetch_and_increment"_s,
10588 << QgsExpressionFunction::Parameter( u
"database"_s )
10589 << QgsExpressionFunction::Parameter( u
"table"_s )
10590 << QgsExpressionFunction::Parameter( u
"id_field"_s )
10591 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
10592 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
10593 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
10594 fcnSqliteFetchAndIncrement,
10595 u
"Record and Attributes"_s
10600 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
10601 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
10605 QgsStaticExpressionFunction *representValueFunc
10606 =
new QgsStaticExpressionFunction( u
"represent_value"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"field_name"_s,
true ), fcnRepresentValue, u
"Record and Attributes"_s );
10609 Q_UNUSED( context )
10612 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
10619 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
10629 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
10634 functions << representValueFunc;
10638 <<
new QgsStaticExpressionFunction(
10639 u
"layer_property"_s,
10641 << QgsExpressionFunction::Parameter( u
"layer"_s )
10642 << QgsExpressionFunction::Parameter( u
"property"_s )
10643 << QgsExpressionFunction::Parameter( u
"translate"_s,
true,
true ),
10644 fcnGetLayerProperty,
10647 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"part"_s,
true ), fcnDecodeUri, u
"Map Layers"_s )
10648 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary_data"_s ), fcnMimeType, u
"General"_s )
10649 <<
new QgsStaticExpressionFunction(
10650 u
"raster_statistic"_s,
10651 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"statistic"_s ),
10652 fcnGetRasterBandStat,
10657 QgsStaticExpressionFunction *varFunction
10667 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10669 if ( !argNode->
isStatic( parent, context ) )
10672 const QString varName = argNode->
eval( parent, context ).toString();
10673 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
10677 return scope ? scope->
isStatic( varName ) :
false;
10682 if ( node && node->
args()->
count() > 0 )
10684 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10685 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
10687 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
10694 functions << varFunction;
10696 QgsStaticExpressionFunction *evalTemplateFunction
10701 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10703 if ( argNode->
isStatic( parent, context ) )
10705 QString expString = argNode->
eval( parent, context ).toString();
10709 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10716 functions << evalTemplateFunction;
10718 QgsStaticExpressionFunction *evalFunc
10723 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10725 if ( argNode->
isStatic( parent, context ) )
10727 QString expString = argNode->
eval( parent, context ).toString();
10731 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10739 functions << evalFunc;
10741 QgsStaticExpressionFunction *attributeFunc
10742 =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10744 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10745 for ( QgsExpressionNode *argNode : argList )
10747 if ( !argNode->
isStatic( parent, context ) )
10759 functions << attributeFunc;
10763 <<
new QgsWithVariableExpressionFunction()
10764 <<
new QgsStaticExpressionFunction(
10766 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10770 <<
new QgsStaticExpressionFunction(
10771 u
"raster_attributes"_s,
10772 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10773 fcnRasterAttributes,
10778 <<
new QgsArrayForeachExpressionFunction()
10779 <<
new QgsArrayFilterExpressionFunction()
10780 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10781 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10782 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10783 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10784 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10785 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayAll, u
"Arrays"_s )
10786 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10787 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10793 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10794 <<
new QgsStaticExpressionFunction( u
"array_majority"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"option"_s,
true, QVariant(
"all" ) ), fcnArrayMajority, u
"Arrays"_s )
10795 <<
new QgsStaticExpressionFunction( u
"array_minority"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"option"_s,
true, QVariant(
"all" ) ), fcnArrayMinority, u
"Arrays"_s )
10797 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10798 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10799 <<
new QgsStaticExpressionFunction(
10801 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
10805 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10806 <<
new QgsStaticExpressionFunction(
10807 u
"array_remove_all"_s,
10818 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10819 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"priority"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10820 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10821 <<
new QgsStaticExpressionFunction(
10823 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ),
10827 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10828 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10829 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10830 <<
new QgsStaticExpressionFunction(
10831 u
"array_to_string"_s,
10833 << QgsExpressionFunction::Parameter( u
"array"_s )
10834 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10835 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10839 <<
new QgsStaticExpressionFunction(
10840 u
"string_to_array"_s,
10842 << QgsExpressionFunction::Parameter( u
"string"_s )
10843 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10844 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10848 <<
new QgsStaticExpressionFunction(
10849 u
"generate_series"_s,
10850 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ),
10854 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10857 <<
new QgsStaticExpressionFunction( u
"from_json"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLoadJson, u
"Maps"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"json_to_map"_s )
10858 <<
new QgsStaticExpressionFunction( u
"to_json"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"json_string"_s ), fcnWriteJson, u
"Maps"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"map_to_json"_s )
10859 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10861 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10862 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10863 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10864 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10865 <<
new QgsStaticExpressionFunction( u
"map_insert"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnMapInsert, u
"Maps"_s )
10866 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10869 <<
new QgsStaticExpressionFunction( u
"map_prefix_keys"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"prefix"_s ), fcnMapPrefixKeys, u
"Maps"_s )
10870 <<
new QgsStaticExpressionFunction( u
"map_to_html_table"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlTable, u
"Maps"_s )
10871 <<
new QgsStaticExpressionFunction( u
"map_to_html_dl"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlDefinitionList, u
"Maps"_s )
10881 *sOwnedFunctions() << func;
10882 *sBuiltinFunctions() << func->name();
10883 sBuiltinFunctions()->append( func->aliases() );
10897 QMutexLocker locker( &sFunctionsMutex );
10898 sFunctions()->append( function );
10899 if ( transferOwnership )
10900 sOwnedFunctions()->append( function );
10915 QMutexLocker locker( &sFunctionsMutex );
10916 sFunctions()->removeAt( fnIdx );
10917 sFunctionIndexMap.clear();
10925 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10926 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10928 sBuiltinFunctions()->removeAll( func->name() );
10929 for (
const QString &alias : func->aliases() )
10931 sBuiltinFunctions()->removeAll( alias );
10934 sFunctions()->removeAll( func );
10937 qDeleteAll( *sOwnedFunctions() );
10938 sOwnedFunctions()->clear();
10943 if ( sBuiltinFunctions()->isEmpty() )
10947 return *sBuiltinFunctions();
10952 u
"array_foreach"_s,
10962 QgsExpressionNode::NodeList *args = node->
args();
10964 if ( args->
count() < 2 )
10967 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10977 QVariantList result;
10979 if ( args->
count() < 2 )
10983 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10985 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10986 std::unique_ptr< QgsExpressionContext > tempContext;
10989 tempContext = std::make_unique< QgsExpressionContext >();
10990 subContext = tempContext.get();
10993 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10997 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
11001 result << args->
at( 1 )->
eval( parent, subContext );
11014 Q_UNUSED( context )
11026 if ( args->
count() < 2 )
11030 args->
at( 0 )->
prepare( parent, context );
11034 subContext = *context;
11041 args->
at( 1 )->
prepare( parent, &subContext );
11054 QgsExpressionNode::NodeList *args = node->
args();
11056 if ( args->
count() < 2 )
11059 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11069 QVariantList result;
11071 if ( args->
count() < 2 )
11075 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11077 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11078 std::unique_ptr< QgsExpressionContext > tempContext;
11081 tempContext = std::make_unique< QgsExpressionContext >();
11082 subContext = tempContext.get();
11085 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11089 if ( args->
count() >= 3 )
11091 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
11093 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
11095 limit = limitVar.toInt();
11103 for (
const QVariant &value : array )
11105 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
11106 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
11110 if ( limit > 0 && limit == result.size() )
11125 Q_UNUSED( context )
11137 if ( args->
count() < 2 )
11141 args->
at( 0 )->
prepare( parent, context );
11145 subContext = *context;
11151 args->
at( 1 )->
prepare( parent, &subContext );
11163 QgsExpressionNode::NodeList *args = node->
args();
11165 if ( args->
count() < 3 )
11169 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11171 QVariant
name = args->
at( 0 )->
eval( parent, context );
11172 QVariant value = args->
at( 1 )->
eval( parent, context );
11175 appendTemporaryVariable( context,
name.toString(), value );
11176 if ( args->
at( 2 )->
isStatic( parent, context ) )
11178 popTemporaryVariable( context );
11189 if ( args->
count() < 3 )
11193 QVariant
name = args->
at( 0 )->
eval( parent, context );
11194 QVariant value = args->
at( 1 )->
eval( parent, context );
11196 const QgsExpressionContext *updatedContext = context;
11197 std::unique_ptr< QgsExpressionContext > tempContext;
11198 if ( !updatedContext )
11200 tempContext = std::make_unique< QgsExpressionContext >();
11201 updatedContext = tempContext.get();
11204 appendTemporaryVariable( updatedContext,
name.toString(), value );
11205 result = args->
at( 2 )->
eval( parent, updatedContext );
11208 popTemporaryVariable( updatedContext );
11217 Q_UNUSED( context )
11229 if ( args->
count() < 3 )
11234 QVariant value = args->
at( 1 )->
prepare( parent, context );
11237 std::unique_ptr< QgsExpressionContext > tempContext;
11238 if ( !updatedContext )
11240 tempContext = std::make_unique< QgsExpressionContext >();
11241 updatedContext = tempContext.get();
11244 appendTemporaryVariable( updatedContext,
name.toString(), value );
11245 args->
at( 2 )->
prepare( parent, updatedContext );
11248 popTemporaryVariable( updatedContext );
11253void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
11255 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
11256 delete updatedContext->
popScope();
11259void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
11261 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
11262 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
11264 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
GeometryBackend
Geometry backend for QgsGeometry.
@ GEOS
Use GEOS implementation.
@ QGIS
Use internal implementation.
@ Left
Buffer to left of line.
DashPatternSizeAdjustment
Dash pattern size adjustment options.
@ ScaleDashOnly
Only dash lengths are adjusted.
@ ScaleBothDashAndGap
Both the dash and gap lengths are adjusted equally.
@ ScaleGapOnly
Only gap lengths are adjusted.
@ Success
Operation succeeded.
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
JoinStyle
Join styles for buffers.
@ Bevel
Use beveled joins.
@ Round
Use rounded joins.
@ Miter
Use mitered joins.
RasterBandStatistic
Available raster band statistics.
@ StdDev
Standard deviation.
@ NoStatistic
No statistic.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
EndCapStyle
End cap styles for buffers.
@ Flat
Flat cap (in line with start/end of line).
@ Square
Square cap (extends past start/end of line by buffer distance).
Aggregate
Available aggregates to calculate.
@ StringMinimumLength
Minimum length of string (string fields only).
@ FirstQuartile
First quartile (numeric fields only).
@ Mean
Mean of values (numeric fields only).
@ Median
Median of values (numeric fields only).
@ StringMaximumLength
Maximum length of string (string fields only).
@ Range
Range of values (max - min) (numeric and datetime fields only).
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
@ Minority
Minority of values.
@ CountMissing
Number of missing (null) values.
@ ArrayAggregate
Create an array of values.
@ Majority
Majority of values.
@ StDevSample
Sample standard deviation of values (numeric fields only).
@ ThirdQuartile
Third quartile (numeric fields only).
@ CountDistinct
Number of distinct values.
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
DashPatternLineEndingRule
Dash pattern line ending rules.
@ HalfDash
Start or finish the pattern with a half length dash.
@ HalfGap
Start or finish the pattern with a half length gap.
@ FullGap
Start or finish the pattern with a full gap.
@ FullDash
Start or finish the pattern with a full dash.
MakeValidMethod
Algorithms to use when repairing invalid geometries.
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
@ Structure
Structured method, first makes all rings valid and then merges shells and subtracts holes from shells...
@ GeometryCollection
GeometryCollection.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
bool isMeasure() const
Returns true if the geometry contains m values.
virtual QgsRectangle boundingBox() const
Returns the minimal bounding box for the geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
virtual QgsCoordinateSequence coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
virtual int partCount() const =0
Returns count of parts contained in the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
static Qgis::Aggregate stringToAggregate(const QString &string, bool *ok=nullptr)
Converts a string to a aggregate type.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QgsArrayFilterExpressionFunction()
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
QgsArrayForeachExpressionFunction()
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
bool isEmpty() const override
Returns true if the geometry is empty.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
double roundness() const
Returns the roundness of the curve polygon.
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.
Abstract base class for curved geometry type.
double sinuosity() const
Returns the curve sinuosity, which is the ratio of the curve length() to curve straightDistance2d().
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
virtual bool isClosed() const
Returns true if the curve is closed.
double straightDistance2d() const
Returns the straight distance of the curve, i.e.
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double convertLengthMeasurement(double length, Qgis::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
double bearing(const QgsPointXY &p1, const QgsPointXY &p2) const
Computes the bearing (in radians) between two points.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
double convertAreaMeasurement(double area, Qgis::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
Defines a QGIS exception class.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
QString uniqueHash(bool &ok, const QSet< QString > &variables=QSet< QString >()) const
Returns a unique hash representing the current state of the context.
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool hasGeometry() const
Returns true if the context has a geometry associated with it.
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
An abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
bool operator==(const QgsExpressionFunction &other) const
QgsExpressionFunction(const QString &fnname, int params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters.
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
virtual bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
Will be called during prepare to determine if the function is static.
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
bool lazyEval() const
true if this function should use lazy evaluation.
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
QString name() const
The name of the function.
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)=0
Returns result of evaluating the function.
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
virtual bool handlesNull() const
Returns true if the function handles NULL values in arguments by itself, and the default NULL value h...
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
const QString helpText() const
The help text for the function.
virtual bool usesGeometry(const QgsExpressionNodeFunction *node) const
Does this function use a geometry object.
An expression node which takes its value from a feature's field.
QString name() const
The name of the column.
An expression node for expression functions.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
An expression node for literal values.
A list of expression nodes.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
int count() const
Returns the number of nodes in the list.
Abstract base class for all nodes that can appear in an expression.
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
A set of expression-related functions.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
QString expression() const
Returns the original, unmodified expression string.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
Qgis::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static const QStringList & BuiltinFunctions()
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static PRIVATE QString helpText(QString name)
Returns the help text for a specified function.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
static bool unregisterFunction(const QString &name)
Unregisters a function from the expression engine.
Qgis::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions).
friend class QgsExpressionNodeFunction
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QgsExpression(const QString &expr)
Creates a new expression based on the provided string.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Represents a list of OrderByClauses, with the most important first and the least important last.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsFeatureRequest & setRequestMayBeNested(bool requestMayBeNested)
In case this request may be run nested within another already running iteration on the same connectio...
QgsFeatureRequest & setTimeout(int timeout)
Sets the timeout (in milliseconds) for the maximum time we should wait during feature requests before...
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the iterator to check if it should be cance...
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
QgsVectorLayer * materialize(const QgsFeatureRequest &request, QgsFeedback *feedback=nullptr)
Materializes a request (query) made against this feature source, by running it over the source and re...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
ConstraintStrength
Strength of constraints.
@ ConstraintStrengthNotSet
Constraint is not set.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
int size() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
int partCount() const override
Returns count of parts contained in the geometry.
int numGeometries() const
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Encapsulates parameters under which a geometry operation is performed.
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
A geometry is the spatial representation of a feature.
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
double lineLocatePoint(const QgsGeometry &point) const
Returns a distance representing the location along this linestring of the closest point on this lines...
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points shared by this geometry and other.
double length() const
Returns the planar, 2-dimensional length of geometry.
QgsGeometry offsetCurve(double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
QgsGeometry densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
QgsGeometry poleOfInaccessibility(double precision, double *distanceToBoundary=nullptr) const
Calculates the approximate pole of inaccessibility for a surface, which is the most distant internal ...
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsGeometry squareWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs square waves along the boundary of the geometry, with the specified wavelength and amplitu...
QgsGeometry concaveHull(double targetPercent, bool allowHoles=false, QgsFeedback *feedback=nullptr) const
Returns a possibly concave polygon that contains all the points in the geometry.
QgsGeometry triangularWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs triangular waves along the boundary of the geometry, with the specified wavelength and amp...
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
Q_INVOKABLE bool touches(const QgsGeometry &geometry) const
Returns true if the geometry touches another geometry.
bool isExactlyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry applyDashPattern(const QVector< double > &pattern, Qgis::DashPatternLineEndingRule startRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternLineEndingRule endRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternSizeAdjustment adjustment=Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap, double patternOffset=0) const
Applies a dash pattern to a geometry, returning a MultiLineString geometry which is the input geometr...
QgsGeometry roundWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs rounded (sine-like) waves along the boundary of the geometry, with the specified wavelengt...
QgsGeometry nearestPoint(const QgsGeometry &other) const
Returns the nearest (closest) point on this geometry to another geometry.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
QgsGeometry mergeLines(const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Q_INVOKABLE bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
QgsGeometry singleSidedBuffer(double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle=Qgis::JoinStyle::Round, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
Q_INVOKABLE bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
double area() const
Returns the planar, 2-dimensional area of the geometry.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
Q_INVOKABLE bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false, QgsFeedback *feedback=nullptr) const
Attempts to make an invalid geometry valid without losing vertices.
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
QgsGeometry sharedPaths(const QgsGeometry &other) const
Find paths shared between the two given lineal geometries (this and other).
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
QgsGeometry buffer(double distance, int segments, QgsFeedback *feedback=nullptr) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
bool isFuzzyEqual(const QgsGeometry &geometry, double epsilon=1e-4, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry within the tolerance epsilon using the specified backend.
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry extendLine(double startDistance, double endDistance) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
QgsGeometry triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
bool isTopologicallyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::GEOS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry simplify(double tolerance, QgsFeedback *feedback=nullptr) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Q_INVOKABLE bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
Q_INVOKABLE bool overlaps(const QgsGeometry &geometry) const
Returns true if the geometry overlaps another geometry.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle(double tolerance, QString *errorMsg=nullptr, QgsFeedback *feedback=nullptr) const
Returns the maximum inscribed circle.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Represents a color stop within a QgsGradientColorRamp color ramp.
static QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
static QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.
A representation of the interval between two datetime values.
bool isValid() const
Returns true if the interval is valid.
double days() const
Returns the interval duration in days.
double weeks() const
Returns the interval duration in weeks.
double months() const
Returns the interval duration in months (based on a 30 day month).
double seconds() const
Returns the interval duration in seconds.
double years() const
Returns the interval duration in years (based on an average year length).
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
Line string geometry type, with support for z-dimension and m-values.
bool lineLocatePointByM(double m, double &x, double &y, double &z, double &distanceFromStart, bool use3DDistance=true) const
Attempts to locate a point on the linestring by m value.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
Represents a model of the Earth's magnetic field.
static bool fieldComponentsWithTimeDerivatives(double Bx, double By, double Bz, double Bxt, double Byt, double Bzt, double &H, double &F, double &D, double &I, double &Ht, double &Ft, double &Dt, double &It)
Compute various quantities dependent on a magnetic field and their rates of change.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Base class for all map layer types.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QgsLayerMetadata metadata
QString publicSource(bool hidePassword=false) const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
virtual bool isEditable() const
Returns true if the layer can be edited.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
Implementation of a geometry simplifier using the "MapToPixel" algorithm.
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Custom exception class which is raised when an operation is not supported.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
double inclination(const QgsPoint &other) const
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Quadrilateral geometry type.
static QgsQuadrilateral squareFromDiagonal(const QgsPoint &p1, const QgsPoint &p2)
Construct a QgsQuadrilateral as a square from a diagonal.
QgsPolygon * toPolygon(bool force2D=false) const
Returns the quadrilateral as a new polygon.
static QgsQuadrilateral rectangleFrom3Points(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, ConstructionOption mode)
Construct a QgsQuadrilateral as a Rectangle from 3 points.
ConstructionOption
A quadrilateral can be constructed from 3 points where the second distance can be determined by the t...
@ Distance
Second distance is equal to the distance between 2nd and 3rd point.
@ Projected
Second distance is equal to the distance of the perpendicular projection of the 3rd point on the segm...
The Field class represents a Raster Attribute Table field, including its name, usage and type.
bool isRamp() const
Returns true if the field carries a color ramp component information (RedMin/RedMax,...
bool isColor() const
Returns true if the field carries a color component (Red, Green, Blue and optionally Alpha) informati...
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
A rectangle specified with double values.
void grow(double delta)
Grows the rectangle in place by the specified amount.
Regular Polygon geometry type.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices).
QgsPolygon * toPolygon() const
Returns as a polygon.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
Q_INVOKABLE QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
void setUsesGeometryFunction(const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry)
Set a function that will be called when determining if the function requires feature geometry or not.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
static QString unaccent(const QString &input)
Removes accents and other diacritical marks from a string, replacing accented characters with their u...
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Contains utility functions for working with symbols and symbol layers.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
Allows creation of a multi-layer database-side transaction.
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QVariant aggregate(Qgis::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters ¶meters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeatureIds *fids=nullptr, QgsFeedback *feedback=nullptr, QString *error=nullptr) const
Calculates an aggregated value from the layer's features.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QgsWithVariableExpressionFunction()
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored).
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 allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
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
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
const QString cacheKey(const QString &pathIn)
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
std::function< bool(const QgsGeometry &geometry, const QgsGeometry &other, const QVariantList &values, Qgis::GeometryBackend backend)> RelationFunction
allows geometry function with different parameters to be used with the same executeGeomOverlay functi...
double qDateTimeToDecimalYear(const QDateTime &dateTime)
QList< QgsExpressionFunction * > ExpressionFunctionList
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColorObject(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
#define SET_EVAL_ERROR(x)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QLineF segment(int index, QRectF rect, double radius)
A bundle of parameters controlling aggregate calculation.
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
Single variable definition for use within a QgsExpressionContextScope.
The Context struct stores the current layer and coordinate transform context.
const QgsMapLayer * layer
QgsCoordinateTransformContext transformContext
Utility class for identifying a unique vertex within a geometry.