70#include <QCryptographicHash>
71#include <QMimeDatabase>
72#include <QProcessEnvironment>
73#include <QRegularExpression>
78using namespace Qt::StringLiterals;
99 QVariantList argValues;
103 const QList< QgsExpressionNode * > argList = args->
list();
104 argValues.reserve( argList.size() );
111 v = QVariant::fromValue( n );
115 v = n->eval( parent, context );
117 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
118 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
121 argValues.append( v );
126 return func( argValues, context, parent, node );
137 return QStringList();
164 return mGroups.isEmpty() ? false : mGroups.contains( u
"deprecated"_s );
169 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
180 const QString &fnname,
183 const QString &group,
184 const QString &helpText,
188 const QStringList &aliases,
193 , mAliases( aliases )
194 , mUsesGeometry( false )
195 , mUsesGeometryFunc( usesGeometry )
196 , mReferencedColumnsFunc( referencedColumns )
207 if ( mUsesGeometryFunc )
208 return mUsesGeometryFunc( node );
210 return mUsesGeometry;
220 if ( mReferencedColumnsFunc )
221 return mReferencedColumnsFunc( node );
223 return mReferencedColumns;
229 return mIsStaticFunc( node, parent, context );
237 return mPrepareFunc( node, parent, context );
249 mIsStaticFunc =
nullptr;
255 mPrepareFunc = prepareFunc;
260 if ( node && node->
args() )
262 const QList< QgsExpressionNode * > argList = node->
args()->
list();
265 if ( !argNode->isStatic( parent, context ) )
275 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
276 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
277 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
279 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
286 double current = start + step;
287 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
310 return QVariant::fromValue( geom );
321 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
323 if ( name ==
"feature"_L1 )
325 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
327 else if ( name ==
"id"_L1 )
329 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
331 else if ( name ==
"geometry"_L1 )
333 return fcnGeometry( values, context, parent, node );
343 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
352 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
354 return expression.evaluate( context );
359 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
360 return QVariant( std::sqrt( x ) );
365 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
366 return QVariant( std::fabs( val ) );
371 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
372 return ( deg * M_PI ) / 180;
376 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
377 return ( 180 * rad ) / M_PI;
381 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
382 return QVariant( std::sin( x ) );
386 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
387 return QVariant( std::cos( x ) );
391 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
392 return QVariant( std::tan( x ) );
396 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
397 return QVariant( std::asin( x ) );
401 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::acos( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
407 return QVariant( std::atan( x ) );
411 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
412 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
413 return QVariant( std::atan2( y, x ) );
417 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
418 return QVariant( std::exp( x ) );
422 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
425 return QVariant( std::log( x ) );
429 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
432 return QVariant( log10( x ) );
436 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
437 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
438 if ( x <= 0 || b <= 0 )
440 return QVariant( std::log( x ) / std::log( b ) );
444 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
445 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
449 std::random_device rd;
450 std::mt19937_64 generator( rd() );
452 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
455 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
458 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
463 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
464 std::hash<std::string> hasher;
465 seed = hasher( seedStr.toStdString() );
467 generator.seed( seed );
471 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
472 return QVariant( min + f * ( max - min ) );
476 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
477 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
481 std::random_device rd;
482 std::mt19937_64 generator( rd() );
484 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
487 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
490 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
495 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
496 std::hash<std::string> hasher;
497 seed = hasher( seedStr.toStdString() );
499 generator.seed( seed );
502 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
503 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
504 return QVariant( randomInteger );
507 return QVariant(
int( randomInteger ) );
512 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
513 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
514 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
515 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
516 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
518 if ( domainMin >= domainMax )
520 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
525 if ( val >= domainMax )
529 else if ( val <= domainMin )
535 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
536 double c = rangeMin - ( domainMin * m );
539 return QVariant( m * val +
c );
544 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
545 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
546 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
547 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
548 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
549 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
551 if ( domainMin >= domainMax )
553 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
563 if ( val >= domainMax )
567 else if ( val <= domainMin )
573 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
578 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
579 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
580 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
581 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
582 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
583 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
585 if ( domainMin >= domainMax )
587 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
597 if ( val >= domainMax )
601 else if ( val <= domainMin )
607 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
608 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
613 const double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
614 const double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
615 const double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
616 const double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
617 const double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
619 const double x1 = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
620 const double y1 = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
621 const double x2 = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
622 const double y2 = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
624 if ( x1 < 0.0 || x1 > 1.0 || y1 < 0.0 || y1 > 1.0 || x2 < 0.0 || x2 > 1.0 || y2 < 0.0 || y2 > 1.0 )
626 parent->
setEvalErrorString( QObject::tr(
"Cubic bezier control points must be between 0 and 1" ) );
630 if ( domainMin >= domainMax )
632 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
637 if ( val >= domainMax )
641 else if ( val <= domainMin )
647 const double t = ( val - domainMin ) / ( domainMax - domainMin );
650 const double cx = 3.0 * x1;
651 const double bx = 3.0 * ( x2 - x1 ) - cx;
652 const double ax = 1.0 - cx - bx;
653 const double cy = 3.0 * y1;
654 const double by = 3.0 * ( y2 - y1 ) - cy;
655 const double ay = 1.0 - cy - by;
657 constexpr double epsilon = 1e-6;
662 for (
int i = 0; i < 8; ++i )
664 const double x2val = ( ( ax * s + bx ) * s + cx ) * s - t;
665 if ( std::fabs( x2val ) < epsilon )
670 const double d2 = ( 3.0 * ax * s + 2.0 * bx ) * s + cx;
671 if ( std::fabs( d2 ) < 1e-6 )
694 while ( !solved && t0 < t1 )
696 const double x2val = ( ( ax * s + bx ) * s + cx ) * s;
697 if ( std::fabs( x2val - t ) < epsilon )
706 s = ( t1 - t0 ) * 0.5 + t0;
710 const double easedT = ( ( ay * s + by ) * s + cy ) * s;
711 return QVariant( ( rangeMax - rangeMin ) * easedT + rangeMin );
717 double maxVal = std::numeric_limits<double>::quiet_NaN();
718 for (
const QVariant &val : values )
721 if ( std::isnan( maxVal ) )
725 else if ( !std::isnan( testVal ) )
727 maxVal = std::max( maxVal, testVal );
731 if ( !std::isnan( maxVal ) )
733 result = QVariant( maxVal );
741 double minVal = std::numeric_limits<double>::quiet_NaN();
742 for (
const QVariant &val : values )
745 if ( std::isnan( minVal ) )
749 else if ( !std::isnan( testVal ) )
751 minVal = std::min( minVal, testVal );
755 if ( !std::isnan( minVal ) )
757 result = QVariant( minVal );
769 QVariant value = node->
eval( parent, context );
774 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
778 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
783 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
785 value = node->
eval( parent, context );
791 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
796 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
798 QString subExpression = node->
dump();
802 if ( values.count() > 3 )
804 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
807 if ( !nl || nl->value().isValid() )
812 if ( values.count() > 4 )
814 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
816 value = node->
eval( parent, context );
823 if ( values.count() > 5 )
825 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
828 if ( !nl || nl->value().isValid() )
830 orderBy = node->
dump();
835 QString aggregateError;
843 const QSet< QString > filterVars = filterExp.referencedVariables();
844 const QSet< QString > subExpVars = subExp.referencedVariables();
845 QSet<QString> allVars = filterVars + subExpVars;
847 bool isStatic =
true;
848 if ( filterVars.contains( u
"parent"_s ) || filterVars.contains( QString() ) || subExpVars.contains( u
"parent"_s ) || subExpVars.contains( QString() ) )
854 for (
const QString &varName : allVars )
857 if ( scope && !scope->
isStatic( varName ) )
865 if ( isStatic && !parameters.
orderBy.isEmpty() )
867 for (
const auto &orderByClause : std::as_const( parameters.
orderBy ) )
869 const QgsExpression &orderByExpression { orderByClause.expression() };
881 const QString contextHash = context->
uniqueHash( ok, allVars );
884 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
889 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
900 subContext.appendScope( subScope );
901 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
913 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
917 if ( !aggregateError.isEmpty() )
918 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
920 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
931 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
939 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
943 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
952 QVariant value = node->
eval( parent, context );
954 QString relationId = value.toString();
961 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
963 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
968 relation = relations.at( 0 );
975 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
977 value = node->
eval( parent, context );
983 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
988 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
990 QString subExpression = node->
dump();
994 if ( values.count() > 3 )
996 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
998 value = node->
eval( parent, context );
1000 parameters.
delimiter = value.toString();
1005 if ( values.count() > 4 )
1007 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
1010 if ( !nl || nl->value().isValid() )
1012 orderBy = node->
dump();
1023 const QString
cacheKey = u
"relagg:%1%:%2:%3:%4:%5:%6"_s.arg( relationId, vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1033 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1037 if ( !error.isEmpty() )
1038 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1040 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1050static QVariant fcnAggregateGeneric(
1056 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1064 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
1068 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1075 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1077 QString subExpression = node->
dump();
1081 if ( values.count() > 1 )
1083 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
1086 if ( !nl || nl->value().isValid() )
1087 groupBy = node->
dump();
1091 if ( values.count() > 2 )
1093 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
1096 if ( !nl || nl->value().isValid() )
1102 if ( orderByPos >= 0 && values.count() > orderByPos )
1104 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
1107 if ( !nl || nl->value().isValid() )
1109 orderBy = node->
dump();
1117 if ( !groupBy.isEmpty() )
1120 QVariant groupByValue = groupByExp.evaluate( context );
1122 if ( !parameters.
filter.isEmpty() )
1123 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1125 parameters.
filter = groupByClause;
1131 bool isStatic =
true;
1132 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1133 for (
const QString &varName : refVars )
1136 if ( scope && !scope->
isStatic( varName ) )
1147 const QString contextHash = context->
uniqueHash( ok, refVars );
1150 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
1155 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1167 subContext.appendScope( subScope );
1169 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1173 if ( !error.isEmpty() )
1174 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1176 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1281 if ( values.count() > 3 )
1283 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1285 QVariant value = node->
eval( parent, context );
1287 parameters.
delimiter = value.toString();
1298 if ( values.count() > 3 )
1300 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1302 QVariant value = node->
eval( parent, context );
1304 parameters.
delimiter = value.toString();
1320 QVariant scale = context->
variable( u
"map_scale"_s );
1325 const double v = scale.toDouble( &ok );
1333 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1334 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1335 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1338 if ( testValue <= minValue )
1340 return QVariant( minValue );
1342 else if ( testValue >= maxValue )
1344 return QVariant( maxValue );
1348 return QVariant( testValue );
1354 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1355 return QVariant( std::floor( x ) );
1360 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1361 return QVariant( std::ceil( x ) );
1366 const QVariant value = values.at( 0 );
1367 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1369 return QVariant(
false );
1371 else if ( value.userType() == QMetaType::QString )
1374 return QVariant( !value.toString().isEmpty() );
1376 else if ( QgsExpressionUtils::isList( value ) )
1378 return !value.toList().isEmpty();
1380 return QVariant( value.toBool() );
1384 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1388 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1392 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1397 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1398 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1399 if ( format.isEmpty() && !language.isEmpty() )
1401 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1402 return QVariant( QDateTime() );
1405 if ( format.isEmpty() && language.isEmpty() )
1406 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1408 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1409 QLocale locale = QLocale();
1410 if ( !language.isEmpty() )
1412 locale = QLocale( language );
1415 QDateTime datetime = locale.toDateTime( datetimestring, format );
1416 if ( !datetime.isValid() )
1418 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1419 datetime = QDateTime();
1421 return QVariant( datetime );
1426 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1427 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1428 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1430 const QDate date( year, month, day );
1431 if ( !date.isValid() )
1433 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1436 return QVariant( date );
1441 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1442 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1443 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1445 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1446 if ( !time.isValid() )
1448 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1451 return QVariant( time );
1456 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1457 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1458 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1459 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1460 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1461 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1463 const QDate date( year, month, day );
1464 if ( !date.isValid() )
1466 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1469 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1470 if ( !time.isValid() )
1472 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1475 return QVariant( QDateTime( date, time ) );
1480 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1484#if QT_FEATURE_timezone > 0
1485 if ( !timeZoneId.isEmpty() )
1487 tz = QTimeZone( timeZoneId.toUtf8() );
1490 if ( !tz.isValid() )
1492 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1497 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1499 return QVariant::fromValue( tz );
1504#if QT_FEATURE_timezone > 0
1505 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1506 if ( datetime.isValid() )
1508 return QVariant::fromValue( datetime.timeZone() );
1512 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1519#if QT_FEATURE_timezone > 0
1520 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1521 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1522 if ( datetime.isValid() && tz.isValid() )
1524 datetime.setTimeZone( tz );
1525 return QVariant::fromValue( datetime );
1529 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1536#if QT_FEATURE_timezone > 0
1537 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1538 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1539 if ( datetime.isValid() && tz.isValid() )
1541 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1545 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1552#if QT_FEATURE_timezone > 0
1553 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1554 if ( timeZone.isValid() )
1556 return QString( timeZone.id() );
1560 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1567 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1568 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1569 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1570 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1571 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1572 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1573 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1575 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1580 for (
const QVariant &value : values )
1591 const QVariant val1 = values.at( 0 );
1592 const QVariant val2 = values.at( 1 );
1602 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1603 return QVariant( str.toLower() );
1607 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1608 return QVariant( str.toUpper() );
1612 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1613 QStringList elems = str.split(
' ' );
1614 for (
int i = 0; i < elems.size(); i++ )
1616 if ( elems[i].size() > 1 )
1617 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1619 return QVariant( elems.join(
' '_L1 ) );
1624 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1625 return QVariant( str.trimmed() );
1630 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1632 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1634 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1635 str.replace( re, QString() );
1636 return QVariant( str );
1641 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1643 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1645 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1646 str.replace( re, QString() );
1647 return QVariant( str );
1652 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1653 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1659 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1660 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1666 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1667 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1674 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1680 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1681 return QVariant( QString( character ) );
1686 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1688 if ( value.isEmpty() )
1693 int res = value.at( 0 ).unicode();
1694 return QVariant( res );
1699 if ( values.length() == 2 || values.length() == 3 )
1701 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1702 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1704 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1717 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1721 return QVariant( geom.
length() );
1727 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1728 return QVariant( str.length() );
1733 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1738 double totalLength = 0;
1743 totalLength += line->length3D();
1748 totalLength += segmentized->length3D();
1758 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1759 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1760 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1765 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1767 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1768 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1769 QVector< QPair< QString, QString > > mapItems;
1771 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1773 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1777 std::sort( mapItems.begin(), mapItems.end(), [](
const QPair< QString, QString > &pair1,
const QPair< QString, QString > &pair2 ) { return ( pair1.first.length() > pair2.first.length() ); } );
1779 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1781 str = str.replace( it->first, it->second );
1784 return QVariant( str );
1786 else if ( values.count() == 3 )
1788 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1789 QVariantList before;
1791 bool isSingleReplacement =
false;
1793 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1795 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1799 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1802 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1804 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1805 isSingleReplacement =
true;
1809 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1812 if ( !isSingleReplacement && before.length() != after.length() )
1814 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1818 for (
int i = 0; i < before.length(); i++ )
1820 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1823 return QVariant( str );
1827 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1834 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1835 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1836 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1838 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1839 if ( !re.isValid() )
1841 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1844 return QVariant( str.replace( re, after ) );
1849 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1850 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1852 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1853 if ( !re.isValid() )
1855 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1858 return QVariant( ( str.indexOf( re ) + 1 ) );
1863 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1864 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1865 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1867 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1868 if ( !re.isValid() )
1870 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1874 QRegularExpressionMatch matches = re.match( str );
1875 if ( matches.hasMatch() )
1878 QStringList list = matches.capturedTexts();
1881 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1883 array += ( !( *it ).isEmpty() ) ? *it : empty;
1886 return QVariant( array );
1896 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1897 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1899 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1900 if ( !re.isValid() )
1902 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1907 QRegularExpressionMatch match = re.match( str );
1908 if ( match.hasMatch() )
1911 if ( match.lastCapturedIndex() > 0 )
1914 return QVariant( match.captured( 1 ) );
1919 return QVariant( match.captured( 0 ) );
1924 return QVariant(
"" );
1930 QString uuid = QUuid::createUuid().toString();
1931 if ( values.at( 0 ).toString().compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1932 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1933 else if ( values.at( 0 ).toString().compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1934 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1940 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1943 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1944 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1947 if ( values.at( 2 ).isValid() )
1948 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1954 from = str.size() + from;
1960 else if ( from > 0 )
1968 len = str.size() + len - from;
1975 return QVariant( str.mid( from, len ) );
1980 return QVariant( f.
id() );
1985 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1986 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1987 bool foundLayer =
false;
1988 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
1993 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1994 if ( !layer || !layer->dataProvider() )
1996 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2000 if ( bandNb < 1 || bandNb > layer->bandCount() )
2002 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
2008 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
2015 QgsMultiPointXY multiPoint = geom.asMultiPoint();
2016 if ( multiPoint.count() == 1 )
2018 point = multiPoint[0];
2027 double value = layer->dataProvider()->sample( point, bandNb );
2028 return std::isnan( value ) ? QVariant() : value;
2035 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2046 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2047 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2049 bool foundLayer =
false;
2050 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2054 [parent, bandNb, value](
QgsMapLayer *mapLayer ) -> QVariant {
2055 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
2056 if ( !layer || !layer->dataProvider() )
2058 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2062 if ( bandNb < 1 || bandNb > layer->bandCount() )
2064 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
2068 if ( std::isnan( value ) )
2070 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
2074 if ( !layer->dataProvider()->attributeTable( bandNb ) )
2079 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
2080 if ( data.isEmpty() )
2086 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
2087 for (
int idx = 0; idx < static_cast<int>( fields.count() ) && idx < static_cast<int>( data.count() ); ++idx )
2094 result.insert( fields.at( idx ).name, data.at( idx ) );
2104 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2125 if ( values.size() == 1 )
2127 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2130 else if ( values.size() == 2 )
2132 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2133 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2137 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2146 QString table { R
"html(
2149 <tr><th>%1</th></tr>
2152 <tr><td>%2</td></tr>
2156 if ( values.size() == 1 )
2158 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2162 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2166 if ( dict.isEmpty() )
2171 QStringList headers;
2174 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2176 headers.push_back( it.key().toHtmlEscaped() );
2177 cells.push_back( it.value().toString().toHtmlEscaped() );
2180 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2185 QString table { R
"html(
2190 if ( values.size() == 1 )
2192 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2196 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2200 if ( dict.isEmpty() )
2207 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2209 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2212 return table.arg( rows );
2220 layer = context->
variable( u
"layer"_s );
2225 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2227 layer = node->
eval( parent, context );
2238 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2242 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2243 if ( strength ==
"hard"_L1 )
2247 else if ( strength ==
"soft"_L1 )
2252 bool foundLayer =
false;
2253 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2257 [parent, feature, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2258 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2261 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2267 for (
int i = 0; i < fields.
size(); i++ )
2284 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2296 layer = context->
variable( u
"layer"_s );
2301 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2303 layer = node->
eval( parent, context );
2314 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2318 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2319 if ( strength ==
"hard"_L1 )
2323 else if ( strength ==
"soft"_L1 )
2328 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2330 bool foundLayer =
false;
2331 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2335 [parent, feature, attributeName, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2336 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2343 if ( fieldIndex == -1 )
2345 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2358 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2374 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2379 for (
int i = 0; i < fields.
count(); ++i )
2393 if ( values.isEmpty() )
2396 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2398 else if ( values.size() == 1 )
2400 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2401 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2403 else if ( values.size() == 2 )
2405 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2406 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2410 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2417 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2423 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2429 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2431 const QString fieldName { fields.
at( fieldIndex ).
name() };
2432 const QVariant attributeVal = feature.
attribute( fieldIndex );
2433 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2436 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2445 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2457 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2459 result.insert( fields.
at( fieldIndex ).
name(), value );
2474 bool evaluate =
true;
2478 if ( values.isEmpty() )
2481 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2483 else if ( values.size() == 1 )
2485 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2486 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2488 else if ( values.size() == 2 )
2490 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2491 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2493 else if ( values.size() == 3 )
2495 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2496 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2497 evaluate = values.value( 2 ).toBool();
2503 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2507 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2539 subContext.setFeature( feature );
2548 exp.prepare( &subContext );
2549 return exp.evaluate( &subContext ).toString();
2555 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2560 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2567 if ( values.isEmpty() )
2570 layer = context->
variable( u
"layer"_s );
2572 else if ( values.size() == 1 )
2574 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2575 layer = context->
variable( u
"layer"_s );
2577 else if ( values.size() == 2 )
2579 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2580 layer = values.at( 0 );
2584 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2588 bool foundLayer =
false;
2589 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2594 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2595 if ( !layer || !feature.
isValid() )
2614 if ( values.isEmpty() )
2615 layer = context->
variable( u
"layer"_s );
2616 else if ( values.count() == 1 )
2617 layer = values.at( 0 );
2620 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2624 bool foundLayer =
false;
2625 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2630 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2648 static QMap<QString, qlonglong> counterCache;
2649 QVariant functionResult;
2651 auto fetchAndIncrementFunc = [values, parent, &functionResult](
QgsMapLayer *mapLayer,
const QString &databaseArgument ) {
2654 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2659 database = decodedUri.value( u
"path"_s ).toString();
2660 if ( database.isEmpty() )
2662 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2667 database = databaseArgument;
2670 const QString table = values.at( 1 ).toString();
2671 const QString idColumn = values.at( 2 ).toString();
2672 const QString filterAttribute = values.at( 3 ).toString();
2673 const QVariant filterValue = values.at( 4 ).toString();
2674 const QVariantMap defaultValues = values.at( 5 ).toMap();
2680 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2683 functionResult = QVariant();
2687 QString errorMessage;
2688 QString currentValSql;
2690 qlonglong nextId = 0;
2691 bool cachedMode =
false;
2692 bool valueRetrieved =
false;
2694 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2701 auto cachedCounter = counterCache.find( cacheString );
2703 if ( cachedCounter != counterCache.end() )
2705 qlonglong &cachedValue = cachedCounter.value();
2706 nextId = cachedValue;
2708 cachedValue = nextId;
2709 valueRetrieved =
true;
2714 if ( !cachedMode || !valueRetrieved )
2716 int result = SQLITE_ERROR;
2719 if ( !filterAttribute.isNull() )
2724 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2726 if ( result == SQLITE_OK )
2729 if ( sqliteStatement.
step() == SQLITE_ROW )
2735 if ( cachedMode && result == SQLITE_OK )
2737 counterCache.insert( cacheString, nextId );
2739 QObject::connect( layer->
dataProvider()->
transaction(), &QgsTransaction::destroyed, [cacheString]() { counterCache.remove( cacheString ); } );
2741 valueRetrieved =
true;
2745 if ( valueRetrieved )
2754 if ( !filterAttribute.isNull() )
2760 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2763 vals << iter.value().toString();
2766 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2767 upsertSql +=
" VALUES "_L1;
2768 upsertSql +=
'(' + vals.join(
',' ) +
')';
2770 int result = SQLITE_ERROR;
2774 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2781 result = sqliteDb.
exec( upsertSql, errorMessage );
2783 if ( result == SQLITE_OK )
2785 functionResult = QVariant( nextId );
2790 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2791 functionResult = QVariant();
2796 functionResult = QVariant();
2799 bool foundLayer =
false;
2800 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer *layer ) { fetchAndIncrementFunc( layer, QString() ); }, foundLayer );
2803 const QString databasePath = values.at( 0 ).toString();
2807 return functionResult;
2820 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2825 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2828 return QVariant::fromValue( crs );
2834 for (
const QVariant &value : values )
2837 concat += QgsExpressionUtils::getStringValue( value, parent );
2844 if ( values.length() < 2 )
2846 parent->
setEvalErrorString( QObject::tr(
"Function concat_ws requires at least 2 arguments" ) );
2850 const QString separator = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2852 QStringList stringValues;
2853 stringValues.reserve( values.size() - 1 );
2854 for (
int i = 1; i < values.size(); ++i )
2856 const QVariant value = values.at( i );
2859 stringValues.append( QgsExpressionUtils::getStringValue( value, parent ) );
2863 return stringValues.join( separator );
2868 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2869 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2877 if ( values.isEmpty() || values[0].isNull() )
2886 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2887 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2888 return string.right( pos );
2893 if ( values.length() < 2 || values.length() > 3 )
2896 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2897 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2899 bool overlapping =
false;
2900 if ( values.length() == 3 )
2902 overlapping = values.at( 2 ).toBool();
2905 if ( substring.isEmpty() )
2906 return QVariant( 0 );
2911 count = input.count( substring );
2916 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2919 pos += substring.length();
2923 return QVariant( count );
2928 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2929 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2930 return string.left( pos );
2935 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2936 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2937 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2938 return string.leftJustified( length, fill.at( 0 ),
true );
2943 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2944 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2945 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2946 return string.rightJustified( length, fill.at( 0 ),
true );
2951 if ( values.size() < 1 )
2953 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2957 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2958 for (
int n = 1; n < values.length(); n++ )
2960 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2968 return QVariant( QDateTime::currentDateTime() );
2973 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2974 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2975 if ( format.isEmpty() && !language.isEmpty() )
2977 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2978 return QVariant( QDate() );
2981 if ( format.isEmpty() && language.isEmpty() )
2982 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2984 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2985 QLocale locale = QLocale();
2986 if ( !language.isEmpty() )
2988 locale = QLocale( language );
2991 QDate date = locale.toDate( datestring, format );
2992 if ( !date.isValid() )
2994 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2997 return QVariant( date );
3002 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3003 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3004 if ( format.isEmpty() && !language.isEmpty() )
3006 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
3007 return QVariant( QTime() );
3010 if ( format.isEmpty() && language.isEmpty() )
3011 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
3013 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3014 QLocale locale = QLocale();
3015 if ( !language.isEmpty() )
3017 locale = QLocale( language );
3020 QTime time = locale.toTime( timestring, format );
3021 if ( !time.isValid() )
3023 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
3026 return QVariant( time );
3031 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
3040 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3041 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3042 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3044 QString formatString;
3045 if ( values.count() > 3 )
3046 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
3049 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
3053 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
3057 else if ( !formatString.isEmpty() )
3059 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
3063 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
3067 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
3073 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
3081 return floatToDegreeFormat( format, values, context, parent, node );
3088 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
3090 return ok ? QVariant( value ) : QVariant();
3096 return floatToDegreeFormat( format, values, context, parent, node );
3101 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3102 return static_cast< int >( decimalDegrees );
3107 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3108 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3109 return static_cast< int >( remainder * 60 );
3114 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3115 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3116 const double remainderInMinutes = remainder * 60;
3117 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
3119 return remainderSecondsFraction * 60;
3124 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3125 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3126 qint64 seconds = d2.secsTo( d1 );
3127 return QVariant::fromValue(
QgsInterval( seconds ) );
3132 if ( !values.at( 0 ).canConvert<QDate>() )
3135 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
3136 if ( !date.isValid() )
3141 return date.dayOfWeek() % 7;
3146 QVariant value = values.at( 0 );
3147 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3150 return QVariant( inter.
days() );
3154 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3155 return QVariant( d1.date().day() );
3161 QVariant value = values.at( 0 );
3162 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3165 return QVariant( inter.
years() );
3169 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3170 return QVariant( d1.date().year() );
3176 QVariant value = values.at( 0 );
3177 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3180 return QVariant( inter.
months() );
3184 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3185 return QVariant( d1.date().month() );
3191 QVariant value = values.at( 0 );
3192 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3195 return QVariant( inter.
weeks() );
3199 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3200 return QVariant( d1.date().weekNumber() );
3206 QVariant value = values.at( 0 );
3207 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3210 return QVariant( inter.
hours() );
3214 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3215 return QVariant( t1.hour() );
3221 QVariant value = values.at( 0 );
3222 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3225 return QVariant( inter.
minutes() );
3229 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3230 return QVariant( t1.minute() );
3236 QVariant value = values.at( 0 );
3237 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3240 return QVariant( inter.
seconds() );
3244 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3245 return QVariant( t1.second() );
3251 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3254 return QVariant( dt.toMSecsSinceEpoch() );
3264 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3266 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3271 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3274 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3277 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3283 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3286 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3295 if ( !dateTime.isValid() )
3300 const int year = dateTime.date().year();
3301 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3302 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3303 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3304 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3305 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3310 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3311 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3314 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3317 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3322 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3327 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3332 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3337 double declination = 0;
3344 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3356 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3357 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3360 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3363 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3368 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3373 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3378 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3383 double inclination = 0;
3390 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3402 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3403 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3406 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3409 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3414 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3419 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3424 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3429 double declination = 0;
3437 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3447 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3453 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3459 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3464 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3471 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3472 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3475 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3478 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3483 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3488 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3493 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3498 double declination = 0;
3506 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3516 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3522 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3528 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3533 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3538#define ENSURE_GEOM_TYPE( f, g, geomtype ) \
3539 if ( !( f ).hasGeometry() ) \
3540 return QVariant(); \
3541 QgsGeometry g = ( f ).geometry(); \
3542 if ( ( g ).type() != ( geomtype ) ) \
3549 if ( g.isMultipart() )
3551 return g.asMultiPoint().at( 0 ).x();
3555 return g.asPoint().x();
3563 if ( g.isMultipart() )
3565 return g.asMultiPoint().at( 0 ).y();
3569 return g.asPoint().y();
3583 if ( g.isEmpty() || !abGeom->
is3D() )
3596 if ( collection->numGeometries() > 0 )
3609 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3615 return QVariant( isValid );
3620 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3624 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3625#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
3630 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3632 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3635 const bool keepCollapsed = values.value( 2 ).toBool();
3640 valid = geom.
makeValid( method, keepCollapsed );
3644 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3648 return QVariant::fromValue( valid );
3653 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3659 for (
int i = 0; i < multiGeom.size(); ++i )
3661 array += QVariant::fromValue( multiGeom.at( i ) );
3669 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3681 QVariant result( centroid.
asPoint().
x() );
3687 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3699 QVariant result( centroid.
asPoint().
y() );
3705 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3723 if ( collection->numGeometries() == 1 )
3736 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3754 if ( collection->numGeometries() == 1 )
3767 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3772 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3799 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3816 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3833 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3838 bool ignoreClosing =
false;
3839 if ( values.length() > 1 )
3841 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3851 bool skipLast =
false;
3852 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3857 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++i )
3869 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3880 for (
int i = 0; i < line->numPoints() - 1; ++i )
3894 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3904 if ( collection->numGeometries() == 1 )
3911 if ( !curvePolygon )
3915 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3921 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3927 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3937 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3943 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3949 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3958 return QVariant::fromValue(
QgsGeometry( boundary ) );
3963 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3972 return QVariant::fromValue( merged );
3977 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3981 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3986 if ( sharedPaths.
isNull() )
3989 return QVariant::fromValue( sharedPaths );
3995 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4000 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4003 if ( simplified.
isNull() )
4011 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4016 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4021 if ( simplified.
isNull() )
4029 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4034 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
4035 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
4036 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4037 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
4039 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
4048 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4053 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4054 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4055 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4066 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4071 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4072 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4073 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4074 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4075 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4086 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4091 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4092 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4093 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4104 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4109 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4110 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4111 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4112 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4113 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4124 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4129 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4130 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4131 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4142 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4147 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4148 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4149 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4150 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4151 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4162 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4167 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4168 QVector< double > dashPattern;
4169 dashPattern.reserve( pattern.size() );
4170 for (
const QVariant &value : std::as_const( pattern ) )
4173 double v = value.toDouble( &ok );
4185 if ( dashPattern.size() % 2 != 0 )
4187 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4191 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4193 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4195 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4197 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4199 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4201 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4205 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4209 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4211 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4213 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4215 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4217 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4219 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4223 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4227 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4229 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4231 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4233 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4237 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4241 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4252 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4257 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4259 if ( densified.
isNull() )
4267 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4272 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4274 if ( densified.
isNull() )
4283 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4285 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4292 QVector< QgsGeometry > parts;
4293 parts.reserve( list.size() );
4294 for (
const QVariant &value : std::as_const( list ) )
4296 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4307 if ( values.count() < 2 || values.count() > 4 )
4309 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4313 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4314 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4315 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4316 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4317 switch ( values.count() )
4331 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4332 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4333 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4339 if ( values.empty() )
4344 QVector<QgsPoint> points;
4345 points.reserve( values.count() );
4347 auto addPoint = [&points](
const QgsGeometry &geom ) {
4361 for (
const QVariant &value : values )
4363 if ( value.userType() == QMetaType::Type::QVariantList )
4365 const QVariantList list = value.toList();
4366 for (
const QVariant &v : list )
4368 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4373 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4377 if ( points.count() < 2 )
4385 if ( values.count() < 1 )
4387 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4391 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4399 auto polygon = std::make_unique< QgsPolygon >();
4413 if ( !exteriorRing )
4416 polygon->setExteriorRing( exteriorRing->
segmentize() );
4419 for (
int i = 1; i < values.count(); ++i )
4421 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4443 polygon->addInteriorRing( ring->
segmentize() );
4446 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4451 auto tr = std::make_unique<QgsTriangle>();
4452 auto lineString = std::make_unique<QgsLineString>();
4453 lineString->clear();
4455 for (
const QVariant &value : values )
4457 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4479 lineString->addVertex( *point );
4482 tr->setExteriorRing( lineString.release() );
4484 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4489 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4496 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4497 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4519 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4524 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4531 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4532 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4533 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4534 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4554 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4555 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4560 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4567 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4574 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4577 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4584 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4623 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4629 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4644 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4650 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4656 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4665 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4689 return QVariant::fromValue( geom.
vertexAt( idx ) );
4697 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4699 const QVariant v = pointAt( geom, idx, parent );
4702 return QVariant( v.value<
QgsPoint>().
x() );
4708 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4710 return fcnOldXat( values, f, parent, node );
4712 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4714 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4717 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4723 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4725 const QVariant v = pointAt( geom, vertexNumber, parent );
4727 return QVariant( v.value<
QgsPoint>().
x() );
4737 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4739 const QVariant v = pointAt( geom, idx, parent );
4742 return QVariant( v.value<
QgsPoint>().
y() );
4748 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4750 return fcnOldYat( values, f, parent, node );
4752 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4754 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4757 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4763 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4765 const QVariant v = pointAt( geom, vertexNumber, parent );
4767 return QVariant( v.value<
QgsPoint>().
y() );
4774 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4780 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4782 const QVariant v = pointAt( geom, vertexNumber, parent );
4784 return QVariant( v.value<
QgsPoint>().
z() );
4791 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4797 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4799 const QVariant v = pointAt( geom, vertexNumber, parent );
4801 return QVariant( v.value<
QgsPoint>().
m() );
4809 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4811 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4817 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4823 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4828 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4835 ogcContext.
layer = mapLayerPtr.data();
4840 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4855 return QVariant( area );
4859 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4871 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4876 return QVariant( geom.
area() );
4890 return QVariant( len );
4894 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4915 return QVariant( len );
4919 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4925 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4931 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4937 return QVariant( geom.
length() );
4942 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4948 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4957 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4966 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4982 if ( !curvePolygon )
4994 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5001 return QVariant( curvePolygon->
ringCount() );
5003 bool foundPoly =
false;
5012 if ( !curvePolygon )
5023 return QVariant( ringCount );
5028 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5030 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
5036 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5042 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5048 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5057 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5063 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5069 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5075 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5081 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5089 double max = std::numeric_limits< double >::lowest();
5093 double z = ( *it ).z();
5099 if ( max == std::numeric_limits< double >::lowest() )
5102 return QVariant( max );
5107 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5115 double min = std::numeric_limits< double >::max();
5119 double z = ( *it ).z();
5125 if ( min == std::numeric_limits< double >::max() )
5128 return QVariant( min );
5133 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5141 double min = std::numeric_limits< double >::max();
5145 double m = ( *it ).m();
5151 if ( min == std::numeric_limits< double >::max() )
5154 return QVariant( min );
5159 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5167 double max = std::numeric_limits< double >::lowest();
5171 double m = ( *it ).m();
5177 if ( max == std::numeric_limits< double >::lowest() )
5180 return QVariant( max );
5185 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5189 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5198 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5202 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5211 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5216 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5226 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5230 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5232 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5237 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5256 return QVariant::fromValue( curve->
isClosed() );
5261 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5274 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5275 closedLine->close();
5277 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5291 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5292 closedLine->close();
5294 closed->addGeometry( closedLine.release() );
5297 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5305 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5309 return QVariant::fromValue( fGeom.
isEmpty() );
5315 return QVariant::fromValue(
true );
5317 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5318 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5323 if ( values.length() < 2 || values.length() > 3 )
5326 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5327 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5334 if ( values.length() == 2 )
5337 QString result = engine->relate( sGeom.
constGet() );
5338 return QVariant::fromValue( result );
5343 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5344 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5345 return QVariant::fromValue( result );
5351 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5352 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5357 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5358 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5359 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5363 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5364 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5365 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5369 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5370 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5371 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5375 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5376 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5377 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5381 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5382 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5383 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5387 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5388 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5389 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5393 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5394 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5395 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5400 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5401 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5407 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5408 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5409 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5414 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5416 QVariant ret = TVL_False;
5419 ret = fGeom.
isExactlyEqual( sGeom, backend ) ? TVL_True : TVL_False;
5430 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5431 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5432 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5437 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5439 QVariant ret = TVL_False;
5453 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5454 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5455 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5460 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5462 double epsilon = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5464 QVariant ret = TVL_False;
5467 ret = fGeom.
isFuzzyEqual( sGeom, epsilon, backend ) ? TVL_True : TVL_False;
5478 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5479 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5480 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5481 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5482 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5483 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5486 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5488 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5492 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5494 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5498 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5504 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5506 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5511 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5513 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5518 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5520 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5525 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5540 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5544 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5545 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5546 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5547 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5550 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5556 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5559 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5563 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5564 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5565 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5568 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5574 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5577 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5581 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5584 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5590 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5591 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5592 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5593 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5594 if ( joinInt < 1 || joinInt > 3 )
5598 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5601 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5607 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5608 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5609 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5611 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5612 if ( joinInt < 1 || joinInt > 3 )
5616 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5619 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5625 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5626 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5627 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5630 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5636 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5637 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5638 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5640 return QVariant::fromValue( fGeom );
5645 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5646 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5648 const bool perPart = values.value( 3 ).toBool();
5655 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5656 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5658 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5659 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5660 t.rotate( -rotation );
5661 t.translate( -partCenter.x(), -partCenter.y() );
5662 ( *it )->transform( t );
5664 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5676 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5684 fGeom.
rotate( rotation, pt );
5685 return QVariant::fromValue( fGeom );
5691 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5692 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5693 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5694 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent ) :
QgsGeometry();
5700 pt = fGeom.boundingBox().center();
5704 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5709 pt = center.asPoint();
5712 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5713 t.scale( xScale, yScale );
5714 t.translate( -pt.
x(), -pt.
y() );
5716 return QVariant::fromValue( fGeom );
5721 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5727 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5728 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5730 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5732 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5733 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5735 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5736 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5737 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5738 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5749 QTransform transform;
5750 transform.translate( deltaX, deltaY );
5751 transform.rotate( rotationZ );
5752 transform.scale( scaleX, scaleY );
5753 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5755 return QVariant::fromValue( fGeom );
5761 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5763 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5768 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5770 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5776 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5777 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5779 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5785 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5787 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5791#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
5796 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5797 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5798 const bool allowHoles = values.value( 2 ).toBool();
5800 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5813 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5815 if ( values.length() == 2 )
5816 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5824 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5830 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5832 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5838 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5844 double area,
angle, width, height;
5857 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5858 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5860 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5871 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5882 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5892 reversed->addGeometry( curve->
reversed() );
5899 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5905 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5906 std::reverse(
string.begin(),
string.end() );
5912 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5932 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5938 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5939 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5940 return QVariant( fGeom.
distance( sGeom ) );
5945 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5946 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5949 if ( values.length() == 3 && values.at( 2 ).isValid() )
5951 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5952 densify = std::clamp( densify, 0.0, 1.0 );
5960 return res > -1 ? QVariant( res ) : QVariant();
5965 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5966 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5968 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5973 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5974 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5976 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5981 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5982 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5984 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5990 if ( values.length() < 1 || values.length() > 2 )
5993 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5995 if ( values.length() == 2 )
5996 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5997 QString wkt = fGeom.
asWkt( prec );
5998 return QVariant( wkt );
6003 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6004 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
6009 if ( values.length() != 2 )
6011 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
6015 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6016 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6044 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
6051 if ( pt1->
y() < pt2->
y() )
6053 else if ( pt1->
y() > pt2->
y() )
6061 if ( pt1->
x() < pt2->
x() )
6063 else if ( pt1->
x() > pt2->
x() )
6064 return M_PI + ( M_PI_2 );
6069 if ( pt1->
x() < pt2->
x() )
6071 if ( pt1->
y() < pt2->
y() )
6073 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
6077 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI_2 );
6083 if ( pt1->
y() > pt2->
y() )
6085 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) ) + M_PI;
6089 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI + ( M_PI_2 ) );
6096 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6097 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6099 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
6103 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
6111 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
6125 if ( ellipsoid.isEmpty() )
6127 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
6133 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
6141 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
6147 const double bearing = da.
bearing( point1, point2 );
6148 if ( std::isfinite( bearing ) )
6150 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
6163 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6171 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6172 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6173 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
6176 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6183 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6184 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6211 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6220 if ( values.length() != 3 )
6223 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6224 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6225 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6229 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6235 if ( values.length() < 2 )
6238 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6241 return values.at( 0 );
6243 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6244 QVariant cachedExpression;
6249 if ( cachedExpression.isValid() )
6256 bool asc = values.value( 2 ).toBool();
6274 Q_ASSERT( collection );
6278 QgsExpressionSorter sorter( orderBy );
6280 QList<QgsFeature> partFeatures;
6281 partFeatures.reserve( collection->
partCount() );
6282 for (
int i = 0; i < collection->
partCount(); ++i )
6288 sorter.sortFeatures( partFeatures, unconstedContext );
6292 Q_ASSERT( orderedGeom );
6297 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6302 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6305 delete unconstedContext;
6312 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6313 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6317 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6323 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6324 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6328 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6334 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6335 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6339 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6345 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6346 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6347 const bool use3DDistance = values.at( 2 ).toBool();
6349 double x, y, z, distance;
6372 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6375 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6395 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6396 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6398 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6400 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6405 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6406 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6413 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6414 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6419 vertex = count + vertex;
6427 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6428 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6433 vertex = count + vertex;
6441 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6442 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6446 return distance >= 0 ? distance : QVariant();
6451 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6452 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6453 const bool use3DDistance = values.at( 2 ).toBool();
6455 double x, y, z, distance;
6464 return found ? distance : QVariant();
6469 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6471 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6472 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6475 if ( values.length() >= 1 )
6477 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6478 return QVariant( qlonglong( std::round( number ) ) );
6493 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6494 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6495 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6502 const bool omitGroupSeparator = values.value( 3 ).toBool();
6503 const bool trimTrailingZeros = values.value( 4 ).toBool();
6505 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6506 if ( !omitGroupSeparator )
6507 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6509 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6511 QString res = locale.toString( value,
'f', places );
6513 if ( trimTrailingZeros )
6515 const QChar decimal = locale.decimalPoint().at( 0 );
6516 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6518 if ( res.contains( decimal ) )
6520 int trimPoint = res.length() - 1;
6522 while ( res.at( trimPoint ) == zeroDigit )
6525 if ( res.at( trimPoint ) == decimal )
6528 res.truncate( trimPoint + 1 );
6537 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6538 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6539 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6542 if ( format.indexOf(
"Z" ) > 0 )
6543 datetime = datetime.toUTC();
6545 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6546 return locale.toString( datetime, format );
6551 const QVariant variant = values.at( 0 );
6553 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6554 if ( !color.isValid() )
6557 const float alpha = color.alphaF();
6558 if ( color.spec() == QColor::Spec::Cmyk )
6560 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() )
6562 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6566 const float avg = ( color.redF() + color.greenF() + color.blueF() )
6568 color.setRgbF( avg, avg, avg, alpha );
6571 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6578 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6583 else if ( ratio < 0 )
6588 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6589 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6590 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6591 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6593 QColor newColor( red, green, blue, alpha );
6600 const QVariant variant1 = values.at( 0 );
6601 const QVariant variant2 = values.at( 1 );
6603 if ( variant1.userType() != variant2.userType() )
6605 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6610 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6611 if ( !color1.isValid() )
6614 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6615 if ( !color2.isValid() )
6618 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6620 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6624 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6630 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6631 if ( color1.spec() == QColor::Spec::Cmyk )
6633 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6634 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6635 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6636 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6637 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6641 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6642 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6643 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6644 newColor = QColor::fromRgbF( red, green, blue, alpha );
6649 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6654 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6655 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6656 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6657 QColor color = QColor( red, green, blue );
6658 if ( !color.isValid() )
6660 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6661 color = QColor( 0, 0, 0 );
6664 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6669 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6670 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6671 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6672 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6673 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6674 if ( !color.isValid() )
6676 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6685 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6686 QVariant value = node->
eval( parent, context );
6690 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6692 value = node->
eval( parent, context );
6700 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6702 QVariant value = node->
eval( parent, context );
6704 if ( value.toBool() )
6706 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6708 value = node->
eval( parent, context );
6713 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6715 value = node->
eval( parent, context );
6723 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6724 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6725 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6726 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6727 QColor color = QColor( red, green, blue, alpha );
6728 if ( !color.isValid() )
6730 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6731 color = QColor( 0, 0, 0 );
6740 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6742 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6747 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6751 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6756 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6757 QColor color = ramp->
color( value );
6770 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6772 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6774 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6776 QColor color = QColor::fromHslF( hue, saturation, lightness );
6778 if ( !color.isValid() )
6780 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6781 color = QColor( 0, 0, 0 );
6784 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6790 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6792 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6794 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6796 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6798 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6799 if ( !color.isValid() )
6801 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6802 color = QColor( 0, 0, 0 );
6809 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6810 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6811 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6812 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6814 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6815 if ( !color.isValid() )
6817 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6827 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6829 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6831 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6833 QColor color = QColor::fromHsvF( hue, saturation, value );
6835 if ( !color.isValid() )
6837 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6838 color = QColor( 0, 0, 0 );
6841 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6847 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6849 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6851 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6853 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6855 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6856 if ( !color.isValid() )
6858 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6859 color = QColor( 0, 0, 0 );
6866 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6867 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6868 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6869 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6870 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6872 if ( !color.isValid() )
6874 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6883 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6884 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6885 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6886 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6887 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6889 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6890 if ( !color.isValid() )
6892 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6902 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6904 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6906 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6908 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6910 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6912 if ( !color.isValid() )
6914 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6915 color = QColor( 0, 0, 0 );
6918 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6924 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6926 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6928 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6930 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6932 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6934 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6935 if ( !color.isValid() )
6937 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6938 color = QColor( 0, 0, 0 );
6945 const QVariant variant = values.at( 0 );
6947 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6948 if ( !color.isValid() )
6951 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6952 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6954 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6955 return color.green();
6956 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6957 return color.blue();
6958 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6959 return color.alpha();
6960 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6961 return static_cast< double >( color.hsvHueF() * 360 );
6962 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6963 return static_cast< double >( color.hsvSaturationF() * 100 );
6964 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6965 return static_cast< double >( color.valueF() * 100 );
6966 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6967 return static_cast< double >( color.hslHueF() * 360 );
6968 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6969 return static_cast< double >( color.hslSaturationF() * 100 );
6970 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6971 return static_cast< double >( color.lightnessF() * 100 );
6972 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6973 return static_cast< double >( color.cyanF() * 100 );
6974 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6975 return static_cast< double >( color.magentaF() * 100 );
6976 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6977 return static_cast< double >( color.yellowF() * 100 );
6978 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6979 return static_cast< double >( color.blackF() * 100 );
6981 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6987 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6990 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
6994 QList< QColor > colors;
6996 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6999 if ( !colors.last().isValid() )
7001 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
7005 double step = it.key().toDouble();
7006 if ( it == map.constBegin() )
7011 else if ( it == map.constEnd() )
7021 bool discrete = values.at( 1 ).toBool();
7023 if ( colors.empty() )
7026 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
7031 const QVariant variant = values.at( 0 );
7033 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7034 if ( !color.isValid() )
7037 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7038 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7039 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7040 color.setRed( std::clamp( value, 0, 255 ) );
7041 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7042 color.setGreen( std::clamp( value, 0, 255 ) );
7043 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7044 color.setBlue( std::clamp( value, 0, 255 ) );
7045 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7046 color.setAlpha( std::clamp( value, 0, 255 ) );
7047 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7048 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
7049 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7050 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
7051 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7052 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7053 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7054 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
7055 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7056 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
7057 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7058 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7059 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7060 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
7061 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7062 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
7063 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7064 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
7065 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7066 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7069 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7072 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7077 const QVariant variant = values.at( 0 );
7079 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7080 if ( !color.isValid() )
7083 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7085 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7090 const QVariant variant = values.at( 0 );
7092 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7093 if ( !color.isValid() )
7096 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7098 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7103 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7106 return QVariant::fromValue( geom );
7112 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7120 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
7125 return QVariant::fromValue( fGeom );
7128 return QVariant::fromValue( fGeom );
7137 return QVariant::fromValue( fGeom );
7150 bool foundLayer =
false;
7151 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7154 if ( !featureSource || !foundLayer )
7159 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
7172 result = QVariant::fromValue( fet );
7180 bool foundLayer =
false;
7181 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7184 if ( !featureSource || !foundLayer )
7189 QString cacheValueKey;
7190 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7192 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7194 QMap<QString, QVariant>::const_iterator i = attributeMap.constBegin();
7195 QString filterString;
7196 for ( ; i != attributeMap.constEnd(); ++i )
7198 if ( !filterString.isEmpty() )
7200 filterString.append(
" AND " );
7204 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7213 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7214 int attributeId = featureSource->fields().lookupField( attribute );
7215 if ( attributeId == -1 )
7220 const QVariant &attVal = values.at( 2 );
7222 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7245 res = QVariant::fromValue( fet );
7260 if ( !values.isEmpty() )
7263 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7264 fieldName = col->
name();
7265 else if ( values.size() == 2 )
7266 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7269 QVariant value = values.at( 0 );
7274 if ( fieldIndex == -1 )
7276 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7282 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7285 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7294 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7312 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7320 const QVariant data = values.at( 0 );
7321 const QMimeDatabase db;
7322 return db.mimeTypeForData( data.toByteArray() ).name();
7327 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7329 bool foundLayer =
false;
7330 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7334 [layerProperty](
QgsMapLayer *layer ) -> QVariant {
7339 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7340 return layer->name();
7341 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7343 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7344 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7345 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7346 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7347 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7349 QStringList keywords;
7350 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7351 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7353 keywords.append( it.value() );
7355 if ( !keywords.isEmpty() )
7357 return layer->serverProperties()->keywordList();
7359 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7361 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7363 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7365 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7367 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7369 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7371 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7373 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7375 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7377 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7379 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7381 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7383 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7386 QVariant result = QVariant::fromValue( extentGeom );
7389 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7391 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7394 return decodedUri.value( u
"path"_s );
7396 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7398 switch ( layer->
type() )
7401 return QCoreApplication::translate(
"expressions",
"Vector" );
7403 return QCoreApplication::translate(
"expressions",
"Raster" );
7405 return QCoreApplication::translate(
"expressions",
"Mesh" );
7407 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
7409 return QCoreApplication::translate(
"expressions",
"Plugin" );
7411 return QCoreApplication::translate(
"expressions",
"Annotation" );
7413 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
7415 return QCoreApplication::translate(
"expressions",
"Group" );
7417 return QCoreApplication::translate(
"expressions",
"Tiled Scene" );
7423 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7426 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7428 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7430 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7448 const QString uriPart = values.at( 1 ).toString();
7450 bool foundLayer =
false;
7452 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7456 [parent, uriPart](
QgsMapLayer *layer ) -> QVariant {
7457 if ( !layer->dataProvider() )
7459 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7465 if ( !uriPart.isNull() )
7467 return decodedUri.value( uriPart );
7479 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7490 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7491 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7493 bool foundLayer =
false;
7494 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7498 [parent, band, layerProperty](
QgsMapLayer *layer ) -> QVariant {
7499 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7503 if ( band < 1 || band > rl->bandCount() )
7505 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7511 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7513 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7515 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7517 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7519 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7521 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7525 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7555 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7572 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7573 bool ascending = values.value( 1 ).toBool();
7574 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7580 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7585 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7590 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7595 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7596 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7598 for (
const auto &item : listB )
7600 if ( listA.contains( item ) )
7604 return QVariant( match == listB.count() );
7609 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7614 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7615 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7616 if ( pos < list.length() && pos >= 0 )
7617 return list.at( pos );
7618 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7619 return list.at( list.length() + pos );
7625 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7626 return list.value( 0 );
7631 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7632 return list.value( list.size() - 1 );
7637 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7638 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7643 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7644 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7649 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7652 for (
const QVariant &item : list )
7654 switch ( item.userType() )
7656 case QMetaType::Int:
7657 case QMetaType::UInt:
7658 case QMetaType::LongLong:
7659 case QMetaType::ULongLong:
7660 case QMetaType::Float:
7661 case QMetaType::Double:
7662 total += item.toDouble();
7667 return i == 0 ? QVariant() : total / i;
7672 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7673 QVariantList numbers;
7674 for (
const auto &item : list )
7676 switch ( item.userType() )
7678 case QMetaType::Int:
7679 case QMetaType::UInt:
7680 case QMetaType::LongLong:
7681 case QMetaType::ULongLong:
7682 case QMetaType::Float:
7683 case QMetaType::Double:
7684 numbers.append( item );
7688 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7689 const int count = numbers.count();
7694 else if ( count % 2 )
7696 return numbers.at( count / 2 );
7700 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7706 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7709 for (
const QVariant &item : list )
7711 switch ( item.userType() )
7713 case QMetaType::Int:
7714 case QMetaType::UInt:
7715 case QMetaType::LongLong:
7716 case QMetaType::ULongLong:
7717 case QMetaType::Float:
7718 case QMetaType::Double:
7719 total += item.toDouble();
7724 return i == 0 ? QVariant() : total;
7727static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7729 QVariant result = value;
7730 ( void ) result.convert(
static_cast<int>( type ) );
7736 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7737 QHash< QVariant, int > hash;
7738 for (
const auto &item : list )
7742 const QList< int > occurrences = hash.values();
7743 if ( occurrences.empty() )
7744 return QVariantList();
7746 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7748 const QString option = values.at( 1 ).toString();
7749 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7751 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7753 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7755 if ( hash.isEmpty() )
7758 return QVariant( hash.key( maxValue ) );
7760 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7762 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7764 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7766 if ( maxValue * 2 <= list.size() )
7769 return QVariant( hash.key( maxValue ) );
7780 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7781 QHash< QVariant, int > hash;
7782 for (
const auto &item : list )
7786 const QList< int > occurrences = hash.values();
7787 if ( occurrences.empty() )
7788 return QVariantList();
7790 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7792 const QString option = values.at( 1 ).toString();
7793 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7795 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7797 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7799 if ( hash.isEmpty() )
7802 return QVariant( hash.key( minValue ) );
7804 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7806 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7808 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7810 if ( hash.isEmpty() )
7814 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7815 if ( maxValue * 2 > list.size() )
7816 hash.remove( hash.key( maxValue ) );
7818 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7829 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7830 list.append( values.at( 1 ) );
7831 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7836 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7837 list.prepend( values.at( 1 ) );
7838 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7843 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7844 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7845 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7850 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7851 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7853 position = position + list.length();
7854 if ( position >= 0 && position < list.length() )
7855 list.removeAt( position );
7856 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7864 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7866 const QVariant toRemove = values.at( 1 );
7869 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant &element ) { return QgsVariantUtils::isNull( element ); } ), list.end() );
7873 list.removeAll( toRemove );
7875 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7880 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7882 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7884 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7885 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7887 int index = list.indexOf( it.key() );
7888 while ( index >= 0 )
7890 list.replace( index, it.value() );
7891 index = list.indexOf( it.key() );
7895 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7897 else if ( values.count() == 3 )
7899 QVariantList before;
7901 bool isSingleReplacement =
false;
7903 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7905 before = QVariantList() << values.at( 1 );
7909 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7912 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7914 after = QVariantList() << values.at( 2 );
7915 isSingleReplacement =
true;
7919 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7922 if ( !isSingleReplacement && before.length() != after.length() )
7924 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7928 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7929 for (
int i = 0; i < before.length(); i++ )
7931 int index = list.indexOf( before.at( i ) );
7932 while ( index >= 0 )
7934 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7935 index = list.indexOf( before.at( i ) );
7939 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7943 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7950 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7951 QVariantList list_new;
7953 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
7955 while ( list.removeOne( cur ) )
7957 list_new.append( cur );
7961 list_new.append( list );
7963 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7969 for (
const QVariant &cur : values )
7971 list += QgsExpressionUtils::getListValue( cur, parent );
7973 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7978 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7979 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7980 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7981 int slice_length = 0;
7983 if ( start_pos < 0 )
7985 start_pos = list.length() + start_pos;
7989 slice_length = end_pos - start_pos + 1;
7993 slice_length = list.length() + end_pos - start_pos + 1;
7996 if ( slice_length < 0 )
8000 list = list.mid( start_pos, slice_length );
8006 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8007 std::reverse( list.begin(), list.end() );
8013 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8014 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
8015 for (
const QVariant &cur : array2 )
8017 if ( array1.contains( cur ) )
8018 return QVariant(
true );
8020 return QVariant(
false );
8025 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8027 QVariantList distinct;
8029 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8031 if ( !distinct.contains( *it ) )
8033 distinct += ( *it );
8042 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8043 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8044 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8048 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8050 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
8051 if ( it != ( array.constEnd() - 1 ) )
8057 return QVariant( str );
8062 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8063 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8064 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8066 QStringList list = str.split( delimiter );
8069 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
8071 array += ( !( *it ).isEmpty() ) ? *it : empty;
8079 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8080 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
8081 if ( document.isNull() )
8084 return document.toVariant();
8090 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
8091 return QString( document.toJson( QJsonDocument::Compact ) );
8096 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8097 if ( str.isEmpty() )
8098 return QVariantMap();
8099 str = str.trimmed();
8106 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8113 for (
int i = 0; i + 1 < values.length(); i += 2 )
8115 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
8122 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8123 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8124 QVariantMap resultMap;
8126 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8128 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
8136 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
8141 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
8146 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8147 map.remove( values.at( 1 ).toString() );
8153 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8154 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
8161 for (
const QVariant &cur : values )
8163 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
8164 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
8165 result.insert( it.key(), it.value() );
8172 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
8177 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
8182 const QString envVarName = values.at( 0 ).toString();
8183 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
8186 return QProcessEnvironment::systemEnvironment().value( envVarName );
8191 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8194 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
8197 return QFileInfo( file ).completeBaseName();
8202 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8205 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8208 return QFileInfo( file ).completeSuffix();
8213 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8216 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8219 return QFileInfo::exists( file );
8224 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8227 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8230 return QFileInfo( file ).fileName();
8235 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8238 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8241 return QFileInfo( file ).isFile();
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(
"is_directory"_L1 ) );
8252 return QFileInfo( file ).isDir();
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_path"_L1 ) );
8263 return QDir::toNativeSeparators( QFileInfo( file ).path() );
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_size"_L1 ) );
8274 return QFileInfo( file ).size();
8277static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8279 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8285 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8286 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8288 if ( method ==
"md4"_L1 )
8290 hash = fcnHash( str, QCryptographicHash::Md4 );
8292 else if ( method ==
"md5"_L1 )
8294 hash = fcnHash( str, QCryptographicHash::Md5 );
8296 else if ( method ==
"sha1"_L1 )
8298 hash = fcnHash( str, QCryptographicHash::Sha1 );
8300 else if ( method ==
"sha224"_L1 )
8302 hash = fcnHash( str, QCryptographicHash::Sha224 );
8304 else if ( method ==
"sha256"_L1 )
8306 hash = fcnHash( str, QCryptographicHash::Sha256 );
8308 else if ( method ==
"sha384"_L1 )
8310 hash = fcnHash( str, QCryptographicHash::Sha384 );
8312 else if ( method ==
"sha512"_L1 )
8314 hash = fcnHash( str, QCryptographicHash::Sha512 );
8316 else if ( method ==
"sha3_224"_L1 )
8318 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8320 else if ( method ==
"sha3_256"_L1 )
8322 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8324 else if ( method ==
"sha3_384"_L1 )
8326 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8328 else if ( method ==
"sha3_512"_L1 )
8330 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8332 else if ( method ==
"keccak_224"_L1 )
8334 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8336 else if ( method ==
"keccak_256"_L1 )
8338 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8340 else if ( method ==
"keccak_384"_L1 )
8342 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8344 else if ( method ==
"keccak_512"_L1 )
8346 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8350 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8357 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8362 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8367 const QByteArray input = values.at( 0 ).toByteArray();
8368 return QVariant( QString( input.toBase64() ) );
8373 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8375 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8377 query.addQueryItem( it.key(), it.value().toString() );
8379 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8384 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8385 const QByteArray base64 = value.toLocal8Bit();
8386 const QByteArray decoded = QByteArray::fromBase64( base64 );
8387 return QVariant( decoded );
8393static QVariant executeGeomOverlay(
8394 const QVariantList &values,
8398 bool invert =
false,
8399 double bboxGrow = 0,
8400 bool isNearestFunc =
false,
8401 bool isIntersectsFunc =
false
8406 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8410 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8413 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8422 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8425 const bool layerCanBeCached = node->
isStatic( parent, context );
8426 QVariant targetLayerValue = node->
eval( parent, context );
8430 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8432 QString subExpString = node->dump();
8434 bool testOnly = ( subExpString ==
"NULL" );
8437 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8441 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8446 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8448 QString filterString = node->dump();
8449 if ( filterString !=
"NULL" )
8451 request.setFilterExpression( filterString );
8455 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8457 QVariant limitValue = node->eval( parent, context );
8459 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8461 double max_distance = 0;
8462 bool cacheEnabled =
false;
8464 double minOverlap { -1 };
8465 double minInscribedCircleRadius { -1 };
8466 bool returnDetails =
false;
8467 bool sortByMeasure =
false;
8468 bool sortAscending =
false;
8469 bool requireMeasures =
false;
8470 bool overlapOrRadiusFilter =
false;
8474 if ( isNearestFunc )
8477 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8479 QVariant distanceValue = node->eval( parent, context );
8481 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8484 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8486 QVariant cacheValue = node->eval( parent, context );
8488 cacheEnabled = cacheValue.toBool();
8493 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8495 QVariant cacheValue = node->eval( parent, context );
8497 cacheEnabled = cacheValue.toBool();
8500 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8502 const QVariant minOverlapValue = node->eval( parent, context );
8504 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8507 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8509 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8511 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8514 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8516 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8519 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8521 const QString sorting { node->eval( parent, context ).toString().toLower() };
8522 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8523 sortAscending = sorting.startsWith(
"asc" );
8524 requireMeasures = sortByMeasure || returnDetails;
8525 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8528 node = QgsExpressionUtils::getNode( values.at( 9 ), parent );
8530 const QString backendStr = node->eval( parent, context ).toString().toUpper();
8536 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
8542 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8545 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8548 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8551 if ( bboxGrow != 0 )
8553 intDomain.
grow( bboxGrow );
8556 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8562 QList<QgsFeature> features;
8563 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8567 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8568 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8572 cachedTarget = targetLayer->
materialize( request );
8573 if ( layerCanBeCached )
8574 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8584 if ( layerCanBeCached )
8585 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8592 QList<QgsFeatureId> fidsList;
8593 if ( isNearestFunc )
8595 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8599 fidsList = spatialIndex.
intersects( intDomain );
8602 QListIterator<QgsFeatureId> i( fidsList );
8603 while ( i.hasNext() )
8606 if ( sameLayers && feat.
id() == fId2 )
8608 features.append( cachedTarget->
getFeature( fId2 ) );
8615 request.setFilterRect( intDomain );
8620 if ( sameLayers && feat.
id() == feat2.
id() )
8622 features.append( feat2 );
8630 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8631 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8637 subExpression.
prepare( &subContext );
8650 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double &overlapValue ) ->
bool {
8651 bool testResult {
false };
8653 QVector<double> overlapValues;
8654 const QgsGeometry merged { intersection.mergeLines() };
8659 if ( minOverlap != -1 || requireMeasures )
8661 overlapValue = geom->
length();
8662 overlapValues.append( overlapValue );
8663 if ( minOverlap != -1 )
8665 if ( overlapValue >= minOverlap )
8677 if ( !overlapValues.isEmpty() )
8679 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8686 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double &radiusValue,
double &overlapValue ) ->
bool {
8688 bool testResult {
false };
8690 QVector<double> overlapValues;
8691 QVector<double> radiusValues;
8692 for (
auto it = intersection.const_parts_begin(); ( !testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8696 if ( minOverlap != -1 || requireMeasures )
8698 overlapValue = geom->
area();
8699 overlapValues.append( geom->
area() );
8700 if ( minOverlap != -1 )
8702 if ( overlapValue >= minOverlap )
8714 if ( minInscribedCircleRadius != -1 || requireMeasures )
8717 const double width = bbox.
width();
8718 const double height = bbox.
height();
8719 const double size = width > height ? width : height;
8720 const double tolerance = size / 100.0;
8722 testResult = radiusValue >= minInscribedCircleRadius;
8723 radiusValues.append( radiusValues );
8728 if ( !radiusValues.isEmpty() )
8730 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8733 if ( !overlapValues.isEmpty() )
8735 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8744 QVariantList results;
8746 QListIterator<QgsFeature> i( features );
8749 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8754 if ( relationFunction( geometry, feat2.
geometry(), values, backend ) )
8756 double overlapValue = -1;
8757 double radiusValue = -1;
8759 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8771 for (
const auto &geom : std::as_const( geometries ) )
8773 switch ( geom.type() )
8777 poly.append( geom.asPolygon() );
8782 line.append( geom.asPolyline() );
8787 point.append( geom.asPoint() );
8798 switch ( geometry.
type() )
8826 switch ( intersection.
type() )
8831 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8833 if ( !testResult && overlapOrRadiusFilter )
8845 if ( minInscribedCircleRadius != -1 )
8851 const bool testResult { testLinestring( intersection, overlapValue ) };
8853 if ( !testResult && overlapOrRadiusFilter )
8865 if ( minInscribedCircleRadius != -1 )
8870 bool testResult {
false };
8871 if ( minOverlap != -1 || requireMeasures )
8891 testResult = testLinestring( feat2.
geometry(), overlapValue );
8896 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8902 if ( !testResult && overlapOrRadiusFilter )
8929 const QVariant expResult = subExpression.
evaluate( &subContext );
8931 if ( requireMeasures )
8933 QVariantMap resultRecord;
8934 resultRecord.insert( u
"id"_s, feat2.
id() );
8935 resultRecord.insert( u
"result"_s, expResult );
8937 resultRecord.insert( u
"overlap"_s, overlapValue );
8939 if ( radiusValue != -1 )
8941 resultRecord.insert( u
"radius"_s, radiusValue );
8943 results.append( resultRecord );
8947 results.append( expResult );
8953 results.append( feat2.
id() );
8973 if ( requireMeasures )
8975 if ( sortByMeasure )
8977 std::sort( results.begin(), results.end(), [sortAscending](
const QVariant &recordA,
const QVariant &recordB ) ->
bool {
8978 return sortAscending ? recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
8979 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
8983 if ( limit > 0 && results.size() > limit )
8985 results.erase( results.begin() + limit );
8988 if ( !returnDetails )
8990 QVariantList expResults;
8991 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
8993 expResults.append( it->toMap().value( u
"result"_s ) );
9003 QVariantList disjoint_results;
9012 if ( !results.contains( feat2.
id() ) )
9015 disjoint_results.append( subExpression.
evaluate( &subContext ) );
9018 return disjoint_results;
9026 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
false,
true );
9032 return executeGeomOverlay( values, context, parent, geomFunction );
9038 return executeGeomOverlay( values, context, parent, geomFunction );
9046 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9054 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9062 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9068 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 10 ), parent );
9070 QVariant epsilonValue = node->
eval( parent, context );
9072 double epsilon = QgsExpressionUtils::getDoubleValue( epsilonValue, parent );
9075 return geometry.
isFuzzyEqual( other, epsilon, backend );
9077 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9083 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9089 return executeGeomOverlay( values, context, parent, geomFunction );
9095 return executeGeomOverlay( values, context, parent, geomFunction,
true, 0,
false,
true );
9103 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
true );
9112 QMutexLocker locker( &sFunctionsMutex );
9114 QList<QgsExpressionFunction *> &functions = *sFunctions();
9116 if ( functions.isEmpty() )
9119 << QgsExpressionFunction::Parameter( u
"expression"_s )
9120 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
9121 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
9124 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true ) << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9127 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9133 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnAzimuth, u
"GeometryGroup"_s )
9134 <<
new QgsStaticExpressionFunction(
9137 << QgsExpressionFunction::Parameter( u
"point_a"_s )
9138 << QgsExpressionFunction::Parameter( u
"point_b"_s )
9139 << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() )
9140 << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ),
9144 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnInclination, u
"GeometryGroup"_s )
9145 <<
new QgsStaticExpressionFunction(
9148 << QgsExpressionFunction::Parameter( u
"point"_s )
9149 << QgsExpressionFunction::Parameter( u
"distance"_s )
9150 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9151 << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ),
9162 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
9166 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
9167 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
9169 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction(
9171 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9176 functions << randFunc;
9178 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction(
9181 << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 )
9182 << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 )
9183 << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9188 functions << randfFunc;
9191 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9192 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9193 <<
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 )
9194 <<
new QgsStaticExpressionFunction(
9197 << QgsExpressionFunction::Parameter( u
"value"_s )
9198 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9199 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9200 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9201 << QgsExpressionFunction::Parameter( u
"range_max"_s ),
9205 <<
new QgsStaticExpressionFunction(
9206 u
"scale_polynomial"_s,
9208 << QgsExpressionFunction::Parameter( u
"value"_s )
9209 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9210 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9211 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9212 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9213 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9220 QStringList() << u
"scale_exp"_s
9222 <<
new QgsStaticExpressionFunction(
9223 u
"scale_exponential"_s,
9225 << QgsExpressionFunction::Parameter( u
"value"_s )
9226 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9227 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9228 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9229 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9230 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9231 fcnExponentialScale,
9234 <<
new QgsStaticExpressionFunction(
9235 u
"scale_cubic_bezier"_s,
9237 << QgsExpressionFunction::Parameter( u
"value"_s )
9238 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9239 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9240 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9241 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9242 << QgsExpressionFunction::Parameter( u
"x1"_s )
9243 << QgsExpressionFunction::Parameter( u
"y1"_s )
9244 << QgsExpressionFunction::Parameter( u
"x2"_s )
9245 << QgsExpressionFunction::Parameter( u
"y2"_s ),
9246 fcnCubicBezierScale,
9251 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
9252 <<
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 )
9253 <<
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 )
9254 <<
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 )
9255 <<
new QgsStaticExpressionFunction(
9259 QStringList() << u
"Conversions"_s << u
"String"_s,
9264 QStringList() << u
"tostring"_s
9266 <<
new QgsStaticExpressionFunction(
9269 << QgsExpressionFunction::Parameter( u
"value"_s )
9270 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9271 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9273 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9278 QStringList() << u
"todatetime"_s
9280 <<
new QgsStaticExpressionFunction(
9283 << QgsExpressionFunction::Parameter( u
"value"_s )
9284 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9285 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9287 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9292 QStringList() << u
"todate"_s
9294 <<
new QgsStaticExpressionFunction(
9297 << QgsExpressionFunction::Parameter( u
"value"_s )
9298 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9299 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9301 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9306 QStringList() << u
"totime"_s
9308 <<
new QgsStaticExpressionFunction(
9312 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9317 QStringList() << u
"tointerval"_s
9319 <<
new QgsStaticExpressionFunction(
9322 << QgsExpressionFunction::Parameter( u
"value"_s )
9323 << QgsExpressionFunction::Parameter( u
"axis"_s )
9324 << QgsExpressionFunction::Parameter( u
"precision"_s )
9325 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9332 QStringList() << u
"todm"_s
9334 <<
new QgsStaticExpressionFunction(
9337 << QgsExpressionFunction::Parameter( u
"value"_s )
9338 << QgsExpressionFunction::Parameter( u
"axis"_s )
9339 << QgsExpressionFunction::Parameter( u
"precision"_s )
9340 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9341 fcnToDegreeMinuteSecond,
9347 QStringList() << u
"todms"_s
9349 <<
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 )
9350 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
9351 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
9352 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
9353 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9354 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
9355 <<
new QgsStaticExpressionFunction(
9358 << QgsExpressionFunction::Parameter( u
"condition"_s )
9359 << QgsExpressionFunction::Parameter( u
"result_when_true"_s )
9360 << QgsExpressionFunction::Parameter( u
"result_when_false"_s ),
9368 <<
new QgsStaticExpressionFunction(
9379 <<
new QgsStaticExpressionFunction(
9382 << QgsExpressionFunction::Parameter( u
"layer"_s )
9383 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9384 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9385 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9386 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9387 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9397 if ( !node->
args() )
9400 QSet<QString> referencedVars;
9403 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9409 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9412 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
9420 if ( !node->
args() )
9421 return QSet<QString>();
9423 QSet<QString> referencedCols;
9424 QSet<QString> referencedVars;
9428 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9434 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9439 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
9442 return referencedCols;
9447 <<
new QgsStaticExpressionFunction(
9448 u
"relation_aggregate"_s,
9450 << QgsExpressionFunction::Parameter( u
"relation"_s )
9451 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9452 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9453 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9454 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9455 fcnAggregateRelation,
9463 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9464 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9465 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9466 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9467 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9468 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9469 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9470 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9471 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9472 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9473 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9474 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9475 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9476 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9477 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9478 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9479 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9480 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9481 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9482 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9483 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9485 <<
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 )
9486 <<
new QgsStaticExpressionFunction(
9487 u
"regexp_matches"_s,
9489 << QgsExpressionFunction::Parameter( u
"string"_s )
9490 << QgsExpressionFunction::Parameter( u
"regex"_s )
9491 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
9496 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9497 <<
new QgsStaticExpressionFunction( u
"age"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime1"_s ) << QgsExpressionFunction::Parameter( u
"datetime2"_s ), fcnAge, u
"Date and Time"_s )
9506 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9507 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9508 <<
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 )
9509 <<
new QgsStaticExpressionFunction(
9511 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hour"_s ) << QgsExpressionFunction::Parameter( u
"minute"_s ) << QgsExpressionFunction::Parameter( u
"second"_s ),
9515 <<
new QgsStaticExpressionFunction(
9518 << QgsExpressionFunction::Parameter( u
"year"_s )
9519 << QgsExpressionFunction::Parameter( u
"month"_s )
9520 << QgsExpressionFunction::Parameter( u
"day"_s )
9521 << QgsExpressionFunction::Parameter( u
"hour"_s )
9522 << QgsExpressionFunction::Parameter( u
"minute"_s )
9523 << QgsExpressionFunction::Parameter( u
"second"_s ),
9527 <<
new QgsStaticExpressionFunction(
9530 << QgsExpressionFunction::Parameter( u
"years"_s,
true, 0 )
9531 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9532 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9533 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9534 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9535 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9536 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9540 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9541 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9542 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9543 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9544 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9546 <<
new QgsStaticExpressionFunction(
9549 << QgsExpressionFunction::Parameter( u
"string"_s )
9550 << QgsExpressionFunction::Parameter( u
"substring"_s )
9551 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9558 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9559 <<
new QgsStaticExpressionFunction( u
"ltrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9560 <<
new QgsStaticExpressionFunction( u
"rtrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9561 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9562 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9563 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9567 <<
new QgsStaticExpressionFunction(
9570 << QgsExpressionFunction::Parameter( u
"text"_s )
9571 << QgsExpressionFunction::Parameter( u
"length"_s )
9572 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ),
9576 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9577 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9578 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s ) }, fcnRepeat, u
"String"_s )
9579 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9580 <<
new QgsStaticExpressionFunction(
9581 u
"regexp_replace"_s,
9582 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"replacement"_s ),
9586 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9587 <<
new QgsStaticExpressionFunction(
9589 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ),
9599 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9600 <<
new QgsStaticExpressionFunction( u
"concat_ws"_s, -1, fcnConcatWs, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9601 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9602 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9603 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9604 <<
new QgsStaticExpressionFunction( u
"rpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnRPad, u
"String"_s )
9605 <<
new QgsStaticExpressionFunction( u
"lpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnLPad, u
"String"_s )
9606 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9607 <<
new QgsStaticExpressionFunction(
9610 << QgsExpressionFunction::Parameter( u
"number"_s )
9611 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9612 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9613 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9614 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ),
9618 <<
new QgsStaticExpressionFunction(
9621 << QgsExpressionFunction::Parameter( u
"datetime"_s )
9622 << QgsExpressionFunction::Parameter( u
"format"_s )
9623 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9625 QStringList() << u
"String"_s << u
"Date and Time"_s
9627 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9628 <<
new QgsStaticExpressionFunction(
9630 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9634 <<
new QgsStaticExpressionFunction(
9636 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9640 <<
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 )
9641 <<
new QgsStaticExpressionFunction(
9644 << QgsExpressionFunction::Parameter( u
"red"_s )
9645 << QgsExpressionFunction::Parameter( u
"green"_s )
9646 << QgsExpressionFunction::Parameter( u
"blue"_s )
9647 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9651 <<
new QgsStaticExpressionFunction(
9654 << QgsExpressionFunction::Parameter( u
"red"_s )
9655 << QgsExpressionFunction::Parameter( u
"green"_s )
9656 << QgsExpressionFunction::Parameter( u
"blue"_s )
9657 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9663 <<
new QgsStaticExpressionFunction( u
"create_ramp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ), fcnCreateRamp, u
"Color"_s )
9664 <<
new QgsStaticExpressionFunction(
9666 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9670 <<
new QgsStaticExpressionFunction(
9673 << QgsExpressionFunction::Parameter( u
"hue"_s )
9674 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9675 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9676 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9680 <<
new QgsStaticExpressionFunction(
9683 << QgsExpressionFunction::Parameter( u
"hue"_s )
9684 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9685 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9686 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9690 <<
new QgsStaticExpressionFunction(
9692 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9696 <<
new QgsStaticExpressionFunction(
9699 << QgsExpressionFunction::Parameter( u
"hue"_s )
9700 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9701 << QgsExpressionFunction::Parameter( u
"value"_s )
9702 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9706 <<
new QgsStaticExpressionFunction(
9709 << QgsExpressionFunction::Parameter( u
"hue"_s )
9710 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9711 << QgsExpressionFunction::Parameter( u
"value"_s )
9712 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9716 <<
new QgsStaticExpressionFunction(
9719 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9720 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9721 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9722 << QgsExpressionFunction::Parameter( u
"black"_s ),
9726 <<
new QgsStaticExpressionFunction(
9729 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9730 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9731 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9732 << QgsExpressionFunction::Parameter( u
"black"_s )
9733 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9737 <<
new QgsStaticExpressionFunction(
9740 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9741 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9742 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9743 << QgsExpressionFunction::Parameter( u
"black"_s )
9744 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9748 <<
new QgsStaticExpressionFunction( u
"color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ), fncColorPart, u
"Color"_s )
9749 <<
new QgsStaticExpressionFunction( u
"darker"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncDarker, u
"Color"_s )
9750 <<
new QgsStaticExpressionFunction( u
"lighter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncLighter, u
"Color"_s )
9751 <<
new QgsStaticExpressionFunction(
9752 u
"set_color_part"_s,
9753 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9759 <<
new QgsStaticExpressionFunction( u
"base_file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnBaseFileName, u
"Files and Paths"_s )
9760 <<
new QgsStaticExpressionFunction( u
"file_suffix"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSuffix, u
"Files and Paths"_s )
9761 <<
new QgsStaticExpressionFunction( u
"file_exists"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileExists, u
"Files and Paths"_s )
9762 <<
new QgsStaticExpressionFunction( u
"file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileName, u
"Files and Paths"_s )
9763 <<
new QgsStaticExpressionFunction( u
"is_file"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsFile, u
"Files and Paths"_s )
9764 <<
new QgsStaticExpressionFunction( u
"is_directory"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsDir, u
"Files and Paths"_s )
9765 <<
new QgsStaticExpressionFunction( u
"file_path"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFilePath, u
"Files and Paths"_s )
9766 <<
new QgsStaticExpressionFunction( u
"file_size"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSize, u
"Files and Paths"_s )
9768 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ), fcnExif, u
"Files and Paths"_s )
9769 <<
new QgsStaticExpressionFunction( u
"exif_geotag"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnExifGeoTag, u
"GeometryGroup"_s )
9772 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ), fcnGenericHash, u
"Conversions"_s )
9778 <<
new QgsStaticExpressionFunction( u
"from_base64"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnFromBase64, u
"Conversions"_s )
9781 <<
new QgsStaticExpressionFunction(
9782 u
"magnetic_declination"_s,
9784 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9785 << QgsExpressionFunction::Parameter( u
"date"_s )
9786 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9787 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9788 << QgsExpressionFunction::Parameter( u
"height"_s )
9789 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9790 fcnMagneticDeclination,
9793 <<
new QgsStaticExpressionFunction(
9794 u
"magnetic_inclination"_s,
9796 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9797 << QgsExpressionFunction::Parameter( u
"date"_s )
9798 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9799 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9800 << QgsExpressionFunction::Parameter( u
"height"_s )
9801 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9802 fcnMagneticInclination,
9805 <<
new QgsStaticExpressionFunction(
9806 u
"magnetic_declination_rate_of_change"_s,
9808 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9809 << QgsExpressionFunction::Parameter( u
"date"_s )
9810 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9811 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9812 << QgsExpressionFunction::Parameter( u
"height"_s )
9813 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9814 fcnMagneticDeclinationRateOfChange,
9817 <<
new QgsStaticExpressionFunction(
9818 u
"magnetic_inclination_rate_of_change"_s,
9820 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9821 << QgsExpressionFunction::Parameter( u
"date"_s )
9822 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9823 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9824 << QgsExpressionFunction::Parameter( u
"height"_s )
9825 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9826 fcnMagneticInclinationRateOfChange,
9833 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9835 functions << geomFunc;
9837 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9839 functions << areaFunc;
9841 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9843 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9845 functions << lengthFunc;
9847 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9849 functions << perimeterFunc;
9851 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9853 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnRoundness, u
"GeometryGroup"_s );
9855 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9859 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9863 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9867 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions {
9868 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9869 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9870 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9871 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9872 { u
"overlay_equals_exact"_s, fcnGeomOverlayEqualsExact },
9873 { u
"overlay_equals_topological"_s, fcnGeomOverlayEqualsTopological },
9874 { u
"overlay_equals_fuzzy"_s, fcnGeomOverlayEqualsFuzzy },
9875 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9876 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9877 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9879 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9880 while ( i.hasNext() )
9883 QString defaultBackend = i.key() ==
"overlay_equals"_L1 ? QString(
"QGIS" ) : QString(
"GEOS" );
9884 QgsStaticExpressionFunction *fcnGeomOverlayFunc =
new QgsStaticExpressionFunction(
9887 << QgsExpressionFunction::Parameter( u
"layer"_s )
9888 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9889 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9890 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9891 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9892 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9893 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9894 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9895 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false )
9896 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, defaultBackend,
false )
9897 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4,
false ),
9908 functions << fcnGeomOverlayFunc;
9911 QgsStaticExpressionFunction *fcnGeomOverlayNearestFunc =
new QgsStaticExpressionFunction(
9912 u
"overlay_nearest"_s,
9914 << QgsExpressionFunction::Parameter( u
"layer"_s )
9915 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9916 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9917 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9918 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9919 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9920 fcnGeomOverlayNearest,
9929 functions << fcnGeomOverlayNearestFunc;
9932 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9937 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9938 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9939 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9940 <<
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 )
9941 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9942 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9943 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9944 <<
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 )
9945 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
9946 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
9947 <<
new QgsStaticExpressionFunction(
9949 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ) << QgsExpressionFunction::Parameter( u
"point3"_s ),
9953 <<
new QgsStaticExpressionFunction(
9956 << QgsExpressionFunction::Parameter( u
"center"_s )
9957 << QgsExpressionFunction::Parameter( u
"radius"_s )
9958 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9962 <<
new QgsStaticExpressionFunction(
9965 << QgsExpressionFunction::Parameter( u
"center"_s )
9966 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
9967 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
9968 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9969 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9973 <<
new QgsStaticExpressionFunction(
9974 u
"make_regular_polygon"_s,
9976 << QgsExpressionFunction::Parameter( u
"center"_s )
9977 << QgsExpressionFunction::Parameter( u
"radius"_s )
9978 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
9979 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
9980 fcnMakeRegularPolygon,
9983 <<
new QgsStaticExpressionFunction( u
"make_square"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnMakeSquare, u
"GeometryGroup"_s )
9984 <<
new QgsStaticExpressionFunction(
9985 u
"make_rectangle_3points"_s,
9987 << QgsExpressionFunction::Parameter( u
"point1"_s )
9988 << QgsExpressionFunction::Parameter( u
"point2"_s )
9989 << QgsExpressionFunction::Parameter( u
"point3"_s )
9990 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
9991 fcnMakeRectangleFrom3Points,
9994 <<
new QgsStaticExpressionFunction(
9997 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9998#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
9999 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
10001 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
10003 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
10010 <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
10012 <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
10014 <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
10016 <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
10018 QgsStaticExpressionFunction *xAtFunc
10019 =
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 );
10021 functions << xAtFunc;
10024 QgsStaticExpressionFunction *yAtFunc
10025 =
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 );
10027 functions << yAtFunc;
10030 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
10031 <<
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 )
10032 <<
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 )
10033 <<
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 )
10034 <<
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 )
10035 <<
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 )
10036 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10037 <<
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 )
10038 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
10039 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
10040 <<
new QgsStaticExpressionFunction(
10041 u
"intersects_bbox"_s,
10044 u
"GeometryGroup"_s,
10049 QStringList() << u
"bbox"_s
10051 <<
new QgsStaticExpressionFunction( u
"disjoint"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDisjoint, u
"GeometryGroup"_s )
10052 <<
new QgsStaticExpressionFunction( u
"intersects"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersects, u
"GeometryGroup"_s )
10053 <<
new QgsStaticExpressionFunction( u
"touches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnTouches, u
"GeometryGroup"_s )
10054 <<
new QgsStaticExpressionFunction( u
"crosses"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCrosses, u
"GeometryGroup"_s )
10055 <<
new QgsStaticExpressionFunction( u
"contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnContains, u
"GeometryGroup"_s )
10056 <<
new QgsStaticExpressionFunction( u
"overlaps"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnOverlaps, u
"GeometryGroup"_s )
10057 <<
new QgsStaticExpressionFunction( u
"within"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnWithin, u
"GeometryGroup"_s )
10058 <<
new QgsStaticExpressionFunction( u
"equals"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnEquals, u
"GeometryGroup"_s )
10059 <<
new QgsStaticExpressionFunction(
10062 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10063 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10064 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s ),
10068 <<
new QgsStaticExpressionFunction(
10069 u
"equals_topological"_s,
10071 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10072 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10073 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"GEOS"_s ),
10074 fcnIsEqualsTopological,
10077 <<
new QgsStaticExpressionFunction(
10080 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10081 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10082 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s )
10083 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4 ),
10087 <<
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 )
10088 <<
new QgsStaticExpressionFunction(
10091 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10092 << QgsExpressionFunction::Parameter( u
"rotation"_s )
10093 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
10094 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
10098 <<
new QgsStaticExpressionFunction(
10101 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10102 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
10103 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
10104 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
10108 <<
new QgsStaticExpressionFunction(
10109 u
"affine_transform"_s,
10111 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10112 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
10113 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
10114 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
10115 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
10116 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
10117 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
10118 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
10119 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
10120 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
10121 fcnAffineTransform,
10124 <<
new QgsStaticExpressionFunction(
10127 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10128 << QgsExpressionFunction::Parameter( u
"distance"_s )
10129 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
10130 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
10131 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
10132 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
10136 <<
new QgsStaticExpressionFunction( u
"force_rhr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForceRHR, u
"GeometryGroup"_s )
10137 <<
new QgsStaticExpressionFunction( u
"force_polygon_cw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCW, u
"GeometryGroup"_s )
10138 <<
new QgsStaticExpressionFunction( u
"force_polygon_ccw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCCW, u
"GeometryGroup"_s )
10139 <<
new QgsStaticExpressionFunction(
10142 << QgsExpressionFunction::Parameter( u
"center"_s )
10143 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10144 << QgsExpressionFunction::Parameter( u
"width"_s )
10145 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
10146 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ),
10150 <<
new QgsStaticExpressionFunction(
10151 u
"tapered_buffer"_s,
10153 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10154 << QgsExpressionFunction::Parameter( u
"start_width"_s )
10155 << QgsExpressionFunction::Parameter( u
"end_width"_s )
10156 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ),
10160 <<
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 )
10161 <<
new QgsStaticExpressionFunction(
10164 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10165 << QgsExpressionFunction::Parameter( u
"distance"_s )
10166 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10168 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10172 <<
new QgsStaticExpressionFunction(
10173 u
"single_sided_buffer"_s,
10175 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10176 << QgsExpressionFunction::Parameter( u
"distance"_s )
10177 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10179 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10180 fcnSingleSidedBuffer,
10183 <<
new QgsStaticExpressionFunction(
10185 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10189 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
10190 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
10191 <<
new QgsStaticExpressionFunction( u
"pole_of_inaccessibility"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
10192 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
10193 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
10194 <<
new QgsStaticExpressionFunction( u
"interior_ring_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnInteriorRingN, u
"GeometryGroup"_s )
10195 <<
new QgsStaticExpressionFunction( u
"geometry_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnGeometryN, u
"GeometryGroup"_s )
10196 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
10197 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
10198 <<
new QgsStaticExpressionFunction( u
"shared_paths"_s,
QgsExpressionFunction::ParameterList { QgsExpressionFunction::Parameter( u
"geometry1"_s ), QgsExpressionFunction::Parameter( u
"geometry2"_s ) }, fcnSharedPaths, u
"GeometryGroup"_s )
10200 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
10201 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
10202 <<
new QgsStaticExpressionFunction(
10205 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10206 << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
10207 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
10208 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
10209 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ),
10213 <<
new QgsStaticExpressionFunction(
10214 u
"triangular_wave"_s,
10215 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10216 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10217 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10218 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10222 <<
new QgsStaticExpressionFunction(
10223 u
"triangular_wave_randomized"_s,
10224 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10225 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10226 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10227 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10228 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10229 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10230 fcnTriangularWaveRandomized,
10233 <<
new QgsStaticExpressionFunction(
10235 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10236 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10237 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10238 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10242 <<
new QgsStaticExpressionFunction(
10243 u
"square_wave_randomized"_s,
10244 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10245 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10246 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10247 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10248 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10249 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10250 fcnSquareWaveRandomized,
10253 <<
new QgsStaticExpressionFunction(
10255 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10256 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10257 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10258 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10262 <<
new QgsStaticExpressionFunction(
10263 u
"wave_randomized"_s,
10264 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10265 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10266 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10267 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10268 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10269 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10270 fcnRoundWaveRandomized,
10273 <<
new QgsStaticExpressionFunction(
10274 u
"apply_dash_pattern"_s,
10276 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10277 QgsExpressionFunction::Parameter( u
"pattern"_s ),
10278 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
10279 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
10280 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
10281 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
10283 fcnApplyDashPattern,
10286 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"vertices"_s ) }, fcnDensifyByCount, u
"GeometryGroup"_s )
10287 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"distance"_s ) }, fcnDensifyByDistance, u
"GeometryGroup"_s )
10288 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
10289 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
10290 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
10291 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
10292 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
10293 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
10294 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
10295 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
10296 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
10297 <<
new QgsStaticExpressionFunction(
10298 u
"is_empty_or_null"_s,
10301 u
"GeometryGroup"_s,
10309 <<
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 )
10310#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
10311 <<
new QgsStaticExpressionFunction(
10314 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10315 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
10316 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ),
10321 <<
new QgsStaticExpressionFunction( u
"oriented_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnOrientedBBox, u
"GeometryGroup"_s )
10322 <<
new QgsStaticExpressionFunction( u
"main_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnMainAngle, u
"GeometryGroup"_s )
10323 <<
new QgsStaticExpressionFunction( u
"minimal_circle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ), fcnMinimalCircle, u
"GeometryGroup"_s )
10324 <<
new QgsStaticExpressionFunction( u
"difference"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDifference, u
"GeometryGroup"_s )
10325 <<
new QgsStaticExpressionFunction( u
"distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDistance, u
"GeometryGroup"_s )
10326 <<
new QgsStaticExpressionFunction(
10327 u
"hausdorff_distance"_s,
10329 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10330 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10331 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
10332 fcnHausdorffDistance,
10335 <<
new QgsStaticExpressionFunction( u
"intersection"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersection, u
"GeometryGroup"_s )
10336 <<
new QgsStaticExpressionFunction(
10337 u
"sym_difference"_s,
10340 u
"GeometryGroup"_s,
10345 QStringList() << u
"symDifference"_s
10347 <<
new QgsStaticExpressionFunction( u
"combine"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10348 <<
new QgsStaticExpressionFunction( u
"union"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10349 <<
new QgsStaticExpressionFunction(
10353 u
"GeometryGroup"_s,
10358 QStringList() << u
"geomToWKT"_s
10360 <<
new QgsStaticExpressionFunction( u
"geom_to_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10361 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
10362 <<
new QgsStaticExpressionFunction(
10364 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"source_auth_id"_s ) << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
10365 fcnTransformGeometry,
10368 <<
new QgsStaticExpressionFunction(
10370 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ),
10372 u
"GeometryGroup"_s,
10375 <<
new QgsStaticExpressionFunction( u
"is_multipart"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsMultipart, u
"GeometryGroup"_s )
10380 <<
new QgsStaticExpressionFunction( u
"sinuosity"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSinuosity, u
"GeometryGroup"_s )
10381 <<
new QgsStaticExpressionFunction( u
"straight_distance_2d"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStraightDistance2d, u
"GeometryGroup"_s );
10384 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction(
10387 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10388 << QgsExpressionFunction::Parameter( u
"orderby"_s )
10389 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
10391 u
"GeometryGroup"_s,
10396 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10397 for ( QgsExpressionNode *argNode : argList )
10399 if ( !argNode->isStatic( parent, context ) )
10405 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10407 QString expString = argNode->
eval( parent, context ).toString();
10411 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10421 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10422 QString
expression = argNode->
eval( parent, context ).toString();
10424 e.prepare( context );
10429 functions << orderPartsFunc;
10432 <<
new QgsStaticExpressionFunction( u
"closest_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnClosestPoint, u
"GeometryGroup"_s )
10433 <<
new QgsStaticExpressionFunction( u
"shortest_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnShortestLine, u
"GeometryGroup"_s )
10434 <<
new QgsStaticExpressionFunction( u
"line_interpolate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
10435 <<
new QgsStaticExpressionFunction(
10436 u
"line_interpolate_point_by_m"_s,
10438 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10439 << QgsExpressionFunction::Parameter( u
"m"_s )
10440 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10441 fcnLineInterpolatePointByM,
10444 <<
new QgsStaticExpressionFunction( u
"line_interpolate_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
10445 <<
new QgsStaticExpressionFunction( u
"line_locate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
10446 <<
new QgsStaticExpressionFunction(
10447 u
"line_locate_m"_s,
10449 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10450 << QgsExpressionFunction::Parameter( u
"m"_s )
10451 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10455 <<
new QgsStaticExpressionFunction( u
"angle_at_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
10456 <<
new QgsStaticExpressionFunction( u
"distance_to_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
10457 <<
new QgsStaticExpressionFunction(
10458 u
"line_substring"_s,
10459 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10467 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
10469 functions << idFunc;
10471 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
10473 functions << currentFeatureFunc;
10475 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction(
10479 u
"Record and Attributes"_s,
10484 QStringList() << u
"$uuid"_s
10487 functions << uuidFunc;
10490 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
10491 <<
new QgsStaticExpressionFunction(
10493 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
10495 u
"Record and Attributes"_s,
10500 QStringList() << u
"QgsExpressionUtils::getFeature"_s
10502 <<
new QgsStaticExpressionFunction(
10503 u
"get_feature_by_id"_s,
10506 u
"Record and Attributes"_s,
10513 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction(
10517 u
"Record and Attributes"_s,
10523 functions << attributesFunc;
10524 QgsStaticExpressionFunction *representAttributesFunc
10525 =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1, fcnRepresentAttributes, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10527 functions << representAttributesFunc;
10529 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction(
10530 u
"is_feature_valid"_s,
10532 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10533 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10534 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10535 fcnValidateFeature,
10536 u
"Record and Attributes"_s,
10542 functions << validateFeature;
10544 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction(
10545 u
"is_attribute_valid"_s,
10547 << QgsExpressionFunction::Parameter( u
"attribute"_s,
false )
10549 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10550 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10551 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10552 fcnValidateAttribute,
10553 u
"Record and Attributes"_s,
10559 functions << validateAttribute;
10561 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction( u
"maptip"_s, -1, fcnFeatureMaptip, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10563 functions << maptipFunc;
10565 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction( u
"display_expression"_s, -1, fcnFeatureDisplayExpression, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10567 functions << displayFunc;
10569 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction( u
"is_selected"_s, -1, fcnIsSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10571 functions << isSelectedFunc;
10573 functions <<
new QgsStaticExpressionFunction( u
"num_selected"_s, -1, fcnNumSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10575 functions <<
new QgsStaticExpressionFunction(
10576 u
"sqlite_fetch_and_increment"_s,
10578 << QgsExpressionFunction::Parameter( u
"database"_s )
10579 << QgsExpressionFunction::Parameter( u
"table"_s )
10580 << QgsExpressionFunction::Parameter( u
"id_field"_s )
10581 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
10582 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
10583 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
10584 fcnSqliteFetchAndIncrement,
10585 u
"Record and Attributes"_s
10590 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
10591 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
10595 QgsStaticExpressionFunction *representValueFunc
10596 =
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 );
10599 Q_UNUSED( context )
10602 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
10609 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
10619 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
10624 functions << representValueFunc;
10628 <<
new QgsStaticExpressionFunction( u
"layer_property"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"property"_s ), fcnGetLayerProperty, u
"Map Layers"_s )
10629 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"part"_s,
true ), fcnDecodeUri, u
"Map Layers"_s )
10630 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary_data"_s ), fcnMimeType, u
"General"_s )
10631 <<
new QgsStaticExpressionFunction(
10632 u
"raster_statistic"_s,
10633 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"statistic"_s ),
10634 fcnGetRasterBandStat,
10639 QgsStaticExpressionFunction *varFunction
10649 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10651 if ( !argNode->
isStatic( parent, context ) )
10654 const QString varName = argNode->
eval( parent, context ).toString();
10655 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
10659 return scope ? scope->
isStatic( varName ) :
false;
10664 if ( node && node->
args()->
count() > 0 )
10666 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10667 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
10669 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
10676 functions << varFunction;
10678 QgsStaticExpressionFunction *evalTemplateFunction
10683 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10685 if ( argNode->
isStatic( parent, context ) )
10687 QString expString = argNode->
eval( parent, context ).toString();
10691 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10698 functions << evalTemplateFunction;
10700 QgsStaticExpressionFunction *evalFunc
10705 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10707 if ( argNode->
isStatic( parent, context ) )
10709 QString expString = argNode->
eval( parent, context ).toString();
10713 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10721 functions << evalFunc;
10723 QgsStaticExpressionFunction *attributeFunc
10724 =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10726 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10727 for ( QgsExpressionNode *argNode : argList )
10729 if ( !argNode->
isStatic( parent, context ) )
10741 functions << attributeFunc;
10745 <<
new QgsWithVariableExpressionFunction()
10746 <<
new QgsStaticExpressionFunction(
10748 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10752 <<
new QgsStaticExpressionFunction(
10753 u
"raster_attributes"_s,
10754 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10755 fcnRasterAttributes,
10760 <<
new QgsArrayForeachExpressionFunction()
10761 <<
new QgsArrayFilterExpressionFunction()
10762 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10763 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10764 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10765 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10766 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10767 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array_a"_s ) << QgsExpressionFunction::Parameter( u
"array_b"_s ), fcnArrayAll, u
"Arrays"_s )
10768 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10769 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10775 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10776 <<
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 )
10777 <<
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 )
10779 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10780 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10781 <<
new QgsStaticExpressionFunction(
10783 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
10787 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10788 <<
new QgsStaticExpressionFunction(
10789 u
"array_remove_all"_s,
10800 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10801 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"array_prioritize"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10802 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10803 <<
new QgsStaticExpressionFunction(
10805 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ),
10809 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10810 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10811 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10812 <<
new QgsStaticExpressionFunction(
10813 u
"array_to_string"_s,
10815 << QgsExpressionFunction::Parameter( u
"array"_s )
10816 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10817 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10821 <<
new QgsStaticExpressionFunction(
10822 u
"string_to_array"_s,
10824 << QgsExpressionFunction::Parameter( u
"string"_s )
10825 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10826 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10830 <<
new QgsStaticExpressionFunction(
10831 u
"generate_series"_s,
10832 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ),
10836 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10839 <<
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 )
10840 <<
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 )
10841 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10843 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10844 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10845 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10846 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10847 <<
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 )
10848 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10851 <<
new QgsStaticExpressionFunction( u
"map_prefix_keys"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"prefix"_s ), fcnMapPrefixKeys, u
"Maps"_s )
10852 <<
new QgsStaticExpressionFunction( u
"map_to_html_table"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlTable, u
"Maps"_s )
10853 <<
new QgsStaticExpressionFunction( u
"map_to_html_dl"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlDefinitionList, u
"Maps"_s )
10863 *sOwnedFunctions() << func;
10864 *sBuiltinFunctions() << func->name();
10865 sBuiltinFunctions()->append( func->aliases() );
10879 QMutexLocker locker( &sFunctionsMutex );
10880 sFunctions()->append( function );
10881 if ( transferOwnership )
10882 sOwnedFunctions()->append( function );
10897 QMutexLocker locker( &sFunctionsMutex );
10898 sFunctions()->removeAt( fnIdx );
10899 sFunctionIndexMap.clear();
10907 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10908 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10910 sBuiltinFunctions()->removeAll( func->name() );
10911 for (
const QString &alias : func->aliases() )
10913 sBuiltinFunctions()->removeAll( alias );
10916 sFunctions()->removeAll( func );
10919 qDeleteAll( *sOwnedFunctions() );
10920 sOwnedFunctions()->clear();
10925 if ( sBuiltinFunctions()->isEmpty() )
10929 return *sBuiltinFunctions();
10934 u
"array_foreach"_s,
10944 QgsExpressionNode::NodeList *args = node->
args();
10946 if ( args->
count() < 2 )
10949 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10959 QVariantList result;
10961 if ( args->
count() < 2 )
10965 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10967 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10968 std::unique_ptr< QgsExpressionContext > tempContext;
10971 tempContext = std::make_unique< QgsExpressionContext >();
10972 subContext = tempContext.get();
10975 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10979 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
10983 result << args->
at( 1 )->
eval( parent, subContext );
10996 Q_UNUSED( context )
11008 if ( args->
count() < 2 )
11012 args->
at( 0 )->
prepare( parent, context );
11016 subContext = *context;
11023 args->
at( 1 )->
prepare( parent, &subContext );
11036 QgsExpressionNode::NodeList *args = node->
args();
11038 if ( args->
count() < 2 )
11041 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11051 QVariantList result;
11053 if ( args->
count() < 2 )
11057 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11059 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11060 std::unique_ptr< QgsExpressionContext > tempContext;
11063 tempContext = std::make_unique< QgsExpressionContext >();
11064 subContext = tempContext.get();
11067 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11071 if ( args->
count() >= 3 )
11073 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
11075 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
11077 limit = limitVar.toInt();
11085 for (
const QVariant &value : array )
11087 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
11088 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
11092 if ( limit > 0 && limit == result.size() )
11107 Q_UNUSED( context )
11119 if ( args->
count() < 2 )
11123 args->
at( 0 )->
prepare( parent, context );
11127 subContext = *context;
11133 args->
at( 1 )->
prepare( parent, &subContext );
11145 QgsExpressionNode::NodeList *args = node->
args();
11147 if ( args->
count() < 3 )
11151 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11153 QVariant
name = args->
at( 0 )->
eval( parent, context );
11154 QVariant value = args->
at( 1 )->
eval( parent, context );
11157 appendTemporaryVariable( context,
name.toString(), value );
11158 if ( args->
at( 2 )->
isStatic( parent, context ) )
11160 popTemporaryVariable( context );
11171 if ( args->
count() < 3 )
11175 QVariant
name = args->
at( 0 )->
eval( parent, context );
11176 QVariant value = args->
at( 1 )->
eval( parent, context );
11178 const QgsExpressionContext *updatedContext = context;
11179 std::unique_ptr< QgsExpressionContext > tempContext;
11180 if ( !updatedContext )
11182 tempContext = std::make_unique< QgsExpressionContext >();
11183 updatedContext = tempContext.get();
11186 appendTemporaryVariable( updatedContext,
name.toString(), value );
11187 result = args->
at( 2 )->
eval( parent, updatedContext );
11190 popTemporaryVariable( updatedContext );
11199 Q_UNUSED( context )
11211 if ( args->
count() < 3 )
11216 QVariant value = args->
at( 1 )->
prepare( parent, context );
11219 std::unique_ptr< QgsExpressionContext > tempContext;
11220 if ( !updatedContext )
11222 tempContext = std::make_unique< QgsExpressionContext >();
11223 updatedContext = tempContext.get();
11226 appendTemporaryVariable( updatedContext,
name.toString(), value );
11227 args->
at( 2 )->
prepare( parent, updatedContext );
11230 popTemporaryVariable( updatedContext );
11235void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
11237 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
11238 delete updatedContext->
popScope();
11241void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
11243 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
11244 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
11246 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.
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.
bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
QgsGeometry singleSidedBuffer(double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle=Qgis::JoinStyle::Round, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
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.
bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false, QgsFeedback *feedback=nullptr) const
Attempts to make an invalid geometry valid without losing vertices.
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
QgsGeometry sharedPaths(const QgsGeometry &other) const
Find paths shared between the two given lineal geometries (this and other).
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
QgsGeometry buffer(double distance, int segments, QgsFeedback *feedback=nullptr) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
bool isFuzzyEqual(const QgsGeometry &geometry, double epsilon=1e-4, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry within the tolerance epsilon using the specified backend.
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry extendLine(double startDistance, double endDistance) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
QgsGeometry triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
bool isTopologicallyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::GEOS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry simplify(double tolerance, QgsFeedback *feedback=nullptr) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
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.
bool overlaps(const QgsGeometry &geometry) const
Returns true if the geometry overlaps another geometry.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle(double tolerance, QString *errorMsg=nullptr, QgsFeedback *feedback=nullptr) const
Returns the maximum inscribed circle.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Represents a color stop within a QgsGradientColorRamp color ramp.
static QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
static QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.
A representation of the interval between two datetime values.
bool isValid() const
Returns true if the interval is valid.
double days() const
Returns the interval duration in days.
double weeks() const
Returns the interval duration in weeks.
double months() const
Returns the interval duration in months (based on a 30 day month).
double seconds() const
Returns the interval duration in seconds.
double years() const
Returns the interval duration in years (based on an average year length).
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
Line string geometry type, with support for z-dimension and m-values.
bool lineLocatePointByM(double m, double &x, double &y, double &z, double &distanceFromStart, bool use3DDistance=true) const
Attempts to locate a point on the linestring by m value.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
Represents a model of the Earth's magnetic field.
static bool fieldComponentsWithTimeDerivatives(double Bx, double By, double Bz, double Bxt, double Byt, double Bzt, double &H, double &F, double &D, double &I, double &Ht, double &Ft, double &Dt, double &It)
Compute various quantities dependent on a magnetic field and their rates of change.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Base class for all map layer types.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QgsLayerMetadata metadata
QString publicSource(bool hidePassword=false) const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
virtual bool isEditable() const
Returns true if the layer can be edited.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
Implementation of a geometry simplifier using the "MapToPixel" algorithm.
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Custom exception class which is raised when an operation is not supported.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
double inclination(const QgsPoint &other) const
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Quadrilateral geometry type.
static QgsQuadrilateral squareFromDiagonal(const QgsPoint &p1, const QgsPoint &p2)
Construct a QgsQuadrilateral as a square from a diagonal.
QgsPolygon * toPolygon(bool force2D=false) const
Returns the quadrilateral as a new polygon.
static QgsQuadrilateral rectangleFrom3Points(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, ConstructionOption mode)
Construct a QgsQuadrilateral as a Rectangle from 3 points.
ConstructionOption
A quadrilateral can be constructed from 3 points where the second distance can be determined by the t...
@ Distance
Second distance is equal to the distance between 2nd and 3rd point.
@ Projected
Second distance is equal to the distance of the perpendicular projection of the 3rd point on the segm...
The Field class represents a Raster Attribute Table field, including its name, usage and type.
bool isRamp() const
Returns true if the field carries a color ramp component information (RedMin/RedMax,...
bool isColor() const
Returns true if the field carries a color component (Red, Green, Blue and optionally Alpha) informati...
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
A rectangle specified with double values.
void grow(double delta)
Grows the rectangle in place by the specified amount.
Regular Polygon geometry type.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices).
QgsPolygon * toPolygon() const
Returns as a polygon.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
Q_INVOKABLE QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
void setUsesGeometryFunction(const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry)
Set a function that will be called when determining if the function requires feature geometry or not.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
static QString unaccent(const QString &input)
Removes accents and other diacritical marks from a string, replacing accented characters with their u...
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Contains utility functions for working with symbols and symbol layers.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
Allows creation of a multi-layer database-side transaction.
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QVariant aggregate(Qgis::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters ¶meters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeatureIds *fids=nullptr, QgsFeedback *feedback=nullptr, QString *error=nullptr) const
Calculates an aggregated value from the layer's features.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QgsWithVariableExpressionFunction()
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored).
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
const QString cacheKey(const QString &pathIn)
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
std::function< bool(const QgsGeometry &geometry, const QgsGeometry &other, const QVariantList &values, Qgis::GeometryBackend backend)> RelationFunction
allows geometry function with different parameters to be used with the same executeGeomOverlay functi...
double qDateTimeToDecimalYear(const QDateTime &dateTime)
QList< QgsExpressionFunction * > ExpressionFunctionList
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColorObject(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
#define SET_EVAL_ERROR(x)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QLineF segment(int index, QRectF rect, double radius)
A bundle of parameters controlling aggregate calculation.
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
Single variable definition for use within a QgsExpressionContextScope.
The Context struct stores the current layer and coordinate transform context.
const QgsMapLayer * layer
QgsCoordinateTransformContext transformContext
Utility class for identifying a unique vertex within a geometry.