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();
960 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
971 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
973 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
978 relation = relations.at( 0 );
985 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
987 value = node->
eval( parent, context );
993 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
998 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
1000 QString subExpression = node->
dump();
1004 if ( values.count() > 3 )
1006 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1008 value = node->
eval( parent, context );
1010 parameters.
delimiter = value.toString();
1015 if ( values.count() > 4 )
1017 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
1020 if ( !nl || nl->value().isValid() )
1022 orderBy = node->
dump();
1033 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 );
1043 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1047 if ( !error.isEmpty() )
1048 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1050 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1060static QVariant fcnAggregateGeneric(
1066 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1074 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
1078 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1085 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1087 QString subExpression = node->
dump();
1091 if ( values.count() > 1 )
1093 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
1096 if ( !nl || nl->value().isValid() )
1097 groupBy = node->
dump();
1101 if ( values.count() > 2 )
1103 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
1106 if ( !nl || nl->value().isValid() )
1112 if ( orderByPos >= 0 && values.count() > orderByPos )
1114 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
1117 if ( !nl || nl->value().isValid() )
1119 orderBy = node->
dump();
1127 if ( !groupBy.isEmpty() )
1130 QVariant groupByValue = groupByExp.evaluate( context );
1132 if ( !parameters.
filter.isEmpty() )
1133 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1135 parameters.
filter = groupByClause;
1141 bool isStatic =
true;
1142 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1143 for (
const QString &varName : refVars )
1146 if ( scope && !scope->
isStatic( varName ) )
1157 const QString contextHash = context->
uniqueHash( ok, refVars );
1160 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
1165 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1177 subContext.appendScope( subScope );
1179 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1183 if ( !error.isEmpty() )
1184 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1186 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1291 if ( values.count() > 3 )
1293 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1295 QVariant value = node->
eval( parent, context );
1297 parameters.
delimiter = value.toString();
1308 if ( values.count() > 3 )
1310 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1312 QVariant value = node->
eval( parent, context );
1314 parameters.
delimiter = value.toString();
1330 QVariant scale = context->
variable( u
"map_scale"_s );
1335 const double v = scale.toDouble( &ok );
1343 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1344 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1345 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1348 if ( testValue <= minValue )
1350 return QVariant( minValue );
1352 else if ( testValue >= maxValue )
1354 return QVariant( maxValue );
1358 return QVariant( testValue );
1364 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1365 return QVariant( std::floor( x ) );
1370 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1371 return QVariant( std::ceil( x ) );
1376 const QVariant value = values.at( 0 );
1377 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1379 return QVariant(
false );
1381 else if ( value.userType() == QMetaType::QString )
1384 return QVariant( !value.toString().isEmpty() );
1386 else if ( QgsExpressionUtils::isList( value ) )
1388 return !value.toList().isEmpty();
1390 return QVariant( value.toBool() );
1394 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1398 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1402 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1407 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1408 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1409 if ( format.isEmpty() && !language.isEmpty() )
1411 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1412 return QVariant( QDateTime() );
1415 if ( format.isEmpty() && language.isEmpty() )
1416 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1418 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1419 QLocale locale = QLocale();
1420 if ( !language.isEmpty() )
1422 locale = QLocale( language );
1425 QDateTime datetime = locale.toDateTime( datetimestring, format );
1426 if ( !datetime.isValid() )
1428 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1429 datetime = QDateTime();
1431 return QVariant( datetime );
1436 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1437 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1438 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1440 const QDate date( year, month, day );
1441 if ( !date.isValid() )
1443 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1446 return QVariant( date );
1451 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1452 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1453 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1455 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1456 if ( !time.isValid() )
1458 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1461 return QVariant( time );
1466 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1467 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1468 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1469 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1470 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1471 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1473 const QDate date( year, month, day );
1474 if ( !date.isValid() )
1476 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1479 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1480 if ( !time.isValid() )
1482 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1485 return QVariant( QDateTime( date, time ) );
1490 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1494#if QT_FEATURE_timezone > 0
1495 if ( !timeZoneId.isEmpty() )
1497 tz = QTimeZone( timeZoneId.toUtf8() );
1500 if ( !tz.isValid() )
1502 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1507 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1509 return QVariant::fromValue( tz );
1514#if QT_FEATURE_timezone > 0
1515 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1516 if ( datetime.isValid() )
1518 return QVariant::fromValue( datetime.timeZone() );
1523 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1530#if QT_FEATURE_timezone > 0
1531 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1532 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1533 if ( datetime.isValid() && tz.isValid() )
1535 datetime.setTimeZone( tz );
1536 return QVariant::fromValue( datetime );
1541 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1548#if QT_FEATURE_timezone > 0
1549 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1550 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1551 if ( datetime.isValid() && tz.isValid() )
1553 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1558 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1565#if QT_FEATURE_timezone > 0
1566 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1567 if ( timeZone.isValid() )
1569 return QString( timeZone.id() );
1574 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1581 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1582 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1583 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1584 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1585 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1586 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1587 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1589 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1594 for (
const QVariant &value : values )
1605 const QVariant val1 = values.at( 0 );
1606 const QVariant val2 = values.at( 1 );
1616 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1617 return QVariant( str.toLower() );
1622 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1623 return QVariant( str.toUpper() );
1628 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1629 QStringList elems = str.split(
' ' );
1630 for (
int i = 0; i < elems.size(); i++ )
1632 if ( elems[i].size() > 1 )
1633 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1635 return QVariant( elems.join(
' '_L1 ) );
1640 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1641 return QVariant( str.trimmed() );
1646 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1648 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1650 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1651 str.replace( re, QString() );
1652 return QVariant( str );
1657 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1659 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1661 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1662 str.replace( re, QString() );
1663 return QVariant( str );
1668 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1669 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1675 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1676 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1682 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1683 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1690 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1696 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1697 return QVariant( QString( character ) );
1702 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1704 if ( value.isEmpty() )
1709 int res = value.at( 0 ).unicode();
1710 return QVariant( res );
1715 if ( values.length() == 2 || values.length() == 3 )
1717 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1718 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1720 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1733 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1737 return QVariant( geom.
length() );
1743 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1744 return QVariant( str.length() );
1749 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1754 double totalLength = 0;
1759 totalLength += line->length3D();
1764 totalLength += segmentized->length3D();
1774 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1775 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1776 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1781 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1783 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1784 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1785 QVector< QPair< QString, QString > > mapItems;
1787 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1789 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1793 std::sort( mapItems.begin(), mapItems.end(), [](
const QPair< QString, QString > &pair1,
const QPair< QString, QString > &pair2 ) { return ( pair1.first.length() > pair2.first.length() ); } );
1795 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1797 str = str.replace( it->first, it->second );
1800 return QVariant( str );
1802 else if ( values.count() == 3 )
1804 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1805 QVariantList before;
1807 bool isSingleReplacement =
false;
1809 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1811 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1815 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1818 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1820 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1821 isSingleReplacement =
true;
1825 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1828 if ( !isSingleReplacement && before.length() != after.length() )
1830 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1834 for (
int i = 0; i < before.length(); i++ )
1836 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1839 return QVariant( str );
1843 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1850 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1851 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1852 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1854 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1855 if ( !re.isValid() )
1857 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1860 return QVariant( str.replace( re, after ) );
1865 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1866 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1868 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1869 if ( !re.isValid() )
1871 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1874 return QVariant( ( str.indexOf( re ) + 1 ) );
1879 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1880 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1881 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1883 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1884 if ( !re.isValid() )
1886 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1890 QRegularExpressionMatch matches = re.match( str );
1891 if ( matches.hasMatch() )
1894 QStringList list = matches.capturedTexts();
1897 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1899 array += ( !( *it ).isEmpty() ) ? *it : empty;
1902 return QVariant( array );
1912 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1913 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1915 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1916 if ( !re.isValid() )
1918 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1923 QRegularExpressionMatch match = re.match( str );
1924 if ( match.hasMatch() )
1927 if ( match.lastCapturedIndex() > 0 )
1930 return QVariant( match.captured( 1 ) );
1935 return QVariant( match.captured( 0 ) );
1940 return QVariant(
"" );
1946 const int version = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1951 uuid = QUuid::createUuid();
1954#if QT_VERSION >= QT_VERSION_CHECK( 6, 9, 0 )
1955 uuid = QUuid::createUuidV7();
1957 parent->
setEvalErrorString( QObject::tr(
"UUid version 7 is not supported on this QGIS build" ) );
1962 parent->
setEvalErrorString( QObject::tr(
"UUid version %1 is not supported" ).arg( version ) );
1966 const QString format = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1967 if ( format.compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1968 return uuid.toString( QUuid::StringFormat::WithoutBraces );
1969 else if ( format.compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1970 return uuid.toString( QUuid::StringFormat::Id128 );
1971 return uuid.toString();
1976 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1979 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1980 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1983 if ( values.at( 2 ).isValid() )
1984 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1990 from = str.size() + from;
1996 else if ( from > 0 )
2004 len = str.size() + len - from;
2011 return QVariant( str.mid( from, len ) );
2016 return QVariant( f.
id() );
2021 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2022 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
2023 bool foundLayer =
false;
2024 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2029 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
2030 if ( !layer || !layer->dataProvider() )
2032 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2036 if ( bandNb < 1 || bandNb > layer->bandCount() )
2038 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
2044 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
2051 QgsMultiPointXY multiPoint = geom.asMultiPoint();
2052 if ( multiPoint.count() == 1 )
2054 point = multiPoint[0];
2063 double value = layer->dataProvider()->sample( point, bandNb );
2064 return std::isnan( value ) ? QVariant() : value;
2071 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2082 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2083 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2085 bool foundLayer =
false;
2086 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2090 [parent, bandNb, value](
QgsMapLayer *mapLayer ) -> QVariant {
2091 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
2092 if ( !layer || !layer->dataProvider() )
2094 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2098 if ( bandNb < 1 || bandNb > layer->bandCount() )
2100 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
2104 if ( std::isnan( value ) )
2106 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
2110 if ( !layer->dataProvider()->attributeTable( bandNb ) )
2115 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
2116 if ( data.isEmpty() )
2122 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
2123 for (
int idx = 0; idx < static_cast<int>( fields.count() ) && idx < static_cast<int>( data.count() ); ++idx )
2130 result.insert( fields.at( idx ).name, data.at( idx ) );
2140 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2161 if ( values.size() == 1 )
2163 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2166 else if ( values.size() == 2 )
2168 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2169 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2173 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2182 QString table { R
"html(
2185 <tr><th>%1</th></tr>
2188 <tr><td>%2</td></tr>
2192 if ( values.size() == 1 )
2194 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2198 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2202 if ( dict.isEmpty() )
2207 QStringList headers;
2210 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2212 headers.push_back( it.key().toHtmlEscaped() );
2213 cells.push_back( it.value().toString().toHtmlEscaped() );
2216 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2221 QString table { R
"html(
2226 if ( values.size() == 1 )
2228 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2232 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2236 if ( dict.isEmpty() )
2243 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2245 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2248 return table.arg( rows );
2256 layer = context->
variable( u
"layer"_s );
2261 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2263 layer = node->
eval( parent, context );
2274 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2278 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2279 if ( strength ==
"hard"_L1 )
2283 else if ( strength ==
"soft"_L1 )
2288 bool foundLayer =
false;
2289 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2293 [parent, feature, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2294 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2297 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2303 for (
int i = 0; i < fields.
size(); i++ )
2320 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2332 layer = context->
variable( u
"layer"_s );
2337 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2339 layer = node->
eval( parent, context );
2350 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2354 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2355 if ( strength ==
"hard"_L1 )
2359 else if ( strength ==
"soft"_L1 )
2364 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2366 bool foundLayer =
false;
2367 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2371 [parent, feature, attributeName, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2372 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2379 if ( fieldIndex == -1 )
2381 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2394 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2410 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2415 for (
int i = 0; i < fields.
count(); ++i )
2429 if ( values.isEmpty() )
2432 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2434 else if ( values.size() == 1 )
2436 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2437 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2439 else if ( values.size() == 2 )
2441 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2442 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2446 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2453 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2459 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2465 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2467 const QString fieldName { fields.
at( fieldIndex ).
name() };
2468 const QVariant attributeVal = feature.
attribute( fieldIndex );
2469 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2472 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2481 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2493 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2495 result.insert( fields.
at( fieldIndex ).
name(), value );
2510 bool evaluate =
true;
2514 if ( values.isEmpty() )
2517 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2519 else if ( values.size() == 1 )
2521 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2522 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2524 else if ( values.size() == 2 )
2526 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2527 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2529 else if ( values.size() == 3 )
2531 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2532 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2533 evaluate = values.value( 2 ).toBool();
2539 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2543 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2575 subContext.setFeature( feature );
2584 exp.prepare( &subContext );
2585 return exp.evaluate( &subContext ).toString();
2591 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2596 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2603 if ( values.isEmpty() )
2606 layer = context->
variable( u
"layer"_s );
2608 else if ( values.size() == 1 )
2610 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2611 layer = context->
variable( u
"layer"_s );
2613 else if ( values.size() == 2 )
2615 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2616 layer = values.at( 0 );
2620 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2624 bool foundLayer =
false;
2625 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2630 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2631 if ( !layer || !feature.
isValid() )
2650 if ( values.isEmpty() )
2651 layer = context->
variable( u
"layer"_s );
2652 else if ( values.count() == 1 )
2653 layer = values.at( 0 );
2656 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2660 bool foundLayer =
false;
2661 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2666 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2684 static QMap<QString, qlonglong> counterCache;
2685 QVariant functionResult;
2687 auto fetchAndIncrementFunc = [values, parent, &functionResult](
QgsMapLayer *mapLayer,
const QString &databaseArgument ) {
2690 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2695 database = decodedUri.value( u
"path"_s ).toString();
2696 if ( database.isEmpty() )
2698 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2703 database = databaseArgument;
2706 const QString table = values.at( 1 ).toString();
2707 const QString idColumn = values.at( 2 ).toString();
2708 const QString filterAttribute = values.at( 3 ).toString();
2709 const QVariant filterValue = values.at( 4 ).toString();
2710 const QVariantMap defaultValues = values.at( 5 ).toMap();
2716 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2719 functionResult = QVariant();
2723 QString errorMessage;
2724 QString currentValSql;
2726 qlonglong nextId = 0;
2727 bool cachedMode =
false;
2728 bool valueRetrieved =
false;
2730 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2737 auto cachedCounter = counterCache.find( cacheString );
2739 if ( cachedCounter != counterCache.end() )
2741 qlonglong &cachedValue = cachedCounter.value();
2742 nextId = cachedValue;
2744 cachedValue = nextId;
2745 valueRetrieved =
true;
2750 if ( !cachedMode || !valueRetrieved )
2752 int result = SQLITE_ERROR;
2755 if ( !filterAttribute.isNull() )
2760 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2762 if ( result == SQLITE_OK )
2765 if ( sqliteStatement.
step() == SQLITE_ROW )
2771 if ( cachedMode && result == SQLITE_OK )
2773 counterCache.insert( cacheString, nextId );
2775 QObject::connect( layer->
dataProvider()->
transaction(), &QgsTransaction::destroyed, [cacheString]() { counterCache.remove( cacheString ); } );
2777 valueRetrieved =
true;
2781 if ( valueRetrieved )
2790 if ( !filterAttribute.isNull() )
2796 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2799 vals << iter.value().toString();
2802 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2803 upsertSql +=
" VALUES "_L1;
2804 upsertSql +=
'(' + vals.join(
',' ) +
')';
2806 int result = SQLITE_ERROR;
2810 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2817 result = sqliteDb.
exec( upsertSql, errorMessage );
2819 if ( result == SQLITE_OK )
2821 functionResult = QVariant( nextId );
2826 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2827 functionResult = QVariant();
2832 functionResult = QVariant();
2835 bool foundLayer =
false;
2836 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer *layer ) { fetchAndIncrementFunc( layer, QString() ); }, foundLayer );
2839 const QString databasePath = values.at( 0 ).toString();
2843 return functionResult;
2856 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2861 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2864 return QVariant::fromValue( crs );
2869 QString concat(
"" );
2870 for (
const QVariant &value : values )
2873 concat += QgsExpressionUtils::getStringValue( value, parent );
2880 if ( values.length() < 2 )
2882 parent->
setEvalErrorString( QObject::tr(
"Function concat_ws requires at least 2 arguments" ) );
2886 const QString separator = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2888 QStringList stringValues;
2889 stringValues.reserve( values.size() - 1 );
2890 for (
int i = 1; i < values.size(); ++i )
2892 const QVariant value = values.at( i );
2895 stringValues.append( QgsExpressionUtils::getStringValue( value, parent ) );
2899 return stringValues.join( separator );
2904 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2905 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2913 if ( values.isEmpty() || values[0].isNull() )
2921 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2922 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2923 return string.right( pos );
2928 if ( values.length() < 2 || values.length() > 3 )
2931 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2932 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2934 bool overlapping =
false;
2935 if ( values.length() == 3 )
2937 overlapping = values.at( 2 ).toBool();
2940 if ( substring.isEmpty() )
2941 return QVariant( 0 );
2946 count = input.count( substring );
2951 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2954 pos += substring.length();
2958 return QVariant( count );
2963 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2964 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2965 return string.left( pos );
2970 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2971 const int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2972 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2973 if ( fill.isEmpty() )
2977 return string.leftJustified( length, fill.at( 0 ),
true );
2982 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2983 const int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2984 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2985 if ( fill.isEmpty() )
2989 return string.rightJustified( length, fill.at( 0 ),
true );
2994 if ( values.size() < 1 )
2996 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
3000 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3001 for (
int n = 1; n < values.length(); n++ )
3003 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
3011 return QVariant( QDateTime::currentDateTime() );
3016 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3017 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3018 if ( format.isEmpty() && !language.isEmpty() )
3020 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
3021 return QVariant( QDate() );
3024 if ( format.isEmpty() && language.isEmpty() )
3025 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
3027 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3028 QLocale locale = QLocale();
3029 if ( !language.isEmpty() )
3031 locale = QLocale( language );
3034 QDate date = locale.toDate( datestring, format );
3035 if ( !date.isValid() )
3037 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
3040 return QVariant( date );
3045 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3046 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3047 if ( format.isEmpty() && !language.isEmpty() )
3049 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
3050 return QVariant( QTime() );
3053 if ( format.isEmpty() && language.isEmpty() )
3054 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
3056 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3057 QLocale locale = QLocale();
3058 if ( !language.isEmpty() )
3060 locale = QLocale( language );
3063 QTime time = locale.toTime( timestring, format );
3064 if ( !time.isValid() )
3066 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
3069 return QVariant( time );
3074 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
3083 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3084 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3085 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3087 QString formatString;
3088 if ( values.count() > 3 )
3089 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
3092 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
3096 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
3100 else if ( !formatString.isEmpty() )
3102 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
3106 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
3110 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
3116 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
3124 return floatToDegreeFormat( format, values, context, parent, node );
3131 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
3133 return ok ? QVariant( value ) : QVariant();
3139 return floatToDegreeFormat( format, values, context, parent, node );
3144 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3145 return static_cast< int >( decimalDegrees );
3150 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3151 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3152 return static_cast< int >( remainder * 60 );
3157 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3158 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3159 const double remainderInMinutes = remainder * 60;
3160 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
3162 return remainderSecondsFraction * 60;
3167 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3168 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3169 qint64 seconds = d2.secsTo( d1 );
3170 return QVariant::fromValue(
QgsInterval( seconds ) );
3175 if ( !values.at( 0 ).canConvert<QDate>() )
3178 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
3179 if ( !date.isValid() )
3184 return date.dayOfWeek() % 7;
3189 QVariant value = values.at( 0 );
3190 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3193 return QVariant( inter.
days() );
3197 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3198 return QVariant( d1.date().day() );
3204 QVariant value = values.at( 0 );
3205 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3208 return QVariant( inter.
years() );
3212 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3213 return QVariant( d1.date().year() );
3219 QVariant value = values.at( 0 );
3220 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3223 return QVariant( inter.
months() );
3227 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3228 return QVariant( d1.date().month() );
3234 QVariant value = values.at( 0 );
3235 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3238 return QVariant( inter.
weeks() );
3242 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3243 return QVariant( d1.date().weekNumber() );
3249 QVariant value = values.at( 0 );
3250 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3253 return QVariant( inter.
hours() );
3257 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3258 return QVariant( t1.hour() );
3264 QVariant value = values.at( 0 );
3265 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3268 return QVariant( inter.
minutes() );
3272 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3273 return QVariant( t1.minute() );
3279 QVariant value = values.at( 0 );
3280 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3283 return QVariant( inter.
seconds() );
3287 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3288 return QVariant( t1.second() );
3294 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3297 return QVariant( dt.toMSecsSinceEpoch() );
3307 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3309 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3314 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3317 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3320 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3326 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3329 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3338 if ( !dateTime.isValid() )
3343 const int year = dateTime.date().year();
3344 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3345 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3346 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3347 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3348 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3353 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3354 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3357 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3360 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3365 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3370 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3375 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3380 double declination = 0;
3387 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3399 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3400 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3403 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3406 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3411 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3416 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3421 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3426 double inclination = 0;
3433 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3445 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3446 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3449 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3452 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3457 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3462 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3467 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3472 double declination = 0;
3480 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3490 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3496 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3502 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3507 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3514 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3515 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3518 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3521 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3526 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3531 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3536 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3541 double declination = 0;
3549 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3559 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3565 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3571 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3576 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3581#define ENSURE_GEOM_TYPE( f, g, geomtype ) \
3582 if ( !( f ).hasGeometry() ) \
3583 return QVariant(); \
3584 QgsGeometry g = ( f ).geometry(); \
3585 if ( ( g ).type() != ( geomtype ) ) \
3592 if ( g.isMultipart() )
3594 return g.asMultiPoint().at( 0 ).x();
3598 return g.asPoint().x();
3606 if ( g.isMultipart() )
3608 return g.asMultiPoint().at( 0 ).y();
3612 return g.asPoint().y();
3626 if ( g.isEmpty() || !abGeom->
is3D() )
3639 if ( collection->numGeometries() > 0 )
3652 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3658 return QVariant( isValid );
3663 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3667 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3668#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
3673 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3675 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3678 const bool keepCollapsed = values.value( 2 ).toBool();
3683 valid = geom.
makeValid( method, keepCollapsed );
3687 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3691 return QVariant::fromValue( valid );
3696 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3702 for (
int i = 0; i < multiGeom.size(); ++i )
3704 array += QVariant::fromValue( multiGeom.at( i ) );
3712 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3724 QVariant result( centroid.
asPoint().
x() );
3730 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3742 QVariant result( centroid.
asPoint().
y() );
3748 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3766 if ( collection->numGeometries() == 1 )
3779 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3797 if ( collection->numGeometries() == 1 )
3810 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3815 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3842 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3859 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3876 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3881 bool ignoreClosing =
false;
3882 if ( values.length() > 1 )
3884 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3894 bool skipLast =
false;
3895 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3900 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++i )
3912 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3923 for (
int i = 0; i < line->numPoints() - 1; ++i )
3937 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3947 if ( collection->numGeometries() == 1 )
3954 if ( !curvePolygon )
3958 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3964 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3970 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3980 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3986 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3992 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4001 return QVariant::fromValue(
QgsGeometry( boundary ) );
4006 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4015 return QVariant::fromValue( merged );
4020 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4024 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4029 if ( sharedPaths.
isNull() )
4032 return QVariant::fromValue( sharedPaths );
4038 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4043 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4046 if ( simplified.
isNull() )
4054 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4059 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4064 if ( simplified.
isNull() )
4072 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4077 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
4078 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
4079 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4080 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
4082 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
4091 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4096 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4097 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4098 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4109 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4114 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4115 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4116 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4117 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4118 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4129 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4134 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4135 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4136 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4147 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4152 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4153 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4154 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4155 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4156 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4167 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4172 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4173 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4174 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4185 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4190 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4191 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4192 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4193 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4194 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4205 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4210 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4211 QVector< double > dashPattern;
4212 dashPattern.reserve( pattern.size() );
4213 for (
const QVariant &value : std::as_const( pattern ) )
4216 double v = value.toDouble( &ok );
4228 if ( dashPattern.size() % 2 != 0 )
4230 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4234 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4236 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4238 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4240 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4242 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4244 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4248 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4252 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4254 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4256 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4258 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4260 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4262 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4266 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4270 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4272 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4274 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4276 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4280 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4284 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4295 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4300 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4302 if ( densified.
isNull() )
4310 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4315 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4317 if ( densified.
isNull() )
4326 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4328 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4335 QVector< QgsGeometry > parts;
4336 parts.reserve( list.size() );
4337 for (
const QVariant &value : std::as_const( list ) )
4339 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4350 if ( values.count() < 2 || values.count() > 4 )
4352 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4356 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4357 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4358 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4359 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4360 switch ( values.count() )
4374 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4375 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4376 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4382 if ( values.empty() )
4387 QVector<QgsPoint> points;
4388 points.reserve( values.count() );
4390 auto addPoint = [&points](
const QgsGeometry &geom ) {
4404 for (
const QVariant &value : values )
4406 if ( value.userType() == QMetaType::Type::QVariantList )
4408 const QVariantList list = value.toList();
4409 for (
const QVariant &v : list )
4411 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4416 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4420 if ( points.count() < 2 )
4428 if ( values.count() < 1 )
4430 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4434 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4442 auto polygon = std::make_unique< QgsPolygon >();
4456 if ( !exteriorRing )
4459 polygon->setExteriorRing( exteriorRing->
segmentize() );
4462 for (
int i = 1; i < values.count(); ++i )
4464 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4486 polygon->addInteriorRing( ring->
segmentize() );
4489 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4494 auto tr = std::make_unique<QgsTriangle>();
4495 auto lineString = std::make_unique<QgsLineString>();
4496 lineString->clear();
4498 for (
const QVariant &value : values )
4500 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4522 lineString->addVertex( *point );
4525 tr->setExteriorRing( lineString.release() );
4527 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4532 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4539 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4540 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4562 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4567 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4574 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4575 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4576 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4577 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4597 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4598 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4603 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4610 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4617 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4620 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4627 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4666 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4672 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4687 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4693 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4699 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4708 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4732 return QVariant::fromValue( geom.
vertexAt( idx ) );
4740 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4742 const QVariant v = pointAt( geom, idx, parent );
4745 return QVariant( v.value<
QgsPoint>().
x() );
4751 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4753 return fcnOldXat( values, f, parent, node );
4755 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4757 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4760 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4766 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4768 const QVariant v = pointAt( geom, vertexNumber, parent );
4770 return QVariant( v.value<
QgsPoint>().
x() );
4780 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4782 const QVariant v = pointAt( geom, idx, parent );
4785 return QVariant( v.value<
QgsPoint>().
y() );
4791 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4793 return fcnOldYat( values, f, parent, node );
4795 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4797 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4800 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4806 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4808 const QVariant v = pointAt( geom, vertexNumber, parent );
4810 return QVariant( v.value<
QgsPoint>().
y() );
4817 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4823 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4825 const QVariant v = pointAt( geom, vertexNumber, parent );
4827 return QVariant( v.value<
QgsPoint>().
z() );
4834 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4840 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4842 const QVariant v = pointAt( geom, vertexNumber, parent );
4844 return QVariant( v.value<
QgsPoint>().
m() );
4852 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4854 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4860 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4866 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4871 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4878 ogcContext.
layer = mapLayerPtr.data();
4883 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4898 return QVariant( area );
4902 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4914 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4919 return QVariant( geom.
area() );
4933 return QVariant( len );
4937 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4958 return QVariant( len );
4962 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4968 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4974 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4980 return QVariant( geom.
length() );
4985 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4991 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5000 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5009 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5025 if ( !curvePolygon )
5037 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5044 return QVariant( curvePolygon->
ringCount() );
5046 bool foundPoly =
false;
5055 if ( !curvePolygon )
5066 return QVariant( ringCount );
5071 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5073 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
5079 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5085 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5091 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5100 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5106 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5112 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5118 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5124 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5132 double max = std::numeric_limits< double >::lowest();
5136 double z = ( *it ).z();
5142 if ( max == std::numeric_limits< double >::lowest() )
5145 return QVariant( max );
5150 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5158 double min = std::numeric_limits< double >::max();
5162 double z = ( *it ).z();
5168 if ( min == std::numeric_limits< double >::max() )
5171 return QVariant( min );
5176 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5184 double min = std::numeric_limits< double >::max();
5188 double m = ( *it ).m();
5194 if ( min == std::numeric_limits< double >::max() )
5197 return QVariant( min );
5202 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5210 double max = std::numeric_limits< double >::lowest();
5214 double m = ( *it ).m();
5220 if ( max == std::numeric_limits< double >::lowest() )
5223 return QVariant( max );
5228 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5232 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5241 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5245 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5254 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5259 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5269 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5273 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5275 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5280 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5299 return QVariant::fromValue( curve->
isClosed() );
5304 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5317 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5318 closedLine->close();
5320 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5334 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5335 closedLine->close();
5337 closed->addGeometry( closedLine.release() );
5340 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5348 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5352 return QVariant::fromValue( fGeom.
isEmpty() );
5358 return QVariant::fromValue(
true );
5360 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5361 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5366 if ( values.length() < 2 || values.length() > 3 )
5369 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5370 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5377 if ( values.length() == 2 )
5380 QString result = engine->relate( sGeom.
constGet() );
5381 return QVariant::fromValue( result );
5386 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5387 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5388 return QVariant::fromValue( result );
5394 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5395 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5400 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5401 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5402 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5406 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5407 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5408 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5412 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5413 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5414 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5418 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5419 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5420 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5424 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5425 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5426 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5430 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5431 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5432 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5436 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5437 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5438 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5443 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5444 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5450 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5451 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5452 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5457 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5459 QVariant ret = TVL_False;
5462 ret = fGeom.
isExactlyEqual( sGeom, backend ) ? TVL_True : TVL_False;
5473 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5474 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5475 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5480 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5482 QVariant ret = TVL_False;
5496 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5497 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5498 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5503 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5505 double epsilon = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5507 QVariant ret = TVL_False;
5510 ret = fGeom.
isFuzzyEqual( sGeom, epsilon, backend ) ? TVL_True : TVL_False;
5521 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5522 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5523 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5524 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5525 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5526 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5529 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5531 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5535 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5537 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5541 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5547 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5549 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5554 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5556 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5561 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5563 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5568 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5583 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5587 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5588 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5589 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5590 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5593 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5599 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5602 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5606 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5607 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5608 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5611 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5617 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5620 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5624 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5627 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5633 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5634 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5635 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5636 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5637 if ( joinInt < 1 || joinInt > 3 )
5641 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5644 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5650 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5651 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5652 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5654 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5655 if ( joinInt < 1 || joinInt > 3 )
5659 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5662 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5668 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5669 const double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5670 const double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5672 const double deflectionStart = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5673 const double deflectionEnd = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5676 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5682 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5683 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5684 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5686 return QVariant::fromValue( fGeom );
5691 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5692 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5694 const bool perPart = values.value( 3 ).toBool();
5701 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5702 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5704 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5705 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5706 t.rotate( -rotation );
5707 t.translate( -partCenter.x(), -partCenter.y() );
5708 ( *it )->transform( t );
5710 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5722 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5730 fGeom.
rotate( rotation, pt );
5731 return QVariant::fromValue( fGeom );
5737 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5738 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5739 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5740 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent ) :
QgsGeometry();
5746 pt = fGeom.boundingBox().center();
5750 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5755 pt = center.asPoint();
5758 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5759 t.scale( xScale, yScale );
5760 t.translate( -pt.
x(), -pt.
y() );
5762 return QVariant::fromValue( fGeom );
5767 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5773 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5774 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5776 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5778 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5779 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5781 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5782 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5783 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5784 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5795 QTransform transform;
5796 transform.translate( deltaX, deltaY );
5797 transform.rotate( rotationZ );
5798 transform.scale( scaleX, scaleY );
5799 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5801 return QVariant::fromValue( fGeom );
5807 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5809 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5814 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5816 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5822 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5823 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5825 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5831 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5833 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5837#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
5842 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5843 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5844 const bool allowHoles = values.value( 2 ).toBool();
5846 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5859 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5861 if ( values.length() == 2 )
5862 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5870 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5876 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5878 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5884 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5890 double area,
angle, width, height;
5903 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5904 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5906 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5917 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5928 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5938 reversed->addGeometry( curve->
reversed() );
5945 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5951 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5952 std::reverse(
string.begin(),
string.end() );
5958 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5978 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5984 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5985 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5986 return QVariant( fGeom.
distance( sGeom ) );
5991 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5992 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5995 if ( values.length() == 3 && values.at( 2 ).isValid() )
5997 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5998 densify = std::clamp( densify, 0.0, 1.0 );
6006 return res > -1 ? QVariant( res ) : QVariant();
6011 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6012 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6014 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6019 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6020 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6022 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6027 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6028 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6030 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6036 if ( values.length() < 1 || values.length() > 2 )
6039 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6041 if ( values.length() == 2 )
6042 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6043 QString wkt = fGeom.
asWkt( prec );
6044 return QVariant( wkt );
6049 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6050 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
6055 if ( values.length() != 2 )
6057 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
6061 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6062 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6090 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
6097 if ( pt1->
y() < pt2->
y() )
6099 else if ( pt1->
y() > pt2->
y() )
6107 if ( pt1->
x() < pt2->
x() )
6109 else if ( pt1->
x() > pt2->
x() )
6110 return M_PI + ( M_PI_2 );
6115 if ( pt1->
x() < pt2->
x() )
6117 if ( pt1->
y() < pt2->
y() )
6119 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
6123 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI_2 );
6129 if ( pt1->
y() > pt2->
y() )
6131 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) ) + M_PI;
6135 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI + ( M_PI_2 ) );
6142 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6143 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6145 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
6149 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
6157 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
6171 if ( ellipsoid.isEmpty() )
6173 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
6179 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
6187 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
6193 const double bearing = da.
bearing( point1, point2 );
6194 if ( std::isfinite( bearing ) )
6196 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
6209 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6217 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6218 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6219 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
6222 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6229 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6230 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6257 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6266 if ( values.length() != 3 )
6269 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6270 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6271 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6275 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6281 if ( values.length() < 2 )
6284 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6287 return values.at( 0 );
6289 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6290 QVariant cachedExpression;
6295 if ( cachedExpression.isValid() )
6302 bool asc = values.value( 2 ).toBool();
6320 Q_ASSERT( collection );
6324 QgsExpressionSorter sorter( orderBy );
6326 QList<QgsFeature> partFeatures;
6327 partFeatures.reserve( collection->
partCount() );
6328 for (
int i = 0; i < collection->
partCount(); ++i )
6334 sorter.sortFeatures( partFeatures, unconstedContext );
6338 Q_ASSERT( orderedGeom );
6343 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6348 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6351 delete unconstedContext;
6358 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6359 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6363 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6369 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6370 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6374 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6380 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6381 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6385 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6391 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6392 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6393 const bool use3DDistance = values.at( 2 ).toBool();
6395 double x, y, z, distance;
6418 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6421 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6441 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6442 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6444 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6446 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6451 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6452 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6459 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6460 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6465 vertex = count + vertex;
6473 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6474 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6479 vertex = count + vertex;
6487 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6488 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6492 return distance >= 0 ? distance : QVariant();
6497 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6498 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6499 const bool use3DDistance = values.at( 2 ).toBool();
6501 double x, y, z, distance;
6510 return found ? distance : QVariant();
6515 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6517 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6518 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6521 if ( values.length() >= 1 )
6523 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6524 return QVariant( qlonglong( std::round( number ) ) );
6539 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6540 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6541 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6548 const bool omitGroupSeparator = values.value( 3 ).toBool();
6549 const bool trimTrailingZeros = values.value( 4 ).toBool();
6551 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6552 if ( !omitGroupSeparator )
6553 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6555 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6557 QString res = locale.toString( value,
'f', places );
6559 if ( trimTrailingZeros )
6561 const QChar decimal = locale.decimalPoint().at( 0 );
6562 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6564 if ( res.contains( decimal ) )
6566 int trimPoint = res.length() - 1;
6568 while ( res.at( trimPoint ) == zeroDigit )
6571 if ( res.at( trimPoint ) == decimal )
6574 res.truncate( trimPoint + 1 );
6583 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6584 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6585 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6588 if ( format.indexOf(
"Z" ) > 0 )
6589 datetime = datetime.toUTC();
6591 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6592 return locale.toString( datetime, format );
6597 const QVariant variant = values.at( 0 );
6599 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6600 if ( !color.isValid() )
6603 const float alpha = color.alphaF();
6604 if ( color.spec() == QColor::Spec::Cmyk )
6606 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() )
6608 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6612 const float avg = ( color.redF() + color.greenF() + color.blueF() )
6614 color.setRgbF( avg, avg, avg, alpha );
6617 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6624 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6629 else if ( ratio < 0 )
6634 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6635 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6636 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6637 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6639 QColor newColor( red, green, blue, alpha );
6646 const QVariant variant1 = values.at( 0 );
6647 const QVariant variant2 = values.at( 1 );
6649 if ( variant1.userType() != variant2.userType() )
6651 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6656 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6657 if ( !color1.isValid() )
6660 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6661 if ( !color2.isValid() )
6664 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6666 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6670 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6676 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6677 if ( color1.spec() == QColor::Spec::Cmyk )
6679 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6680 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6681 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6682 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6683 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6687 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6688 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6689 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6690 newColor = QColor::fromRgbF( red, green, blue, alpha );
6695 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6700 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6701 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6702 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6703 QColor color = QColor( red, green, blue );
6704 if ( !color.isValid() )
6706 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6707 color = QColor( 0, 0, 0 );
6710 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6715 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6716 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6717 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6718 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6719 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6720 if ( !color.isValid() )
6722 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6731 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6732 QVariant value = node->
eval( parent, context );
6736 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6738 value = node->
eval( parent, context );
6746 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6748 QVariant value = node->
eval( parent, context );
6750 if ( value.toBool() )
6752 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6754 value = node->
eval( parent, context );
6759 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6761 value = node->
eval( parent, context );
6769 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6770 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6771 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6772 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6773 QColor color = QColor( red, green, blue, alpha );
6774 if ( !color.isValid() )
6776 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6777 color = QColor( 0, 0, 0 );
6786 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6788 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6793 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6797 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6802 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6803 QColor color = ramp->
color( value );
6816 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6818 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6820 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6822 QColor color = QColor::fromHslF( hue, saturation, lightness );
6824 if ( !color.isValid() )
6826 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6827 color = QColor( 0, 0, 0 );
6830 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6836 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6838 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6840 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6842 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6844 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6845 if ( !color.isValid() )
6847 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6848 color = QColor( 0, 0, 0 );
6855 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6856 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6857 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6858 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6860 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6861 if ( !color.isValid() )
6863 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6873 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6875 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6877 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6879 QColor color = QColor::fromHsvF( hue, saturation, value );
6881 if ( !color.isValid() )
6883 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6884 color = QColor( 0, 0, 0 );
6887 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6893 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6895 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6897 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6899 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6901 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6902 if ( !color.isValid() )
6904 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6905 color = QColor( 0, 0, 0 );
6912 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6913 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6914 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6915 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6916 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6918 if ( !color.isValid() )
6920 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6929 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6930 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6931 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6932 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6933 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6935 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6936 if ( !color.isValid() )
6938 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6948 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6950 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6952 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6954 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6956 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6958 if ( !color.isValid() )
6960 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6961 color = QColor( 0, 0, 0 );
6964 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6970 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6972 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6974 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6976 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6978 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6980 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6981 if ( !color.isValid() )
6983 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6984 color = QColor( 0, 0, 0 );
6991 const QVariant variant = values.at( 0 );
6993 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6994 if ( !color.isValid() )
6997 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6998 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7000 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7001 return color.green();
7002 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7003 return color.blue();
7004 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7005 return color.alpha();
7006 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7007 return static_cast< double >( color.hsvHueF() * 360 );
7008 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7009 return static_cast< double >( color.hsvSaturationF() * 100 );
7010 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7011 return static_cast< double >( color.valueF() * 100 );
7012 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7013 return static_cast< double >( color.hslHueF() * 360 );
7014 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7015 return static_cast< double >( color.hslSaturationF() * 100 );
7016 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7017 return static_cast< double >( color.lightnessF() * 100 );
7018 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7019 return static_cast< double >( color.cyanF() * 100 );
7020 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7021 return static_cast< double >( color.magentaF() * 100 );
7022 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7023 return static_cast< double >( color.yellowF() * 100 );
7024 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7025 return static_cast< double >( color.blackF() * 100 );
7027 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7033 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7036 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
7040 QList< QColor > colors;
7042 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7045 if ( !colors.last().isValid() )
7047 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
7051 double step = it.key().toDouble();
7052 if ( it == map.constBegin() )
7057 else if ( it == map.constEnd() )
7067 bool discrete = values.at( 1 ).toBool();
7069 if ( colors.empty() )
7072 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
7077 const QVariant variant = values.at( 0 );
7079 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7080 if ( !color.isValid() )
7083 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7084 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7085 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7086 color.setRed( std::clamp( value, 0, 255 ) );
7087 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7088 color.setGreen( std::clamp( value, 0, 255 ) );
7089 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7090 color.setBlue( std::clamp( value, 0, 255 ) );
7091 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7092 color.setAlpha( std::clamp( value, 0, 255 ) );
7093 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7094 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
7095 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7096 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
7097 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7098 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7099 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7100 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
7101 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7102 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
7103 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7104 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7105 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7106 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
7107 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7108 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
7109 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7110 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
7111 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7112 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7115 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7118 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7123 const QVariant variant = values.at( 0 );
7125 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7126 if ( !color.isValid() )
7129 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7131 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7136 const QVariant variant = values.at( 0 );
7138 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7139 if ( !color.isValid() )
7142 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7144 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7149 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7152 return QVariant::fromValue( geom );
7158 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7166 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
7171 return QVariant::fromValue( fGeom );
7174 return QVariant::fromValue( fGeom );
7183 return QVariant::fromValue( fGeom );
7196 bool foundLayer =
false;
7197 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7200 if ( !featureSource || !foundLayer )
7205 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
7218 result = QVariant::fromValue( fet );
7226 bool foundLayer =
false;
7227 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7230 if ( !featureSource || !foundLayer )
7235 QString cacheValueKey;
7236 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7238 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7240 QMap<QString, QVariant>::const_iterator i = attributeMap.constBegin();
7241 QString filterString;
7242 for ( ; i != attributeMap.constEnd(); ++i )
7244 if ( !filterString.isEmpty() )
7246 filterString.append(
" AND " );
7250 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7259 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7260 int attributeId = featureSource->fields().lookupField( attribute );
7261 if ( attributeId == -1 )
7266 const QVariant &attVal = values.at( 2 );
7268 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7291 res = QVariant::fromValue( fet );
7306 if ( !values.isEmpty() )
7309 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7310 fieldName = col->
name();
7311 else if ( values.size() == 2 )
7312 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7315 QVariant value = values.at( 0 );
7320 if ( fieldIndex == -1 )
7322 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7328 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7331 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7342 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7361 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7369 const QVariant data = values.at( 0 );
7370 const QMimeDatabase db;
7371 return db.mimeTypeForData( data.toByteArray() ).name();
7376 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7378 bool translate =
true;
7379 if ( values.length() >= 3 )
7381 translate = QgsExpressionUtils::getTVLValue( values.at( 2 ), parent ) == QgsExpressionUtils::TVL::True;
7384 bool foundLayer =
false;
7385 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7389 [layerProperty, translate](
QgsMapLayer *layer ) -> QVariant {
7394 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7395 return layer->name();
7396 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7398 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7399 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7400 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7401 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7402 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7404 QStringList keywords;
7405 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7406 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7408 keywords.append( it.value() );
7410 if ( !keywords.isEmpty() )
7412 return layer->serverProperties()->keywordList();
7414 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7416 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7418 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7420 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7422 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7424 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7426 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7428 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7430 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7432 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7434 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7436 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7438 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7441 QVariant result = QVariant::fromValue( extentGeom );
7444 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7446 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7449 return decodedUri.value( u
"path"_s );
7451 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7453 switch ( layer->
type() )
7456 return translate ? QCoreApplication::translate(
"expressions",
"Vector" ) : u
"Vector"_s;
7458 return translate ? QCoreApplication::translate(
"expressions",
"Raster" ) : u
"Raster"_s;
7460 return translate ? QCoreApplication::translate(
"expressions",
"Mesh" ) : u
"Mesh"_s;
7462 return translate ? QCoreApplication::translate(
"expressions",
"Vector Tile" ) : u
"Vector Tile"_s;
7464 return translate ? QCoreApplication::translate(
"expressions",
"Plugin" ) : u
"Plugin"_s;
7466 return translate ? QCoreApplication::translate(
"expressions",
"Annotation" ) : u
"Annotation"_s;
7468 return translate ? QCoreApplication::translate(
"expressions",
"Point Cloud" ) : u
"Point Cloud"_s;
7470 return translate ? QCoreApplication::translate(
"expressions",
"Group" ) : u
"Group"_s;
7472 return translate ? QCoreApplication::translate(
"expressions",
"Tiled Scene" ) : u
"Tiled Scene"_s;
7478 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7481 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7483 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7485 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7503 const QString uriPart = values.at( 1 ).toString();
7505 bool foundLayer =
false;
7507 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7511 [parent, uriPart](
QgsMapLayer *layer ) -> QVariant {
7512 if ( !layer->dataProvider() )
7514 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7520 if ( !uriPart.isNull() )
7522 return decodedUri.value( uriPart );
7534 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7545 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7546 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7548 bool foundLayer =
false;
7549 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7553 [parent, band, layerProperty](
QgsMapLayer *layer ) -> QVariant {
7554 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7558 if ( band < 1 || band > rl->bandCount() )
7560 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7566 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7568 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7570 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7572 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7574 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7576 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7580 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7610 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7627 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7628 bool ascending = values.value( 1 ).toBool();
7629 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7635 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7640 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7645 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7650 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7651 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7653 for (
const auto &item : listB )
7655 if ( listA.contains( item ) )
7659 return QVariant( match == listB.count() );
7664 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7669 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7670 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7671 if ( pos < list.length() && pos >= 0 )
7672 return list.at( pos );
7673 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7674 return list.at( list.length() + pos );
7680 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7681 return list.value( 0 );
7686 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7687 return list.value( list.size() - 1 );
7692 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7693 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7698 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7699 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7704 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7707 for (
const QVariant &item : list )
7709 switch ( item.userType() )
7711 case QMetaType::Int:
7712 case QMetaType::UInt:
7713 case QMetaType::LongLong:
7714 case QMetaType::ULongLong:
7715 case QMetaType::Float:
7716 case QMetaType::Double:
7717 total += item.toDouble();
7722 return i == 0 ? QVariant() : total / i;
7727 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7728 QVariantList numbers;
7729 for (
const auto &item : list )
7731 switch ( item.userType() )
7733 case QMetaType::Int:
7734 case QMetaType::UInt:
7735 case QMetaType::LongLong:
7736 case QMetaType::ULongLong:
7737 case QMetaType::Float:
7738 case QMetaType::Double:
7739 numbers.append( item );
7743 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7744 const int count = numbers.count();
7749 else if ( count % 2 )
7751 return numbers.at( count / 2 );
7755 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7761 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7764 for (
const QVariant &item : list )
7766 switch ( item.userType() )
7768 case QMetaType::Int:
7769 case QMetaType::UInt:
7770 case QMetaType::LongLong:
7771 case QMetaType::ULongLong:
7772 case QMetaType::Float:
7773 case QMetaType::Double:
7774 total += item.toDouble();
7779 return i == 0 ? QVariant() : total;
7782static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7784 QVariant result = value;
7785 ( void ) result.convert(
static_cast<int>( type ) );
7791 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7792 QHash< QVariant, int > hash;
7793 for (
const auto &item : list )
7797 const QList< int > occurrences = hash.values();
7798 if ( occurrences.empty() )
7799 return QVariantList();
7801 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7803 const QString option = values.at( 1 ).toString();
7804 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7806 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7808 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7810 if ( hash.isEmpty() )
7813 return QVariant( hash.key( maxValue ) );
7815 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7817 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7819 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7821 if ( maxValue * 2 <= list.size() )
7824 return QVariant( hash.key( maxValue ) );
7835 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7836 QHash< QVariant, int > hash;
7837 for (
const auto &item : list )
7841 const QList< int > occurrences = hash.values();
7842 if ( occurrences.empty() )
7843 return QVariantList();
7845 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7847 const QString option = values.at( 1 ).toString();
7848 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7850 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7852 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7854 if ( hash.isEmpty() )
7857 return QVariant( hash.key( minValue ) );
7859 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7861 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7863 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7865 if ( hash.isEmpty() )
7869 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7870 if ( maxValue * 2 > list.size() )
7871 hash.remove( hash.key( maxValue ) );
7873 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7884 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7885 list.append( values.at( 1 ) );
7886 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7891 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7892 list.prepend( values.at( 1 ) );
7893 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7898 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7899 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7900 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7905 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7906 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7908 position = position + list.length();
7909 if ( position >= 0 && position < list.length() )
7910 list.removeAt( position );
7911 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7919 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7921 const QVariant toRemove = values.at( 1 );
7924 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant &element ) { return QgsVariantUtils::isNull( element ); } ), list.end() );
7928 list.removeAll( toRemove );
7930 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7935 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7937 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7939 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7940 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7942 int index = list.indexOf( it.key() );
7943 while ( index >= 0 )
7945 list.replace( index, it.value() );
7946 index = list.indexOf( it.key() );
7950 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7952 else if ( values.count() == 3 )
7954 QVariantList before;
7956 bool isSingleReplacement =
false;
7958 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7960 before = QVariantList() << values.at( 1 );
7964 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7967 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7969 after = QVariantList() << values.at( 2 );
7970 isSingleReplacement =
true;
7974 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7977 if ( !isSingleReplacement && before.length() != after.length() )
7979 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7983 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7984 for (
int i = 0; i < before.length(); i++ )
7986 int index = list.indexOf( before.at( i ) );
7987 while ( index >= 0 )
7989 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7990 index = list.indexOf( before.at( i ) );
7994 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7998 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
8005 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8006 QVariantList list_new;
8008 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
8010 while ( list.removeOne( cur ) )
8012 list_new.append( cur );
8016 list_new.append( list );
8018 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8024 for (
const QVariant &cur : values )
8026 list += QgsExpressionUtils::getListValue( cur, parent );
8028 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8033 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8034 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
8035 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
8036 int slice_length = 0;
8038 if ( start_pos < 0 )
8040 start_pos = list.length() + start_pos;
8044 slice_length = end_pos - start_pos + 1;
8048 slice_length = list.length() + end_pos - start_pos + 1;
8051 if ( slice_length < 0 )
8055 list = list.mid( start_pos, slice_length );
8061 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8062 std::reverse( list.begin(), list.end() );
8068 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8069 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
8070 for (
const QVariant &cur : array2 )
8072 if ( array1.contains( cur ) )
8073 return QVariant(
true );
8075 return QVariant(
false );
8080 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8082 QVariantList distinct;
8084 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8086 if ( !distinct.contains( *it ) )
8088 distinct += ( *it );
8097 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8098 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8099 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8103 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8105 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
8106 if ( it != ( array.constEnd() - 1 ) )
8112 return QVariant( str );
8117 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8118 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8119 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8121 QStringList list = str.split( delimiter );
8124 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
8126 array += ( !( *it ).isEmpty() ) ? *it : empty;
8134 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8135 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
8136 if ( document.isNull() )
8139 return document.toVariant();
8145 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
8146 return QString( document.toJson( QJsonDocument::Compact ) );
8151 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8152 if ( str.isEmpty() )
8153 return QVariantMap();
8154 str = str.trimmed();
8161 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8168 for (
int i = 0; i + 1 < values.length(); i += 2 )
8170 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
8177 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8178 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8179 QVariantMap resultMap;
8181 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8183 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
8191 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
8196 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
8201 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8202 map.remove( values.at( 1 ).toString() );
8208 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8209 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
8216 for (
const QVariant &cur : values )
8218 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
8219 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
8220 result.insert( it.key(), it.value() );
8227 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
8232 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
8237 const QString envVarName = values.at( 0 ).toString();
8238 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
8241 return QProcessEnvironment::systemEnvironment().value( envVarName );
8246 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8249 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
8252 return QFileInfo( file ).completeBaseName();
8257 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8260 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8263 return QFileInfo( file ).completeSuffix();
8268 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8271 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8274 return QFileInfo::exists( file );
8279 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8282 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8285 return QFileInfo( file ).fileName();
8290 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8293 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8296 return QFileInfo( file ).isFile();
8301 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8304 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8307 return QFileInfo( file ).isDir();
8312 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8315 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8318 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8323 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8326 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8329 return QFileInfo( file ).size();
8332static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8334 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8340 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8341 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8343 if ( method ==
"md4"_L1 )
8345 hash = fcnHash( str, QCryptographicHash::Md4 );
8347 else if ( method ==
"md5"_L1 )
8349 hash = fcnHash( str, QCryptographicHash::Md5 );
8351 else if ( method ==
"sha1"_L1 )
8353 hash = fcnHash( str, QCryptographicHash::Sha1 );
8355 else if ( method ==
"sha224"_L1 )
8357 hash = fcnHash( str, QCryptographicHash::Sha224 );
8359 else if ( method ==
"sha256"_L1 )
8361 hash = fcnHash( str, QCryptographicHash::Sha256 );
8363 else if ( method ==
"sha384"_L1 )
8365 hash = fcnHash( str, QCryptographicHash::Sha384 );
8367 else if ( method ==
"sha512"_L1 )
8369 hash = fcnHash( str, QCryptographicHash::Sha512 );
8371 else if ( method ==
"sha3_224"_L1 )
8373 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8375 else if ( method ==
"sha3_256"_L1 )
8377 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8379 else if ( method ==
"sha3_384"_L1 )
8381 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8383 else if ( method ==
"sha3_512"_L1 )
8385 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8387 else if ( method ==
"keccak_224"_L1 )
8389 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8391 else if ( method ==
"keccak_256"_L1 )
8393 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8395 else if ( method ==
"keccak_384"_L1 )
8397 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8399 else if ( method ==
"keccak_512"_L1 )
8401 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8405 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8412 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8417 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8422 const QByteArray input = values.at( 0 ).toByteArray();
8423 return QVariant( QString( input.toBase64() ) );
8428 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8430 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8432 query.addQueryItem( it.key(), it.value().toString() );
8434 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8439 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8440 const QByteArray base64 = value.toLocal8Bit();
8441 const QByteArray decoded = QByteArray::fromBase64( base64 );
8442 return QVariant( decoded );
8448static QVariant executeGeomOverlay(
8449 const QVariantList &values,
8453 bool invert =
false,
8454 double bboxGrow = 0,
8455 bool isNearestFunc =
false,
8456 bool isIntersectsFunc =
false
8461 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8465 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8468 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8477 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8480 const bool layerCanBeCached = node->
isStatic( parent, context );
8481 QVariant targetLayerValue = node->
eval( parent, context );
8485 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8487 QString subExpString = node->dump();
8489 bool testOnly = ( subExpString ==
"NULL" );
8492 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8496 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8501 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8503 QString filterString = node->dump();
8504 if ( filterString !=
"NULL" )
8506 request.setFilterExpression( filterString );
8510 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8512 QVariant limitValue = node->eval( parent, context );
8514 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8516 double max_distance = 0;
8517 bool cacheEnabled =
false;
8519 double minOverlap { -1 };
8520 double minInscribedCircleRadius { -1 };
8521 bool returnDetails =
false;
8522 bool sortByMeasure =
false;
8523 bool sortAscending =
false;
8524 bool requireMeasures =
false;
8525 bool overlapOrRadiusFilter =
false;
8529 if ( isNearestFunc )
8532 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8534 QVariant distanceValue = node->eval( parent, context );
8536 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8539 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8541 QVariant cacheValue = node->eval( parent, context );
8543 cacheEnabled = cacheValue.toBool();
8548 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8550 QVariant cacheValue = node->eval( parent, context );
8552 cacheEnabled = cacheValue.toBool();
8555 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8557 const QVariant minOverlapValue = node->eval( parent, context );
8559 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8562 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8564 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8566 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8569 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8571 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8574 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8576 const QString sorting { node->eval( parent, context ).toString().toLower() };
8577 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8578 sortAscending = sorting.startsWith(
"asc" );
8579 requireMeasures = sortByMeasure || returnDetails;
8580 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8583 node = QgsExpressionUtils::getNode( values.at( 9 ), parent );
8585 const QString backendStr = node->eval( parent, context ).toString().toUpper();
8591 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
8597 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8600 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8603 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8606 if ( bboxGrow != 0 )
8608 intDomain.
grow( bboxGrow );
8611 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8617 QList<QgsFeature> features;
8618 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8622 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8623 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8627 cachedTarget = targetLayer->
materialize( request );
8628 if ( layerCanBeCached )
8629 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8639 if ( layerCanBeCached )
8640 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8647 QList<QgsFeatureId> fidsList;
8648 if ( isNearestFunc )
8650 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8654 fidsList = spatialIndex.
intersects( intDomain );
8657 QListIterator<QgsFeatureId> i( fidsList );
8658 while ( i.hasNext() )
8661 if ( sameLayers && feat.
id() == fId2 )
8663 features.append( cachedTarget->
getFeature( fId2 ) );
8670 request.setFilterRect( intDomain );
8675 if ( sameLayers && feat.
id() == feat2.
id() )
8677 features.append( feat2 );
8685 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8686 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8692 subExpression.
prepare( &subContext );
8705 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double &overlapValue ) ->
bool {
8706 bool testResult {
false };
8708 QVector<double> overlapValues;
8709 const QgsGeometry merged { intersection.mergeLines() };
8714 if ( minOverlap != -1 || requireMeasures )
8716 overlapValue = geom->
length();
8717 overlapValues.append( overlapValue );
8718 if ( minOverlap != -1 )
8720 if ( overlapValue >= minOverlap )
8732 if ( !overlapValues.isEmpty() )
8734 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8741 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double &radiusValue,
double &overlapValue ) ->
bool {
8743 bool testResult {
false };
8745 QVector<double> overlapValues;
8746 QVector<double> radiusValues;
8747 for (
auto it = intersection.const_parts_begin(); ( !testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8751 if ( minOverlap != -1 || requireMeasures )
8753 overlapValue = geom->
area();
8754 overlapValues.append( geom->
area() );
8755 if ( minOverlap != -1 )
8757 if ( overlapValue >= minOverlap )
8769 if ( minInscribedCircleRadius != -1 || requireMeasures )
8772 const double width = bbox.
width();
8773 const double height = bbox.
height();
8774 const double size = width > height ? width : height;
8775 const double tolerance = size / 100.0;
8777 testResult = radiusValue >= minInscribedCircleRadius;
8778 radiusValues.append( radiusValues );
8783 if ( !radiusValues.isEmpty() )
8785 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8788 if ( !overlapValues.isEmpty() )
8790 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8799 QVariantList results;
8801 QListIterator<QgsFeature> i( features );
8804 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8809 if ( relationFunction( geometry, feat2.
geometry(), values, backend ) )
8811 double overlapValue = -1;
8812 double radiusValue = -1;
8814 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8826 for (
const auto &geom : std::as_const( geometries ) )
8828 switch ( geom.type() )
8832 poly.append( geom.asPolygon() );
8837 line.append( geom.asPolyline() );
8842 point.append( geom.asPoint() );
8853 switch ( geometry.
type() )
8881 switch ( intersection.
type() )
8886 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8888 if ( !testResult && overlapOrRadiusFilter )
8900 if ( minInscribedCircleRadius != -1 )
8906 const bool testResult { testLinestring( intersection, overlapValue ) };
8908 if ( !testResult && overlapOrRadiusFilter )
8920 if ( minInscribedCircleRadius != -1 )
8925 bool testResult {
false };
8926 if ( minOverlap != -1 || requireMeasures )
8946 testResult = testLinestring( feat2.
geometry(), overlapValue );
8951 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8957 if ( !testResult && overlapOrRadiusFilter )
8984 const QVariant expResult = subExpression.
evaluate( &subContext );
8986 if ( requireMeasures )
8988 QVariantMap resultRecord;
8989 resultRecord.insert( u
"id"_s, feat2.
id() );
8990 resultRecord.insert( u
"result"_s, expResult );
8992 resultRecord.insert( u
"overlap"_s, overlapValue );
8994 if ( radiusValue != -1 )
8996 resultRecord.insert( u
"radius"_s, radiusValue );
8998 results.append( resultRecord );
9002 results.append( expResult );
9008 results.append( feat2.
id() );
9028 if ( requireMeasures )
9030 if ( sortByMeasure )
9032 std::sort( results.begin(), results.end(), [sortAscending](
const QVariant &recordA,
const QVariant &recordB ) ->
bool {
9033 return sortAscending ? recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
9034 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
9038 if ( limit > 0 && results.size() > limit )
9040 results.erase( results.begin() + limit );
9043 if ( !returnDetails )
9045 QVariantList expResults;
9046 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
9048 expResults.append( it->toMap().value( u
"result"_s ) );
9058 QVariantList disjoint_results;
9067 if ( !results.contains( feat2.
id() ) )
9070 disjoint_results.append( subExpression.
evaluate( &subContext ) );
9073 return disjoint_results;
9081 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
false,
true );
9087 return executeGeomOverlay( values, context, parent, geomFunction );
9093 return executeGeomOverlay( values, context, parent, geomFunction );
9101 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9109 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9117 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9123 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 10 ), parent );
9125 QVariant epsilonValue = node->
eval( parent, context );
9127 double epsilon = QgsExpressionUtils::getDoubleValue( epsilonValue, parent );
9130 return geometry.
isFuzzyEqual( other, epsilon, backend );
9132 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9138 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9144 return executeGeomOverlay( values, context, parent, geomFunction );
9150 return executeGeomOverlay( values, context, parent, geomFunction,
true, 0,
false,
true );
9158 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
true );
9167 QMutexLocker locker( &sFunctionsMutex );
9169 QList<QgsExpressionFunction *> &functions = *sFunctions();
9171 if ( functions.isEmpty() )
9174 << QgsExpressionFunction::Parameter( u
"expression"_s )
9175 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
9176 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
9179 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true ) << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9182 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9188 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnAzimuth, u
"GeometryGroup"_s )
9189 <<
new QgsStaticExpressionFunction(
9192 << QgsExpressionFunction::Parameter( u
"point1"_s )
9193 << QgsExpressionFunction::Parameter( u
"point2"_s )
9194 << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() )
9195 << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ),
9199 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnInclination, u
"GeometryGroup"_s )
9200 <<
new QgsStaticExpressionFunction(
9203 << QgsExpressionFunction::Parameter( u
"point"_s )
9204 << QgsExpressionFunction::Parameter( u
"distance"_s )
9205 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9206 << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ),
9217 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
9221 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
9222 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
9224 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction(
9226 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9231 functions << randFunc;
9233 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction(
9236 << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 )
9237 << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 )
9238 << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9243 functions << randfFunc;
9246 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9247 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9248 <<
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 )
9249 <<
new QgsStaticExpressionFunction(
9252 << QgsExpressionFunction::Parameter( u
"value"_s )
9253 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9254 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9255 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9256 << QgsExpressionFunction::Parameter( u
"range_max"_s ),
9260 <<
new QgsStaticExpressionFunction(
9261 u
"scale_polynomial"_s,
9263 << QgsExpressionFunction::Parameter( u
"value"_s )
9264 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9265 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9266 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9267 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9268 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9275 QStringList() << u
"scale_exp"_s
9277 <<
new QgsStaticExpressionFunction(
9278 u
"scale_exponential"_s,
9280 << QgsExpressionFunction::Parameter( u
"value"_s )
9281 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9282 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9283 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9284 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9285 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9286 fcnExponentialScale,
9289 <<
new QgsStaticExpressionFunction(
9290 u
"scale_cubic_bezier"_s,
9292 << QgsExpressionFunction::Parameter( u
"value"_s )
9293 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9294 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9295 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9296 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9297 << QgsExpressionFunction::Parameter( u
"x1"_s )
9298 << QgsExpressionFunction::Parameter( u
"y1"_s )
9299 << QgsExpressionFunction::Parameter( u
"x2"_s )
9300 << QgsExpressionFunction::Parameter( u
"y2"_s ),
9301 fcnCubicBezierScale,
9306 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
9307 <<
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 )
9308 <<
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 )
9309 <<
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 )
9310 <<
new QgsStaticExpressionFunction(
9314 QStringList() << u
"Conversions"_s << u
"String"_s,
9319 QStringList() << u
"tostring"_s
9321 <<
new QgsStaticExpressionFunction(
9324 << QgsExpressionFunction::Parameter( u
"value"_s )
9325 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9326 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9328 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9333 QStringList() << u
"todatetime"_s
9335 <<
new QgsStaticExpressionFunction(
9338 << QgsExpressionFunction::Parameter( u
"value"_s )
9339 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9340 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9342 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9347 QStringList() << u
"todate"_s
9349 <<
new QgsStaticExpressionFunction(
9352 << QgsExpressionFunction::Parameter( u
"value"_s )
9353 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9354 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9356 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9361 QStringList() << u
"totime"_s
9363 <<
new QgsStaticExpressionFunction(
9367 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9372 QStringList() << u
"tointerval"_s
9374 <<
new QgsStaticExpressionFunction(
9377 << QgsExpressionFunction::Parameter( u
"value"_s )
9378 << QgsExpressionFunction::Parameter( u
"axis"_s )
9379 << QgsExpressionFunction::Parameter( u
"precision"_s )
9380 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9387 QStringList() << u
"todm"_s
9389 <<
new QgsStaticExpressionFunction(
9392 << QgsExpressionFunction::Parameter( u
"value"_s )
9393 << QgsExpressionFunction::Parameter( u
"axis"_s )
9394 << QgsExpressionFunction::Parameter( u
"precision"_s )
9395 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9396 fcnToDegreeMinuteSecond,
9402 QStringList() << u
"todms"_s
9404 <<
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 )
9405 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
9406 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
9407 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
9408 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9409 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
9410 <<
new QgsStaticExpressionFunction(
9413 << QgsExpressionFunction::Parameter( u
"condition"_s )
9414 << QgsExpressionFunction::Parameter( u
"result_when_true"_s )
9415 << QgsExpressionFunction::Parameter( u
"result_when_false"_s ),
9423 <<
new QgsStaticExpressionFunction(
9434 <<
new QgsStaticExpressionFunction(
9437 << QgsExpressionFunction::Parameter( u
"layer"_s )
9438 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9439 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9440 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9441 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9442 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9452 if ( !node->
args() )
9455 QSet<QString> referencedVars;
9458 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9464 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9467 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
9475 if ( !node->
args() )
9476 return QSet<QString>();
9478 QSet<QString> referencedCols;
9479 QSet<QString> referencedVars;
9483 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9489 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9494 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
9497 return referencedCols;
9502 <<
new QgsStaticExpressionFunction(
9503 u
"relation_aggregate"_s,
9505 << QgsExpressionFunction::Parameter( u
"relation"_s )
9506 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9507 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9508 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9509 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9510 fcnAggregateRelation,
9518 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9519 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9520 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9521 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9522 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9523 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9524 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9525 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9526 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9527 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9528 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9529 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9530 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9531 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9532 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9533 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9534 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9535 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9536 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9537 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9538 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9540 <<
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 )
9541 <<
new QgsStaticExpressionFunction(
9542 u
"regexp_matches"_s,
9544 << QgsExpressionFunction::Parameter( u
"string"_s )
9545 << QgsExpressionFunction::Parameter( u
"regex"_s )
9546 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
9551 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9552 <<
new QgsStaticExpressionFunction( u
"age"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime1"_s ) << QgsExpressionFunction::Parameter( u
"datetime2"_s ), fcnAge, u
"Date and Time"_s )
9561 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9562 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9563 <<
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 )
9564 <<
new QgsStaticExpressionFunction(
9566 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hour"_s ) << QgsExpressionFunction::Parameter( u
"minute"_s ) << QgsExpressionFunction::Parameter( u
"second"_s ),
9570 <<
new QgsStaticExpressionFunction(
9573 << QgsExpressionFunction::Parameter( u
"year"_s )
9574 << QgsExpressionFunction::Parameter( u
"month"_s )
9575 << QgsExpressionFunction::Parameter( u
"day"_s )
9576 << QgsExpressionFunction::Parameter( u
"hour"_s )
9577 << QgsExpressionFunction::Parameter( u
"minute"_s )
9578 << QgsExpressionFunction::Parameter( u
"second"_s ),
9582 <<
new QgsStaticExpressionFunction(
9585 << QgsExpressionFunction::Parameter( u
"years"_s,
true, 0 )
9586 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9587 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9588 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9589 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9590 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9591 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9595 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9596 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9597 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9598 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9599 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9601 <<
new QgsStaticExpressionFunction(
9604 << QgsExpressionFunction::Parameter( u
"string"_s )
9605 << QgsExpressionFunction::Parameter( u
"substring"_s )
9606 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9613 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9614 <<
new QgsStaticExpressionFunction( u
"ltrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9615 <<
new QgsStaticExpressionFunction( u
"rtrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9616 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9617 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9618 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9622 <<
new QgsStaticExpressionFunction(
9625 << QgsExpressionFunction::Parameter( u
"text"_s )
9626 << QgsExpressionFunction::Parameter( u
"length"_s )
9627 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ),
9631 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9632 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9633 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s ) }, fcnRepeat, u
"String"_s )
9634 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9635 <<
new QgsStaticExpressionFunction(
9636 u
"regexp_replace"_s,
9637 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"replacement"_s ),
9641 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9642 <<
new QgsStaticExpressionFunction(
9644 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ),
9654 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9655 <<
new QgsStaticExpressionFunction( u
"concat_ws"_s, -1, fcnConcatWs, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9656 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9657 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9658 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9659 <<
new QgsStaticExpressionFunction(
9661 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s,
true, u
" "_s ),
9665 <<
new QgsStaticExpressionFunction(
9667 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s,
true, u
" "_s ),
9671 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9672 <<
new QgsStaticExpressionFunction(
9675 << QgsExpressionFunction::Parameter( u
"number"_s )
9676 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9677 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9678 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9679 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ),
9683 <<
new QgsStaticExpressionFunction(
9686 << QgsExpressionFunction::Parameter( u
"datetime"_s )
9687 << QgsExpressionFunction::Parameter( u
"format"_s )
9688 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9690 QStringList() << u
"String"_s << u
"Date and Time"_s
9692 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9693 <<
new QgsStaticExpressionFunction(
9695 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9699 <<
new QgsStaticExpressionFunction(
9701 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9705 <<
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 )
9706 <<
new QgsStaticExpressionFunction(
9709 << QgsExpressionFunction::Parameter( u
"red"_s )
9710 << QgsExpressionFunction::Parameter( u
"green"_s )
9711 << QgsExpressionFunction::Parameter( u
"blue"_s )
9712 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9716 <<
new QgsStaticExpressionFunction(
9719 << QgsExpressionFunction::Parameter( u
"red"_s )
9720 << QgsExpressionFunction::Parameter( u
"green"_s )
9721 << QgsExpressionFunction::Parameter( u
"blue"_s )
9722 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9728 <<
new QgsStaticExpressionFunction( u
"create_ramp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ), fcnCreateRamp, u
"Color"_s )
9729 <<
new QgsStaticExpressionFunction(
9731 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9735 <<
new QgsStaticExpressionFunction(
9738 << QgsExpressionFunction::Parameter( u
"hue"_s )
9739 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9740 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9741 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9745 <<
new QgsStaticExpressionFunction(
9748 << QgsExpressionFunction::Parameter( u
"hue"_s )
9749 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9750 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9751 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9755 <<
new QgsStaticExpressionFunction(
9757 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9761 <<
new QgsStaticExpressionFunction(
9764 << QgsExpressionFunction::Parameter( u
"hue"_s )
9765 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9766 << QgsExpressionFunction::Parameter( u
"value"_s )
9767 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9771 <<
new QgsStaticExpressionFunction(
9774 << QgsExpressionFunction::Parameter( u
"hue"_s )
9775 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9776 << QgsExpressionFunction::Parameter( u
"value"_s )
9777 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9781 <<
new QgsStaticExpressionFunction(
9784 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9785 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9786 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9787 << QgsExpressionFunction::Parameter( u
"black"_s ),
9791 <<
new QgsStaticExpressionFunction(
9794 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9795 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9796 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9797 << QgsExpressionFunction::Parameter( u
"black"_s )
9798 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9802 <<
new QgsStaticExpressionFunction(
9805 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9806 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9807 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9808 << QgsExpressionFunction::Parameter( u
"black"_s )
9809 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9813 <<
new QgsStaticExpressionFunction( u
"color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ), fncColorPart, u
"Color"_s )
9814 <<
new QgsStaticExpressionFunction( u
"darker"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncDarker, u
"Color"_s )
9815 <<
new QgsStaticExpressionFunction( u
"lighter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncLighter, u
"Color"_s )
9816 <<
new QgsStaticExpressionFunction(
9817 u
"set_color_part"_s,
9818 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9824 <<
new QgsStaticExpressionFunction( u
"base_file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnBaseFileName, u
"Files and Paths"_s )
9825 <<
new QgsStaticExpressionFunction( u
"file_suffix"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSuffix, u
"Files and Paths"_s )
9826 <<
new QgsStaticExpressionFunction( u
"file_exists"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileExists, u
"Files and Paths"_s )
9827 <<
new QgsStaticExpressionFunction( u
"file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileName, u
"Files and Paths"_s )
9828 <<
new QgsStaticExpressionFunction( u
"is_file"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsFile, u
"Files and Paths"_s )
9829 <<
new QgsStaticExpressionFunction( u
"is_directory"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsDir, u
"Files and Paths"_s )
9830 <<
new QgsStaticExpressionFunction( u
"file_path"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFilePath, u
"Files and Paths"_s )
9831 <<
new QgsStaticExpressionFunction( u
"file_size"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSize, u
"Files and Paths"_s )
9833 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ), fcnExif, u
"Files and Paths"_s )
9834 <<
new QgsStaticExpressionFunction( u
"exif_geotag"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnExifGeoTag, u
"GeometryGroup"_s )
9837 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ), fcnGenericHash, u
"Conversions"_s )
9843 <<
new QgsStaticExpressionFunction( u
"from_base64"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnFromBase64, u
"Conversions"_s )
9846 <<
new QgsStaticExpressionFunction(
9847 u
"magnetic_declination"_s,
9849 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9850 << QgsExpressionFunction::Parameter( u
"date"_s )
9851 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9852 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9853 << QgsExpressionFunction::Parameter( u
"height"_s )
9854 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9855 fcnMagneticDeclination,
9858 <<
new QgsStaticExpressionFunction(
9859 u
"magnetic_inclination"_s,
9861 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9862 << QgsExpressionFunction::Parameter( u
"date"_s )
9863 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9864 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9865 << QgsExpressionFunction::Parameter( u
"height"_s )
9866 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9867 fcnMagneticInclination,
9870 <<
new QgsStaticExpressionFunction(
9871 u
"magnetic_declination_rate_of_change"_s,
9873 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9874 << QgsExpressionFunction::Parameter( u
"date"_s )
9875 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9876 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9877 << QgsExpressionFunction::Parameter( u
"height"_s )
9878 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9879 fcnMagneticDeclinationRateOfChange,
9882 <<
new QgsStaticExpressionFunction(
9883 u
"magnetic_inclination_rate_of_change"_s,
9885 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9886 << QgsExpressionFunction::Parameter( u
"date"_s )
9887 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9888 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9889 << QgsExpressionFunction::Parameter( u
"height"_s )
9890 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9891 fcnMagneticInclinationRateOfChange,
9898 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9900 functions << geomFunc;
9902 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9904 functions << areaFunc;
9906 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9908 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9910 functions << lengthFunc;
9912 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9914 functions << perimeterFunc;
9916 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9918 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnRoundness, u
"GeometryGroup"_s );
9920 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9924 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9928 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9932 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions {
9933 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9934 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9935 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9936 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9937 { u
"overlay_equals_exact"_s, fcnGeomOverlayEqualsExact },
9938 { u
"overlay_equals_topological"_s, fcnGeomOverlayEqualsTopological },
9939 { u
"overlay_equals_fuzzy"_s, fcnGeomOverlayEqualsFuzzy },
9940 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9941 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9942 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9944 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9945 while ( i.hasNext() )
9948 QString defaultBackend = i.key() ==
"overlay_equals"_L1 ? QString(
"QGIS" ) : QString(
"GEOS" );
9949 QgsStaticExpressionFunction *fcnGeomOverlayFunc =
new QgsStaticExpressionFunction(
9952 << QgsExpressionFunction::Parameter( u
"layer"_s )
9953 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9954 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9955 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9956 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9957 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9958 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9959 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9960 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false )
9961 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, defaultBackend,
false )
9962 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4,
false ),
9973 functions << fcnGeomOverlayFunc;
9976 QgsStaticExpressionFunction *fcnGeomOverlayNearestFunc =
new QgsStaticExpressionFunction(
9977 u
"overlay_nearest"_s,
9979 << QgsExpressionFunction::Parameter( u
"layer"_s )
9980 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9981 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9982 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9983 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9984 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9985 fcnGeomOverlayNearest,
9994 functions << fcnGeomOverlayNearestFunc;
9997 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
10002 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
10003 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
10004 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
10005 <<
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 )
10006 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
10007 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
10008 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
10009 <<
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 )
10010 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
10011 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
10012 <<
new QgsStaticExpressionFunction(
10013 u
"make_triangle"_s,
10014 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ) << QgsExpressionFunction::Parameter( u
"point3"_s ),
10018 <<
new QgsStaticExpressionFunction(
10021 << QgsExpressionFunction::Parameter( u
"center"_s )
10022 << QgsExpressionFunction::Parameter( u
"radius"_s )
10023 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
10027 <<
new QgsStaticExpressionFunction(
10030 << QgsExpressionFunction::Parameter( u
"center"_s )
10031 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
10032 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
10033 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10034 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
10038 <<
new QgsStaticExpressionFunction(
10039 u
"make_regular_polygon"_s,
10041 << QgsExpressionFunction::Parameter( u
"center"_s )
10042 << QgsExpressionFunction::Parameter( u
"radius"_s )
10043 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
10044 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
10045 fcnMakeRegularPolygon,
10048 <<
new QgsStaticExpressionFunction( u
"make_square"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnMakeSquare, u
"GeometryGroup"_s )
10049 <<
new QgsStaticExpressionFunction(
10050 u
"make_rectangle_3points"_s,
10052 << QgsExpressionFunction::Parameter( u
"point1"_s )
10053 << QgsExpressionFunction::Parameter( u
"point2"_s )
10054 << QgsExpressionFunction::Parameter( u
"point3"_s )
10055 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
10056 fcnMakeRectangleFrom3Points,
10059 <<
new QgsStaticExpressionFunction(
10062 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10063#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
10064 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
10066 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
10068 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
10075 <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
10077 <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
10079 <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
10081 <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
10083 QgsStaticExpressionFunction *xAtFunc
10084 =
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 );
10086 functions << xAtFunc;
10089 QgsStaticExpressionFunction *yAtFunc
10090 =
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 );
10092 functions << yAtFunc;
10095 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
10096 <<
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 )
10097 <<
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 )
10098 <<
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 )
10099 <<
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 )
10100 <<
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 )
10101 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10102 <<
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 )
10103 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
10104 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
10105 <<
new QgsStaticExpressionFunction(
10106 u
"intersects_bbox"_s,
10109 u
"GeometryGroup"_s,
10114 QStringList() << u
"bbox"_s
10116 <<
new QgsStaticExpressionFunction( u
"disjoint"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDisjoint, u
"GeometryGroup"_s )
10117 <<
new QgsStaticExpressionFunction( u
"intersects"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersects, u
"GeometryGroup"_s )
10118 <<
new QgsStaticExpressionFunction( u
"touches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnTouches, u
"GeometryGroup"_s )
10119 <<
new QgsStaticExpressionFunction( u
"crosses"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCrosses, u
"GeometryGroup"_s )
10120 <<
new QgsStaticExpressionFunction( u
"contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnContains, u
"GeometryGroup"_s )
10121 <<
new QgsStaticExpressionFunction( u
"overlaps"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnOverlaps, u
"GeometryGroup"_s )
10122 <<
new QgsStaticExpressionFunction( u
"within"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnWithin, u
"GeometryGroup"_s )
10123 <<
new QgsStaticExpressionFunction( u
"equals"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnEquals, u
"GeometryGroup"_s )
10124 <<
new QgsStaticExpressionFunction(
10127 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10128 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10129 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s ),
10133 <<
new QgsStaticExpressionFunction(
10134 u
"equals_topological"_s,
10136 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10137 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10138 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"GEOS"_s ),
10139 fcnIsEqualsTopological,
10142 <<
new QgsStaticExpressionFunction(
10145 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10146 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10147 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s )
10148 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4 ),
10152 <<
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 )
10153 <<
new QgsStaticExpressionFunction(
10156 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10157 << QgsExpressionFunction::Parameter( u
"rotation"_s )
10158 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
10159 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
10163 <<
new QgsStaticExpressionFunction(
10166 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10167 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
10168 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
10169 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
10173 <<
new QgsStaticExpressionFunction(
10174 u
"affine_transform"_s,
10176 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10177 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
10178 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
10179 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
10180 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
10181 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
10182 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
10183 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
10184 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
10185 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
10186 fcnAffineTransform,
10189 <<
new QgsStaticExpressionFunction(
10192 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10193 << QgsExpressionFunction::Parameter( u
"distance"_s )
10194 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
10195 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
10196 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
10197 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
10201 <<
new QgsStaticExpressionFunction( u
"force_rhr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForceRHR, u
"GeometryGroup"_s )
10202 <<
new QgsStaticExpressionFunction( u
"force_polygon_cw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCW, u
"GeometryGroup"_s )
10203 <<
new QgsStaticExpressionFunction( u
"force_polygon_ccw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCCW, u
"GeometryGroup"_s )
10204 <<
new QgsStaticExpressionFunction(
10207 << QgsExpressionFunction::Parameter( u
"center"_s )
10208 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10209 << QgsExpressionFunction::Parameter( u
"width"_s )
10210 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
10211 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ),
10215 <<
new QgsStaticExpressionFunction(
10216 u
"tapered_buffer"_s,
10218 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10219 << QgsExpressionFunction::Parameter( u
"start_width"_s )
10220 << QgsExpressionFunction::Parameter( u
"end_width"_s )
10221 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ),
10225 <<
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 )
10226 <<
new QgsStaticExpressionFunction(
10229 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10230 << QgsExpressionFunction::Parameter( u
"distance"_s )
10231 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10233 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10237 <<
new QgsStaticExpressionFunction(
10238 u
"single_sided_buffer"_s,
10240 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10241 << QgsExpressionFunction::Parameter( u
"distance"_s )
10242 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10244 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10245 fcnSingleSidedBuffer,
10248 <<
new QgsStaticExpressionFunction(
10251 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10252 << QgsExpressionFunction::Parameter( u
"start_distance"_s )
10253 << QgsExpressionFunction::Parameter( u
"end_distance"_s )
10254 << QgsExpressionFunction::Parameter( u
"start_deflection"_s,
true, 0 )
10255 << QgsExpressionFunction::Parameter( u
"end_deflection"_s,
true, 0 ),
10259 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
10260 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
10261 <<
new QgsStaticExpressionFunction( u
"pole_of_inaccessibility"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
10262 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
10263 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
10264 <<
new QgsStaticExpressionFunction( u
"interior_ring_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnInteriorRingN, u
"GeometryGroup"_s )
10265 <<
new QgsStaticExpressionFunction( u
"geometry_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnGeometryN, u
"GeometryGroup"_s )
10266 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
10267 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
10268 <<
new QgsStaticExpressionFunction( u
"shared_paths"_s,
QgsExpressionFunction::ParameterList { QgsExpressionFunction::Parameter( u
"geometry1"_s ), QgsExpressionFunction::Parameter( u
"geometry2"_s ) }, fcnSharedPaths, u
"GeometryGroup"_s )
10270 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
10271 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
10272 <<
new QgsStaticExpressionFunction(
10275 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10276 << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
10277 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
10278 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
10279 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ),
10283 <<
new QgsStaticExpressionFunction(
10284 u
"triangular_wave"_s,
10285 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10286 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10287 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10288 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10292 <<
new QgsStaticExpressionFunction(
10293 u
"triangular_wave_randomized"_s,
10294 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10295 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10296 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10297 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10298 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10299 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10300 fcnTriangularWaveRandomized,
10303 <<
new QgsStaticExpressionFunction(
10305 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10306 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10307 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10308 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10312 <<
new QgsStaticExpressionFunction(
10313 u
"square_wave_randomized"_s,
10314 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10315 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10316 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10317 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10318 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10319 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10320 fcnSquareWaveRandomized,
10323 <<
new QgsStaticExpressionFunction(
10325 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10326 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10327 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10328 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10332 <<
new QgsStaticExpressionFunction(
10333 u
"wave_randomized"_s,
10334 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10335 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10336 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10337 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10338 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10339 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10340 fcnRoundWaveRandomized,
10343 <<
new QgsStaticExpressionFunction(
10344 u
"apply_dash_pattern"_s,
10346 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10347 QgsExpressionFunction::Parameter( u
"pattern"_s ),
10348 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
10349 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
10350 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
10351 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
10353 fcnApplyDashPattern,
10356 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"vertices"_s ) }, fcnDensifyByCount, u
"GeometryGroup"_s )
10357 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"distance"_s ) }, fcnDensifyByDistance, u
"GeometryGroup"_s )
10358 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
10359 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
10360 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
10361 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
10362 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
10363 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
10364 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
10365 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
10366 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
10367 <<
new QgsStaticExpressionFunction(
10368 u
"is_empty_or_null"_s,
10371 u
"GeometryGroup"_s,
10379 <<
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 )
10380#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
10381 <<
new QgsStaticExpressionFunction(
10384 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10385 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
10386 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ),
10391 <<
new QgsStaticExpressionFunction( u
"oriented_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnOrientedBBox, u
"GeometryGroup"_s )
10392 <<
new QgsStaticExpressionFunction( u
"main_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnMainAngle, u
"GeometryGroup"_s )
10393 <<
new QgsStaticExpressionFunction( u
"minimal_circle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ), fcnMinimalCircle, u
"GeometryGroup"_s )
10394 <<
new QgsStaticExpressionFunction( u
"difference"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDifference, u
"GeometryGroup"_s )
10395 <<
new QgsStaticExpressionFunction( u
"distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDistance, u
"GeometryGroup"_s )
10396 <<
new QgsStaticExpressionFunction(
10397 u
"hausdorff_distance"_s,
10399 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10400 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10401 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
10402 fcnHausdorffDistance,
10405 <<
new QgsStaticExpressionFunction( u
"intersection"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersection, u
"GeometryGroup"_s )
10406 <<
new QgsStaticExpressionFunction(
10407 u
"sym_difference"_s,
10410 u
"GeometryGroup"_s,
10415 QStringList() << u
"symDifference"_s
10417 <<
new QgsStaticExpressionFunction( u
"combine"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10418 <<
new QgsStaticExpressionFunction( u
"union"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10419 <<
new QgsStaticExpressionFunction(
10423 u
"GeometryGroup"_s,
10428 QStringList() << u
"geomToWKT"_s
10430 <<
new QgsStaticExpressionFunction( u
"geom_to_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10431 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
10432 <<
new QgsStaticExpressionFunction(
10434 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"source_auth_id"_s ) << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
10435 fcnTransformGeometry,
10438 <<
new QgsStaticExpressionFunction(
10440 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ),
10442 u
"GeometryGroup"_s,
10445 <<
new QgsStaticExpressionFunction( u
"is_multipart"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsMultipart, u
"GeometryGroup"_s )
10450 <<
new QgsStaticExpressionFunction( u
"sinuosity"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSinuosity, u
"GeometryGroup"_s )
10451 <<
new QgsStaticExpressionFunction( u
"straight_distance_2d"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStraightDistance2d, u
"GeometryGroup"_s );
10454 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction(
10457 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10458 << QgsExpressionFunction::Parameter( u
"orderby"_s )
10459 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
10461 u
"GeometryGroup"_s,
10466 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10467 for ( QgsExpressionNode *argNode : argList )
10469 if ( !argNode->isStatic( parent, context ) )
10475 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10477 QString expString = argNode->
eval( parent, context ).toString();
10481 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10491 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10492 QString
expression = argNode->
eval( parent, context ).toString();
10494 e.prepare( context );
10499 functions << orderPartsFunc;
10502 <<
new QgsStaticExpressionFunction( u
"closest_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnClosestPoint, u
"GeometryGroup"_s )
10503 <<
new QgsStaticExpressionFunction( u
"shortest_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnShortestLine, u
"GeometryGroup"_s )
10504 <<
new QgsStaticExpressionFunction( u
"line_interpolate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
10505 <<
new QgsStaticExpressionFunction(
10506 u
"line_interpolate_point_by_m"_s,
10508 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10509 << QgsExpressionFunction::Parameter( u
"m"_s )
10510 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10511 fcnLineInterpolatePointByM,
10514 <<
new QgsStaticExpressionFunction( u
"line_interpolate_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
10515 <<
new QgsStaticExpressionFunction( u
"line_locate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
10516 <<
new QgsStaticExpressionFunction(
10517 u
"line_locate_m"_s,
10519 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10520 << QgsExpressionFunction::Parameter( u
"m"_s )
10521 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10525 <<
new QgsStaticExpressionFunction( u
"angle_at_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
10526 <<
new QgsStaticExpressionFunction( u
"distance_to_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
10527 <<
new QgsStaticExpressionFunction(
10528 u
"line_substring"_s,
10529 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10537 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
10539 functions << idFunc;
10541 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
10543 functions << currentFeatureFunc;
10545 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction(
10547 { QgsExpressionFunction::Parameter( u
"format"_s,
true, u
"WithBraces"_s ), QgsExpressionFunction::Parameter( u
"version"_s,
true, 4 ) },
10549 u
"Record and Attributes"_s,
10554 QStringList() << u
"$uuid"_s
10557 functions << uuidFunc;
10560 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
10561 <<
new QgsStaticExpressionFunction(
10563 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
10565 u
"Record and Attributes"_s,
10570 QStringList() << u
"QgsExpressionUtils::getFeature"_s
10572 <<
new QgsStaticExpressionFunction(
10573 u
"get_feature_by_id"_s,
10576 u
"Record and Attributes"_s,
10583 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction(
10587 u
"Record and Attributes"_s,
10593 functions << attributesFunc;
10594 QgsStaticExpressionFunction *representAttributesFunc
10595 =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1, fcnRepresentAttributes, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10597 functions << representAttributesFunc;
10599 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction(
10600 u
"is_feature_valid"_s,
10602 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10603 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10604 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10605 fcnValidateFeature,
10606 u
"Record and Attributes"_s,
10612 functions << validateFeature;
10614 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction(
10615 u
"is_attribute_valid"_s,
10617 << QgsExpressionFunction::Parameter( u
"attribute"_s,
false )
10619 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10620 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10621 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10622 fcnValidateAttribute,
10623 u
"Record and Attributes"_s,
10629 functions << validateAttribute;
10631 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction( u
"maptip"_s, -1, fcnFeatureMaptip, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10633 functions << maptipFunc;
10635 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction( u
"display_expression"_s, -1, fcnFeatureDisplayExpression, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10637 functions << displayFunc;
10639 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction( u
"is_selected"_s, -1, fcnIsSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10641 functions << isSelectedFunc;
10643 functions <<
new QgsStaticExpressionFunction( u
"num_selected"_s, -1, fcnNumSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10645 functions <<
new QgsStaticExpressionFunction(
10646 u
"sqlite_fetch_and_increment"_s,
10648 << QgsExpressionFunction::Parameter( u
"database"_s )
10649 << QgsExpressionFunction::Parameter( u
"table"_s )
10650 << QgsExpressionFunction::Parameter( u
"id_field"_s )
10651 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
10652 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
10653 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
10654 fcnSqliteFetchAndIncrement,
10655 u
"Record and Attributes"_s
10660 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
10661 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
10665 QgsStaticExpressionFunction *representValueFunc
10666 =
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 );
10669 Q_UNUSED( context )
10672 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
10679 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
10689 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
10694 functions << representValueFunc;
10698 <<
new QgsStaticExpressionFunction(
10699 u
"layer_property"_s,
10701 << QgsExpressionFunction::Parameter( u
"layer"_s )
10702 << QgsExpressionFunction::Parameter( u
"property"_s )
10703 << QgsExpressionFunction::Parameter( u
"translate"_s,
true,
true ),
10704 fcnGetLayerProperty,
10707 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"part"_s,
true ), fcnDecodeUri, u
"Map Layers"_s )
10708 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary_data"_s ), fcnMimeType, u
"General"_s )
10709 <<
new QgsStaticExpressionFunction(
10710 u
"raster_statistic"_s,
10711 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"statistic"_s ),
10712 fcnGetRasterBandStat,
10717 QgsStaticExpressionFunction *varFunction
10727 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10729 if ( !argNode->
isStatic( parent, context ) )
10732 const QString varName = argNode->
eval( parent, context ).toString();
10733 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
10737 return scope ? scope->
isStatic( varName ) :
false;
10742 if ( node && node->
args()->
count() > 0 )
10744 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10745 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
10747 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
10754 functions << varFunction;
10756 QgsStaticExpressionFunction *evalTemplateFunction
10761 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10763 if ( argNode->
isStatic( parent, context ) )
10765 QString expString = argNode->
eval( parent, context ).toString();
10769 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10776 functions << evalTemplateFunction;
10778 QgsStaticExpressionFunction *evalFunc
10783 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10785 if ( argNode->
isStatic( parent, context ) )
10787 QString expString = argNode->
eval( parent, context ).toString();
10791 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10799 functions << evalFunc;
10801 QgsStaticExpressionFunction *attributeFunc
10802 =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10804 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10805 for ( QgsExpressionNode *argNode : argList )
10807 if ( !argNode->
isStatic( parent, context ) )
10819 functions << attributeFunc;
10823 <<
new QgsWithVariableExpressionFunction()
10824 <<
new QgsStaticExpressionFunction(
10826 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10830 <<
new QgsStaticExpressionFunction(
10831 u
"raster_attributes"_s,
10832 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10833 fcnRasterAttributes,
10838 <<
new QgsArrayForeachExpressionFunction()
10839 <<
new QgsArrayFilterExpressionFunction()
10840 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10841 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10842 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10843 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10844 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10845 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayAll, u
"Arrays"_s )
10846 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10847 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10853 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10854 <<
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 )
10855 <<
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 )
10857 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10858 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10859 <<
new QgsStaticExpressionFunction(
10861 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
10865 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10866 <<
new QgsStaticExpressionFunction(
10867 u
"array_remove_all"_s,
10878 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10879 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"priority"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10880 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10881 <<
new QgsStaticExpressionFunction(
10883 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ),
10887 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10888 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10889 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10890 <<
new QgsStaticExpressionFunction(
10891 u
"array_to_string"_s,
10893 << QgsExpressionFunction::Parameter( u
"array"_s )
10894 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10895 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10899 <<
new QgsStaticExpressionFunction(
10900 u
"string_to_array"_s,
10902 << QgsExpressionFunction::Parameter( u
"string"_s )
10903 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10904 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10908 <<
new QgsStaticExpressionFunction(
10909 u
"generate_series"_s,
10910 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ),
10914 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10917 <<
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 )
10918 <<
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 )
10919 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10921 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10922 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10923 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10924 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10925 <<
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 )
10926 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10929 <<
new QgsStaticExpressionFunction( u
"map_prefix_keys"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"prefix"_s ), fcnMapPrefixKeys, u
"Maps"_s )
10930 <<
new QgsStaticExpressionFunction( u
"map_to_html_table"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlTable, u
"Maps"_s )
10931 <<
new QgsStaticExpressionFunction( u
"map_to_html_dl"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlDefinitionList, u
"Maps"_s )
10941 *sOwnedFunctions() << func;
10942 *sBuiltinFunctions() << func->name();
10943 sBuiltinFunctions()->append( func->aliases() );
10957 QMutexLocker locker( &sFunctionsMutex );
10958 sFunctions()->append( function );
10959 if ( transferOwnership )
10960 sOwnedFunctions()->append( function );
10975 QMutexLocker locker( &sFunctionsMutex );
10976 sFunctions()->removeAt( fnIdx );
10977 sFunctionIndexMap.clear();
10985 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10986 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10988 sBuiltinFunctions()->removeAll( func->name() );
10989 for (
const QString &alias : func->aliases() )
10991 sBuiltinFunctions()->removeAll( alias );
10994 sFunctions()->removeAll( func );
10997 qDeleteAll( *sOwnedFunctions() );
10998 sOwnedFunctions()->clear();
11003 if ( sBuiltinFunctions()->isEmpty() )
11007 return *sBuiltinFunctions();
11012 u
"array_foreach"_s,
11022 QgsExpressionNode::NodeList *args = node->
args();
11024 if ( args->
count() < 2 )
11027 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11037 QVariantList result;
11039 if ( args->
count() < 2 )
11043 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11045 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11046 std::unique_ptr< QgsExpressionContext > tempContext;
11049 tempContext = std::make_unique< QgsExpressionContext >();
11050 subContext = tempContext.get();
11053 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11057 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
11061 result << args->
at( 1 )->
eval( parent, subContext );
11074 Q_UNUSED( context )
11086 if ( args->
count() < 2 )
11090 args->
at( 0 )->
prepare( parent, context );
11094 subContext = *context;
11101 args->
at( 1 )->
prepare( parent, &subContext );
11114 QgsExpressionNode::NodeList *args = node->
args();
11116 if ( args->
count() < 2 )
11119 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11129 QVariantList result;
11131 if ( args->
count() < 2 )
11135 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11137 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11138 std::unique_ptr< QgsExpressionContext > tempContext;
11141 tempContext = std::make_unique< QgsExpressionContext >();
11142 subContext = tempContext.get();
11145 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11149 if ( args->
count() >= 3 )
11151 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
11153 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
11155 limit = limitVar.toInt();
11163 for (
const QVariant &value : array )
11165 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
11166 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
11170 if ( limit > 0 && limit == result.size() )
11185 Q_UNUSED( context )
11197 if ( args->
count() < 2 )
11201 args->
at( 0 )->
prepare( parent, context );
11205 subContext = *context;
11211 args->
at( 1 )->
prepare( parent, &subContext );
11223 QgsExpressionNode::NodeList *args = node->
args();
11225 if ( args->
count() < 3 )
11229 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11231 QVariant
name = args->
at( 0 )->
eval( parent, context );
11232 QVariant value = args->
at( 1 )->
eval( parent, context );
11235 appendTemporaryVariable( context,
name.toString(), value );
11236 if ( args->
at( 2 )->
isStatic( parent, context ) )
11238 popTemporaryVariable( context );
11249 if ( args->
count() < 3 )
11253 QVariant
name = args->
at( 0 )->
eval( parent, context );
11254 QVariant value = args->
at( 1 )->
eval( parent, context );
11256 const QgsExpressionContext *updatedContext = context;
11257 std::unique_ptr< QgsExpressionContext > tempContext;
11258 if ( !updatedContext )
11260 tempContext = std::make_unique< QgsExpressionContext >();
11261 updatedContext = tempContext.get();
11264 appendTemporaryVariable( updatedContext,
name.toString(), value );
11265 result = args->
at( 2 )->
eval( parent, updatedContext );
11268 popTemporaryVariable( updatedContext );
11277 Q_UNUSED( context )
11289 if ( args->
count() < 3 )
11294 QVariant value = args->
at( 1 )->
prepare( parent, context );
11297 std::unique_ptr< QgsExpressionContext > tempContext;
11298 if ( !updatedContext )
11300 tempContext = std::make_unique< QgsExpressionContext >();
11301 updatedContext = tempContext.get();
11304 appendTemporaryVariable( updatedContext,
name.toString(), value );
11305 args->
at( 2 )->
prepare( parent, updatedContext );
11308 popTemporaryVariable( updatedContext );
11313void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
11315 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
11316 delete updatedContext->
popScope();
11319void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
11321 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
11322 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
11324 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 extendLine(double startDistance, double endDistance, double startDeflection=0, double endDeflection=0) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
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 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 ...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
QgsRelationManager * relationManager
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)
Decodes a string to a color.
static QString encodeColor(const QColor &color)
Lossy-encodes a color to a string.
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.