70#include <QCryptographicHash>
71#include <QMimeDatabase>
72#include <QProcessEnvironment>
73#include <QRegularExpression>
78using namespace Qt::StringLiterals;
99 QVariantList argValues;
103 const QList< QgsExpressionNode * > argList = args->
list();
104 argValues.reserve( argList.size() );
111 v = QVariant::fromValue( n );
115 v = n->eval( parent, context );
117 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
118 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
121 argValues.append( v );
126 return func( argValues, context, parent, node );
137 return QStringList();
164 return mGroups.isEmpty() ? false : mGroups.contains( u
"deprecated"_s );
169 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
180 const QString &fnname,
183 const QString &group,
184 const QString &helpText,
188 const QStringList &aliases,
193 , mAliases( aliases )
194 , mUsesGeometry( false )
195 , mUsesGeometryFunc( usesGeometry )
196 , mReferencedColumnsFunc( referencedColumns )
207 if ( mUsesGeometryFunc )
208 return mUsesGeometryFunc( node );
210 return mUsesGeometry;
220 if ( mReferencedColumnsFunc )
221 return mReferencedColumnsFunc( node );
223 return mReferencedColumns;
229 return mIsStaticFunc( node, parent, context );
237 return mPrepareFunc( node, parent, context );
249 mIsStaticFunc =
nullptr;
255 mPrepareFunc = prepareFunc;
260 if ( node && node->
args() )
262 const QList< QgsExpressionNode * > argList = node->
args()->
list();
265 if ( !argNode->isStatic( parent, context ) )
275 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
276 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
277 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
279 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
286 double current = start + step;
287 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
310 return QVariant::fromValue( geom );
321 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
323 if ( name ==
"feature"_L1 )
325 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
327 else if ( name ==
"id"_L1 )
329 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
331 else if ( name ==
"geometry"_L1 )
333 return fcnGeometry( values, context, parent, node );
343 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
352 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
354 return expression.evaluate( context );
359 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
360 return QVariant( std::sqrt( x ) );
365 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
366 return QVariant( std::fabs( val ) );
371 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
372 return ( deg * M_PI ) / 180;
376 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
377 return ( 180 * rad ) / M_PI;
381 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
382 return QVariant( std::sin( x ) );
386 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
387 return QVariant( std::cos( x ) );
391 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
392 return QVariant( std::tan( x ) );
396 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
397 return QVariant( std::asin( x ) );
401 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::acos( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
407 return QVariant( std::atan( x ) );
411 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
412 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
413 return QVariant( std::atan2( y, x ) );
417 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
418 return QVariant( std::exp( x ) );
422 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
425 return QVariant( std::log( x ) );
429 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
432 return QVariant( log10( x ) );
436 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
437 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
438 if ( x <= 0 || b <= 0 )
440 return QVariant( std::log( x ) / std::log( b ) );
444 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
445 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
449 std::random_device rd;
450 std::mt19937_64 generator( rd() );
452 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
455 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
458 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
463 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
464 std::hash<std::string> hasher;
465 seed = hasher( seedStr.toStdString() );
467 generator.seed( seed );
471 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
472 return QVariant( min + f * ( max - min ) );
476 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
477 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
481 std::random_device rd;
482 std::mt19937_64 generator( rd() );
484 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
487 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
490 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
495 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
496 std::hash<std::string> hasher;
497 seed = hasher( seedStr.toStdString() );
499 generator.seed( seed );
502 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
503 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
504 return QVariant( randomInteger );
507 return QVariant(
int( randomInteger ) );
512 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
513 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
514 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
515 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
516 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
518 if ( domainMin >= domainMax )
520 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
525 if ( val >= domainMax )
529 else if ( val <= domainMin )
535 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
536 double c = rangeMin - ( domainMin * m );
539 return QVariant( m * val +
c );
544 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
545 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
546 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
547 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
548 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
549 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
551 if ( domainMin >= domainMax )
553 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
563 if ( val >= domainMax )
567 else if ( val <= domainMin )
573 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
578 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
579 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
580 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
581 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
582 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
583 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
585 if ( domainMin >= domainMax )
587 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
597 if ( val >= domainMax )
601 else if ( val <= domainMin )
607 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
608 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
613 const double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
614 const double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
615 const double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
616 const double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
617 const double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
619 const double x1 = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
620 const double y1 = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
621 const double x2 = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
622 const double y2 = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
624 if ( x1 < 0.0 || x1 > 1.0 || y1 < 0.0 || y1 > 1.0 || x2 < 0.0 || x2 > 1.0 || y2 < 0.0 || y2 > 1.0 )
626 parent->
setEvalErrorString( QObject::tr(
"Cubic bezier control points must be between 0 and 1" ) );
630 if ( domainMin >= domainMax )
632 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
637 if ( val >= domainMax )
641 else if ( val <= domainMin )
647 const double t = ( val - domainMin ) / ( domainMax - domainMin );
650 const double cx = 3.0 * x1;
651 const double bx = 3.0 * ( x2 - x1 ) - cx;
652 const double ax = 1.0 - cx - bx;
653 const double cy = 3.0 * y1;
654 const double by = 3.0 * ( y2 - y1 ) - cy;
655 const double ay = 1.0 - cy - by;
657 constexpr double epsilon = 1e-6;
662 for (
int i = 0; i < 8; ++i )
664 const double x2val = ( ( ax * s + bx ) * s + cx ) * s - t;
665 if ( std::fabs( x2val ) < epsilon )
670 const double d2 = ( 3.0 * ax * s + 2.0 * bx ) * s + cx;
671 if ( std::fabs( d2 ) < 1e-6 )
694 while ( !solved && t0 < t1 )
696 const double x2val = ( ( ax * s + bx ) * s + cx ) * s;
697 if ( std::fabs( x2val - t ) < epsilon )
706 s = ( t1 - t0 ) * 0.5 + t0;
710 const double easedT = ( ( ay * s + by ) * s + cy ) * s;
711 return QVariant( ( rangeMax - rangeMin ) * easedT + rangeMin );
717 double maxVal = std::numeric_limits<double>::quiet_NaN();
718 for (
const QVariant &val : values )
721 if ( std::isnan( maxVal ) )
725 else if ( !std::isnan( testVal ) )
727 maxVal = std::max( maxVal, testVal );
731 if ( !std::isnan( maxVal ) )
733 result = QVariant( maxVal );
741 double minVal = std::numeric_limits<double>::quiet_NaN();
742 for (
const QVariant &val : values )
745 if ( std::isnan( minVal ) )
749 else if ( !std::isnan( testVal ) )
751 minVal = std::min( minVal, testVal );
755 if ( !std::isnan( minVal ) )
757 result = QVariant( minVal );
769 QVariant value = node->
eval( parent, context );
774 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
778 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
783 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
785 value = node->
eval( parent, context );
791 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
796 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
798 QString subExpression = node->
dump();
802 if ( values.count() > 3 )
804 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
807 if ( !nl || nl->value().isValid() )
812 if ( values.count() > 4 )
814 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
816 value = node->
eval( parent, context );
823 if ( values.count() > 5 )
825 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
828 if ( !nl || nl->value().isValid() )
830 orderBy = node->
dump();
835 QString aggregateError;
843 const QSet< QString > filterVars = filterExp.referencedVariables();
844 const QSet< QString > subExpVars = subExp.referencedVariables();
845 QSet<QString> allVars = filterVars + subExpVars;
847 bool isStatic =
true;
848 if ( filterVars.contains( u
"parent"_s ) || filterVars.contains( QString() ) || subExpVars.contains( u
"parent"_s ) || subExpVars.contains( QString() ) )
854 for (
const QString &varName : allVars )
857 if ( scope && !scope->
isStatic( varName ) )
865 if ( isStatic && !parameters.
orderBy.isEmpty() )
867 for (
const auto &orderByClause : std::as_const( parameters.
orderBy ) )
869 const QgsExpression &orderByExpression { orderByClause.expression() };
881 const QString contextHash = context->
uniqueHash( ok, allVars );
884 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
889 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
900 subContext.appendScope( subScope );
901 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
913 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
917 if ( !aggregateError.isEmpty() )
918 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
920 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
931 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
939 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
943 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
952 QVariant value = node->
eval( parent, context );
954 QString relationId = value.toString();
961 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
963 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
968 relation = relations.at( 0 );
975 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
977 value = node->
eval( parent, context );
983 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
988 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
990 QString subExpression = node->
dump();
994 if ( values.count() > 3 )
996 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
998 value = node->
eval( parent, context );
1000 parameters.
delimiter = value.toString();
1005 if ( values.count() > 4 )
1007 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
1010 if ( !nl || nl->value().isValid() )
1012 orderBy = node->
dump();
1023 const QString
cacheKey = u
"relagg:%1%:%2:%3:%4:%5:%6"_s.arg( relationId, vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1033 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1037 if ( !error.isEmpty() )
1038 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1040 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1050static QVariant fcnAggregateGeneric(
1056 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1064 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
1068 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
1075 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1077 QString subExpression = node->
dump();
1081 if ( values.count() > 1 )
1083 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
1086 if ( !nl || nl->value().isValid() )
1087 groupBy = node->
dump();
1091 if ( values.count() > 2 )
1093 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
1096 if ( !nl || nl->value().isValid() )
1102 if ( orderByPos >= 0 && values.count() > orderByPos )
1104 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
1107 if ( !nl || nl->value().isValid() )
1109 orderBy = node->
dump();
1117 if ( !groupBy.isEmpty() )
1120 QVariant groupByValue = groupByExp.evaluate( context );
1122 if ( !parameters.
filter.isEmpty() )
1123 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1125 parameters.
filter = groupByClause;
1131 bool isStatic =
true;
1132 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1133 for (
const QString &varName : refVars )
1136 if ( scope && !scope->
isStatic( varName ) )
1147 const QString contextHash = context->
uniqueHash( ok, refVars );
1150 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy, contextHash );
1155 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1167 subContext.appendScope( subScope );
1169 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1173 if ( !error.isEmpty() )
1174 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1176 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1281 if ( values.count() > 3 )
1283 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1285 QVariant value = node->
eval( parent, context );
1287 parameters.
delimiter = value.toString();
1298 if ( values.count() > 3 )
1300 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1302 QVariant value = node->
eval( parent, context );
1304 parameters.
delimiter = value.toString();
1320 QVariant scale = context->
variable( u
"map_scale"_s );
1325 const double v = scale.toDouble( &ok );
1333 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1334 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1335 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1338 if ( testValue <= minValue )
1340 return QVariant( minValue );
1342 else if ( testValue >= maxValue )
1344 return QVariant( maxValue );
1348 return QVariant( testValue );
1354 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1355 return QVariant( std::floor( x ) );
1360 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1361 return QVariant( std::ceil( x ) );
1366 const QVariant value = values.at( 0 );
1367 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1369 return QVariant(
false );
1371 else if ( value.userType() == QMetaType::QString )
1374 return QVariant( !value.toString().isEmpty() );
1376 else if ( QgsExpressionUtils::isList( value ) )
1378 return !value.toList().isEmpty();
1380 return QVariant( value.toBool() );
1384 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1388 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1392 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1397 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1398 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1399 if ( format.isEmpty() && !language.isEmpty() )
1401 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1402 return QVariant( QDateTime() );
1405 if ( format.isEmpty() && language.isEmpty() )
1406 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1408 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1409 QLocale locale = QLocale();
1410 if ( !language.isEmpty() )
1412 locale = QLocale( language );
1415 QDateTime datetime = locale.toDateTime( datetimestring, format );
1416 if ( !datetime.isValid() )
1418 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1419 datetime = QDateTime();
1421 return QVariant( datetime );
1426 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1427 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1428 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1430 const QDate date( year, month, day );
1431 if ( !date.isValid() )
1433 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1436 return QVariant( date );
1441 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1442 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1443 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1445 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1446 if ( !time.isValid() )
1448 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1451 return QVariant( time );
1456 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1457 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1458 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1459 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1460 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1461 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1463 const QDate date( year, month, day );
1464 if ( !date.isValid() )
1466 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1469 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1470 if ( !time.isValid() )
1472 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1475 return QVariant( QDateTime( date, time ) );
1480 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1484#if QT_FEATURE_timezone > 0
1485 if ( !timeZoneId.isEmpty() )
1487 tz = QTimeZone( timeZoneId.toUtf8() );
1490 if ( !tz.isValid() )
1492 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1497 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1499 return QVariant::fromValue( tz );
1504#if QT_FEATURE_timezone > 0
1505 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1506 if ( datetime.isValid() )
1508 return QVariant::fromValue( datetime.timeZone() );
1513 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1520#if QT_FEATURE_timezone > 0
1521 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1522 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1523 if ( datetime.isValid() && tz.isValid() )
1525 datetime.setTimeZone( tz );
1526 return QVariant::fromValue( datetime );
1531 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1538#if QT_FEATURE_timezone > 0
1539 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1540 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1541 if ( datetime.isValid() && tz.isValid() )
1543 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1548 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1555#if QT_FEATURE_timezone > 0
1556 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1557 if ( timeZone.isValid() )
1559 return QString( timeZone.id() );
1564 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1571 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1572 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1573 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1574 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1575 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1576 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1577 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1579 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1584 for (
const QVariant &value : values )
1595 const QVariant val1 = values.at( 0 );
1596 const QVariant val2 = values.at( 1 );
1606 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1607 return QVariant( str.toLower() );
1611 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1612 return QVariant( str.toUpper() );
1616 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1617 QStringList elems = str.split(
' ' );
1618 for (
int i = 0; i < elems.size(); i++ )
1620 if ( elems[i].size() > 1 )
1621 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1623 return QVariant( elems.join(
' '_L1 ) );
1628 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1629 return QVariant( str.trimmed() );
1634 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1636 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1638 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1639 str.replace( re, QString() );
1640 return QVariant( str );
1645 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1647 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1649 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1650 str.replace( re, QString() );
1651 return QVariant( str );
1656 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1657 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1663 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1664 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1670 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1671 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1678 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1684 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1685 return QVariant( QString( character ) );
1690 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1692 if ( value.isEmpty() )
1697 int res = value.at( 0 ).unicode();
1698 return QVariant( res );
1703 if ( values.length() == 2 || values.length() == 3 )
1705 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1706 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1708 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1721 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1725 return QVariant( geom.
length() );
1731 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1732 return QVariant( str.length() );
1737 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1742 double totalLength = 0;
1747 totalLength += line->length3D();
1752 totalLength += segmentized->length3D();
1762 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1763 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1764 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1769 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1771 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1772 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1773 QVector< QPair< QString, QString > > mapItems;
1775 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1777 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1781 std::sort( mapItems.begin(), mapItems.end(), [](
const QPair< QString, QString > &pair1,
const QPair< QString, QString > &pair2 ) { return ( pair1.first.length() > pair2.first.length() ); } );
1783 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1785 str = str.replace( it->first, it->second );
1788 return QVariant( str );
1790 else if ( values.count() == 3 )
1792 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1793 QVariantList before;
1795 bool isSingleReplacement =
false;
1797 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1799 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1803 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1806 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1808 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1809 isSingleReplacement =
true;
1813 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1816 if ( !isSingleReplacement && before.length() != after.length() )
1818 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1822 for (
int i = 0; i < before.length(); i++ )
1824 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1827 return QVariant( str );
1831 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1838 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1839 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1840 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1842 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1843 if ( !re.isValid() )
1845 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1848 return QVariant( str.replace( re, after ) );
1853 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1854 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1856 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1857 if ( !re.isValid() )
1859 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1862 return QVariant( ( str.indexOf( re ) + 1 ) );
1867 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1868 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1869 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1871 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1872 if ( !re.isValid() )
1874 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1878 QRegularExpressionMatch matches = re.match( str );
1879 if ( matches.hasMatch() )
1882 QStringList list = matches.capturedTexts();
1885 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1887 array += ( !( *it ).isEmpty() ) ? *it : empty;
1890 return QVariant( array );
1900 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1901 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1903 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1904 if ( !re.isValid() )
1906 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1911 QRegularExpressionMatch match = re.match( str );
1912 if ( match.hasMatch() )
1915 if ( match.lastCapturedIndex() > 0 )
1918 return QVariant( match.captured( 1 ) );
1923 return QVariant( match.captured( 0 ) );
1928 return QVariant(
"" );
1934 const int version = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1939 uuid = QUuid::createUuid();
1942#if QT_VERSION >= QT_VERSION_CHECK( 6, 9, 0 )
1943 uuid = QUuid::createUuidV7();
1945 parent->
setEvalErrorString( QObject::tr(
"UUid version 7 is not supported on this QGIS build" ) );
1950 parent->
setEvalErrorString( QObject::tr(
"UUid version %1 is not supported" ).arg( version ) );
1954 const QString format = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1955 if ( format.compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1956 return uuid.toString( QUuid::StringFormat::WithoutBraces );
1957 else if ( format.compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1958 return uuid.toString( QUuid::StringFormat::Id128 );
1959 return uuid.toString();
1964 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1967 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1968 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1971 if ( values.at( 2 ).isValid() )
1972 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1978 from = str.size() + from;
1984 else if ( from > 0 )
1992 len = str.size() + len - from;
1999 return QVariant( str.mid( from, len ) );
2004 return QVariant( f.
id() );
2009 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2010 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
2011 bool foundLayer =
false;
2012 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2017 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
2018 if ( !layer || !layer->dataProvider() )
2020 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2024 if ( bandNb < 1 || bandNb > layer->bandCount() )
2026 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
2032 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
2039 QgsMultiPointXY multiPoint = geom.asMultiPoint();
2040 if ( multiPoint.count() == 1 )
2042 point = multiPoint[0];
2051 double value = layer->dataProvider()->sample( point, bandNb );
2052 return std::isnan( value ) ? QVariant() : value;
2059 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2070 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2071 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2073 bool foundLayer =
false;
2074 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2078 [parent, bandNb, value](
QgsMapLayer *mapLayer ) -> QVariant {
2079 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
2080 if ( !layer || !layer->dataProvider() )
2082 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2086 if ( bandNb < 1 || bandNb > layer->bandCount() )
2088 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
2092 if ( std::isnan( value ) )
2094 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
2098 if ( !layer->dataProvider()->attributeTable( bandNb ) )
2103 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
2104 if ( data.isEmpty() )
2110 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
2111 for (
int idx = 0; idx < static_cast<int>( fields.count() ) && idx < static_cast<int>( data.count() ); ++idx )
2118 result.insert( fields.at( idx ).name, data.at( idx ) );
2128 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2149 if ( values.size() == 1 )
2151 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2154 else if ( values.size() == 2 )
2156 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2157 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2161 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2170 QString table { R
"html(
2173 <tr><th>%1</th></tr>
2176 <tr><td>%2</td></tr>
2180 if ( values.size() == 1 )
2182 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2186 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2190 if ( dict.isEmpty() )
2195 QStringList headers;
2198 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2200 headers.push_back( it.key().toHtmlEscaped() );
2201 cells.push_back( it.value().toString().toHtmlEscaped() );
2204 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2209 QString table { R
"html(
2214 if ( values.size() == 1 )
2216 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2220 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2224 if ( dict.isEmpty() )
2231 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2233 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2236 return table.arg( rows );
2244 layer = context->
variable( u
"layer"_s );
2249 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2251 layer = node->
eval( parent, context );
2262 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2266 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2267 if ( strength ==
"hard"_L1 )
2271 else if ( strength ==
"soft"_L1 )
2276 bool foundLayer =
false;
2277 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2281 [parent, feature, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2282 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2285 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2291 for (
int i = 0; i < fields.
size(); i++ )
2308 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2320 layer = context->
variable( u
"layer"_s );
2325 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2327 layer = node->
eval( parent, context );
2338 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2342 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2343 if ( strength ==
"hard"_L1 )
2347 else if ( strength ==
"soft"_L1 )
2352 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2354 bool foundLayer =
false;
2355 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2359 [parent, feature, attributeName, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2360 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2367 if ( fieldIndex == -1 )
2369 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2382 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2398 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2403 for (
int i = 0; i < fields.
count(); ++i )
2417 if ( values.isEmpty() )
2420 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2422 else if ( values.size() == 1 )
2424 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2425 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2427 else if ( values.size() == 2 )
2429 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2430 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2434 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2441 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2447 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2453 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2455 const QString fieldName { fields.
at( fieldIndex ).
name() };
2456 const QVariant attributeVal = feature.
attribute( fieldIndex );
2457 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2460 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2469 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2481 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2483 result.insert( fields.
at( fieldIndex ).
name(), value );
2498 bool evaluate =
true;
2502 if ( values.isEmpty() )
2505 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2507 else if ( values.size() == 1 )
2509 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2510 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2512 else if ( values.size() == 2 )
2514 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2515 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2517 else if ( values.size() == 3 )
2519 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2520 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2521 evaluate = values.value( 2 ).toBool();
2527 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2531 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2563 subContext.setFeature( feature );
2572 exp.prepare( &subContext );
2573 return exp.evaluate( &subContext ).toString();
2579 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2584 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2591 if ( values.isEmpty() )
2594 layer = context->
variable( u
"layer"_s );
2596 else if ( values.size() == 1 )
2598 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2599 layer = context->
variable( u
"layer"_s );
2601 else if ( values.size() == 2 )
2603 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2604 layer = values.at( 0 );
2608 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2612 bool foundLayer =
false;
2613 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2618 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2619 if ( !layer || !feature.
isValid() )
2638 if ( values.isEmpty() )
2639 layer = context->
variable( u
"layer"_s );
2640 else if ( values.count() == 1 )
2641 layer = values.at( 0 );
2644 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2648 bool foundLayer =
false;
2649 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2654 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2672 static QMap<QString, qlonglong> counterCache;
2673 QVariant functionResult;
2675 auto fetchAndIncrementFunc = [values, parent, &functionResult](
QgsMapLayer *mapLayer,
const QString &databaseArgument ) {
2678 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2683 database = decodedUri.value( u
"path"_s ).toString();
2684 if ( database.isEmpty() )
2686 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2691 database = databaseArgument;
2694 const QString table = values.at( 1 ).toString();
2695 const QString idColumn = values.at( 2 ).toString();
2696 const QString filterAttribute = values.at( 3 ).toString();
2697 const QVariant filterValue = values.at( 4 ).toString();
2698 const QVariantMap defaultValues = values.at( 5 ).toMap();
2704 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2707 functionResult = QVariant();
2711 QString errorMessage;
2712 QString currentValSql;
2714 qlonglong nextId = 0;
2715 bool cachedMode =
false;
2716 bool valueRetrieved =
false;
2718 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2725 auto cachedCounter = counterCache.find( cacheString );
2727 if ( cachedCounter != counterCache.end() )
2729 qlonglong &cachedValue = cachedCounter.value();
2730 nextId = cachedValue;
2732 cachedValue = nextId;
2733 valueRetrieved =
true;
2738 if ( !cachedMode || !valueRetrieved )
2740 int result = SQLITE_ERROR;
2743 if ( !filterAttribute.isNull() )
2748 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2750 if ( result == SQLITE_OK )
2753 if ( sqliteStatement.
step() == SQLITE_ROW )
2759 if ( cachedMode && result == SQLITE_OK )
2761 counterCache.insert( cacheString, nextId );
2763 QObject::connect( layer->
dataProvider()->
transaction(), &QgsTransaction::destroyed, [cacheString]() { counterCache.remove( cacheString ); } );
2765 valueRetrieved =
true;
2769 if ( valueRetrieved )
2778 if ( !filterAttribute.isNull() )
2784 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2787 vals << iter.value().toString();
2790 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2791 upsertSql +=
" VALUES "_L1;
2792 upsertSql +=
'(' + vals.join(
',' ) +
')';
2794 int result = SQLITE_ERROR;
2798 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2805 result = sqliteDb.
exec( upsertSql, errorMessage );
2807 if ( result == SQLITE_OK )
2809 functionResult = QVariant( nextId );
2814 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2815 functionResult = QVariant();
2820 functionResult = QVariant();
2823 bool foundLayer =
false;
2824 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer *layer ) { fetchAndIncrementFunc( layer, QString() ); }, foundLayer );
2827 const QString databasePath = values.at( 0 ).toString();
2831 return functionResult;
2844 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2849 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2852 return QVariant::fromValue( crs );
2857 QString concat(
"" );
2858 for (
const QVariant &value : values )
2861 concat += QgsExpressionUtils::getStringValue( value, parent );
2868 if ( values.length() < 2 )
2870 parent->
setEvalErrorString( QObject::tr(
"Function concat_ws requires at least 2 arguments" ) );
2874 const QString separator = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2876 QStringList stringValues;
2877 stringValues.reserve( values.size() - 1 );
2878 for (
int i = 1; i < values.size(); ++i )
2880 const QVariant value = values.at( i );
2883 stringValues.append( QgsExpressionUtils::getStringValue( value, parent ) );
2887 return stringValues.join( separator );
2892 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2893 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2901 if ( values.isEmpty() || values[0].isNull() )
2910 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2911 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2912 return string.right( pos );
2917 if ( values.length() < 2 || values.length() > 3 )
2920 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2921 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2923 bool overlapping =
false;
2924 if ( values.length() == 3 )
2926 overlapping = values.at( 2 ).toBool();
2929 if ( substring.isEmpty() )
2930 return QVariant( 0 );
2935 count = input.count( substring );
2940 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2943 pos += substring.length();
2947 return QVariant( count );
2952 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2953 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2954 return string.left( pos );
2959 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2960 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2961 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2962 return string.leftJustified( length, fill.at( 0 ),
true );
2967 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2968 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2969 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2970 return string.rightJustified( length, fill.at( 0 ),
true );
2975 if ( values.size() < 1 )
2977 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2981 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2982 for (
int n = 1; n < values.length(); n++ )
2984 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2992 return QVariant( QDateTime::currentDateTime() );
2997 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2998 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2999 if ( format.isEmpty() && !language.isEmpty() )
3001 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
3002 return QVariant( QDate() );
3005 if ( format.isEmpty() && language.isEmpty() )
3006 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
3008 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3009 QLocale locale = QLocale();
3010 if ( !language.isEmpty() )
3012 locale = QLocale( language );
3015 QDate date = locale.toDate( datestring, format );
3016 if ( !date.isValid() )
3018 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
3021 return QVariant( date );
3026 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3027 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3028 if ( format.isEmpty() && !language.isEmpty() )
3030 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
3031 return QVariant( QTime() );
3034 if ( format.isEmpty() && language.isEmpty() )
3035 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
3037 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3038 QLocale locale = QLocale();
3039 if ( !language.isEmpty() )
3041 locale = QLocale( language );
3044 QTime time = locale.toTime( timestring, format );
3045 if ( !time.isValid() )
3047 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
3050 return QVariant( time );
3055 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
3064 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3065 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3066 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3068 QString formatString;
3069 if ( values.count() > 3 )
3070 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
3073 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
3077 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
3081 else if ( !formatString.isEmpty() )
3083 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
3087 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
3091 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
3097 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
3105 return floatToDegreeFormat( format, values, context, parent, node );
3112 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
3114 return ok ? QVariant( value ) : QVariant();
3120 return floatToDegreeFormat( format, values, context, parent, node );
3125 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3126 return static_cast< int >( decimalDegrees );
3131 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3132 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3133 return static_cast< int >( remainder * 60 );
3138 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3139 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3140 const double remainderInMinutes = remainder * 60;
3141 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
3143 return remainderSecondsFraction * 60;
3148 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3149 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3150 qint64 seconds = d2.secsTo( d1 );
3151 return QVariant::fromValue(
QgsInterval( seconds ) );
3156 if ( !values.at( 0 ).canConvert<QDate>() )
3159 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
3160 if ( !date.isValid() )
3165 return date.dayOfWeek() % 7;
3170 QVariant value = values.at( 0 );
3171 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3174 return QVariant( inter.
days() );
3178 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3179 return QVariant( d1.date().day() );
3185 QVariant value = values.at( 0 );
3186 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3189 return QVariant( inter.
years() );
3193 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3194 return QVariant( d1.date().year() );
3200 QVariant value = values.at( 0 );
3201 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3204 return QVariant( inter.
months() );
3208 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3209 return QVariant( d1.date().month() );
3215 QVariant value = values.at( 0 );
3216 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3219 return QVariant( inter.
weeks() );
3223 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3224 return QVariant( d1.date().weekNumber() );
3230 QVariant value = values.at( 0 );
3231 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3234 return QVariant( inter.
hours() );
3238 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3239 return QVariant( t1.hour() );
3245 QVariant value = values.at( 0 );
3246 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3249 return QVariant( inter.
minutes() );
3253 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3254 return QVariant( t1.minute() );
3260 QVariant value = values.at( 0 );
3261 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3264 return QVariant( inter.
seconds() );
3268 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3269 return QVariant( t1.second() );
3275 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3278 return QVariant( dt.toMSecsSinceEpoch() );
3288 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3290 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3295 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3298 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3301 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3307 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3310 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3319 if ( !dateTime.isValid() )
3324 const int year = dateTime.date().year();
3325 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3326 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3327 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3328 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3329 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3334 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3335 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3338 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3341 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3346 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3351 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3356 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3361 double declination = 0;
3368 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3380 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3381 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3384 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3387 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3392 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3397 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3402 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3407 double inclination = 0;
3414 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3426 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3427 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3430 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3433 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3438 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3443 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3448 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3453 double declination = 0;
3461 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3471 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3477 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3483 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3488 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3495 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3496 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3499 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3502 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3507 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3512 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3517 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3522 double declination = 0;
3530 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3540 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3546 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3552 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3557 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3562#define ENSURE_GEOM_TYPE( f, g, geomtype ) \
3563 if ( !( f ).hasGeometry() ) \
3564 return QVariant(); \
3565 QgsGeometry g = ( f ).geometry(); \
3566 if ( ( g ).type() != ( geomtype ) ) \
3573 if ( g.isMultipart() )
3575 return g.asMultiPoint().at( 0 ).x();
3579 return g.asPoint().x();
3587 if ( g.isMultipart() )
3589 return g.asMultiPoint().at( 0 ).y();
3593 return g.asPoint().y();
3607 if ( g.isEmpty() || !abGeom->
is3D() )
3620 if ( collection->numGeometries() > 0 )
3633 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3639 return QVariant( isValid );
3644 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3648 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3649#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
3654 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3656 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3659 const bool keepCollapsed = values.value( 2 ).toBool();
3664 valid = geom.
makeValid( method, keepCollapsed );
3668 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3672 return QVariant::fromValue( valid );
3677 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3683 for (
int i = 0; i < multiGeom.size(); ++i )
3685 array += QVariant::fromValue( multiGeom.at( i ) );
3693 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3705 QVariant result( centroid.
asPoint().
x() );
3711 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3723 QVariant result( centroid.
asPoint().
y() );
3729 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3747 if ( collection->numGeometries() == 1 )
3760 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3778 if ( collection->numGeometries() == 1 )
3791 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3796 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3823 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3840 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3857 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3862 bool ignoreClosing =
false;
3863 if ( values.length() > 1 )
3865 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3875 bool skipLast =
false;
3876 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3881 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++i )
3893 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3904 for (
int i = 0; i < line->numPoints() - 1; ++i )
3918 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3928 if ( collection->numGeometries() == 1 )
3935 if ( !curvePolygon )
3939 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3945 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3951 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3961 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3967 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3973 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3982 return QVariant::fromValue(
QgsGeometry( boundary ) );
3987 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3996 return QVariant::fromValue( merged );
4001 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4005 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4010 if ( sharedPaths.
isNull() )
4013 return QVariant::fromValue( sharedPaths );
4019 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4024 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4027 if ( simplified.
isNull() )
4035 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4040 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4045 if ( simplified.
isNull() )
4053 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4058 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
4059 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
4060 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4061 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
4063 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
4072 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4077 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4078 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4079 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4090 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4095 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4096 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4097 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4098 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4099 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4110 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4115 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4116 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4117 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4128 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4133 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4134 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4135 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4136 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4137 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4148 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4153 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4154 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4155 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4166 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4171 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4172 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4173 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4174 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4175 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4186 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4191 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4192 QVector< double > dashPattern;
4193 dashPattern.reserve( pattern.size() );
4194 for (
const QVariant &value : std::as_const( pattern ) )
4197 double v = value.toDouble( &ok );
4209 if ( dashPattern.size() % 2 != 0 )
4211 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4215 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4217 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4219 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4221 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4223 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4225 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4229 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4233 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4235 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4237 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4239 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4241 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4243 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4247 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4251 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4253 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4255 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4257 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4261 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4265 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4276 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4281 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4283 if ( densified.
isNull() )
4291 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4296 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4298 if ( densified.
isNull() )
4307 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4309 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4316 QVector< QgsGeometry > parts;
4317 parts.reserve( list.size() );
4318 for (
const QVariant &value : std::as_const( list ) )
4320 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4331 if ( values.count() < 2 || values.count() > 4 )
4333 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4337 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4338 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4339 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4340 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4341 switch ( values.count() )
4355 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4356 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4357 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4363 if ( values.empty() )
4368 QVector<QgsPoint> points;
4369 points.reserve( values.count() );
4371 auto addPoint = [&points](
const QgsGeometry &geom ) {
4385 for (
const QVariant &value : values )
4387 if ( value.userType() == QMetaType::Type::QVariantList )
4389 const QVariantList list = value.toList();
4390 for (
const QVariant &v : list )
4392 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4397 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4401 if ( points.count() < 2 )
4409 if ( values.count() < 1 )
4411 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4415 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4423 auto polygon = std::make_unique< QgsPolygon >();
4437 if ( !exteriorRing )
4440 polygon->setExteriorRing( exteriorRing->
segmentize() );
4443 for (
int i = 1; i < values.count(); ++i )
4445 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4467 polygon->addInteriorRing( ring->
segmentize() );
4470 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4475 auto tr = std::make_unique<QgsTriangle>();
4476 auto lineString = std::make_unique<QgsLineString>();
4477 lineString->clear();
4479 for (
const QVariant &value : values )
4481 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4503 lineString->addVertex( *point );
4506 tr->setExteriorRing( lineString.release() );
4508 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4513 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4520 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4521 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4543 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4548 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4555 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4556 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4557 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4558 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4578 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4579 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4584 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4591 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4598 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4601 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4608 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4647 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4653 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4668 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4674 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4680 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4689 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4713 return QVariant::fromValue( geom.
vertexAt( idx ) );
4721 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4723 const QVariant v = pointAt( geom, idx, parent );
4726 return QVariant( v.value<
QgsPoint>().
x() );
4732 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4734 return fcnOldXat( values, f, parent, node );
4736 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4738 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4741 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4747 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4749 const QVariant v = pointAt( geom, vertexNumber, parent );
4751 return QVariant( v.value<
QgsPoint>().
x() );
4761 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4763 const QVariant v = pointAt( geom, idx, parent );
4766 return QVariant( v.value<
QgsPoint>().
y() );
4772 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4774 return fcnOldYat( values, f, parent, node );
4776 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4778 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4781 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4787 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4789 const QVariant v = pointAt( geom, vertexNumber, parent );
4791 return QVariant( v.value<
QgsPoint>().
y() );
4798 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4804 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4806 const QVariant v = pointAt( geom, vertexNumber, parent );
4808 return QVariant( v.value<
QgsPoint>().
z() );
4815 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4821 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4823 const QVariant v = pointAt( geom, vertexNumber, parent );
4825 return QVariant( v.value<
QgsPoint>().
m() );
4833 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4835 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4841 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4847 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4852 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4859 ogcContext.
layer = mapLayerPtr.data();
4864 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4879 return QVariant( area );
4883 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4895 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4900 return QVariant( geom.
area() );
4914 return QVariant( len );
4918 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4939 return QVariant( len );
4943 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4949 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4955 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4961 return QVariant( geom.
length() );
4966 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4972 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4981 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4990 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5006 if ( !curvePolygon )
5018 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5025 return QVariant( curvePolygon->
ringCount() );
5027 bool foundPoly =
false;
5036 if ( !curvePolygon )
5047 return QVariant( ringCount );
5052 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5054 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
5060 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5066 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5072 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5081 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5087 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5093 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5099 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5105 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5113 double max = std::numeric_limits< double >::lowest();
5117 double z = ( *it ).z();
5123 if ( max == std::numeric_limits< double >::lowest() )
5126 return QVariant( max );
5131 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5139 double min = std::numeric_limits< double >::max();
5143 double z = ( *it ).z();
5149 if ( min == std::numeric_limits< double >::max() )
5152 return QVariant( min );
5157 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5165 double min = std::numeric_limits< double >::max();
5169 double m = ( *it ).m();
5175 if ( min == std::numeric_limits< double >::max() )
5178 return QVariant( min );
5183 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5191 double max = std::numeric_limits< double >::lowest();
5195 double m = ( *it ).m();
5201 if ( max == std::numeric_limits< double >::lowest() )
5204 return QVariant( max );
5209 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5213 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5222 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5226 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5235 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5240 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5250 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5254 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5256 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5261 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5280 return QVariant::fromValue( curve->
isClosed() );
5285 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5298 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5299 closedLine->close();
5301 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5315 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5316 closedLine->close();
5318 closed->addGeometry( closedLine.release() );
5321 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5329 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5333 return QVariant::fromValue( fGeom.
isEmpty() );
5339 return QVariant::fromValue(
true );
5341 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5342 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5347 if ( values.length() < 2 || values.length() > 3 )
5350 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5351 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5358 if ( values.length() == 2 )
5361 QString result = engine->relate( sGeom.
constGet() );
5362 return QVariant::fromValue( result );
5367 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5368 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5369 return QVariant::fromValue( result );
5375 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5376 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5381 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5382 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5383 return fGeom.
disjoint( 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.
intersects( 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.
touches( sGeom ) ? TVL_True : TVL_False;
5399 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5400 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5401 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5405 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5406 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5407 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5411 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5412 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5413 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5417 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5418 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5419 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5424 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5425 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5431 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5432 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5433 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5438 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5440 QVariant ret = TVL_False;
5443 ret = fGeom.
isExactlyEqual( sGeom, backend ) ? TVL_True : TVL_False;
5454 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5455 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5456 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5461 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5463 QVariant ret = TVL_False;
5477 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5478 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5479 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5484 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5486 double epsilon = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5488 QVariant ret = TVL_False;
5491 ret = fGeom.
isFuzzyEqual( sGeom, epsilon, backend ) ? TVL_True : TVL_False;
5502 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5503 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5504 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5505 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5506 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5507 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5510 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5512 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5516 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5518 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5522 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5528 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5530 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5535 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5537 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5542 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5544 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5549 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5564 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5568 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5569 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5570 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5571 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5574 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5580 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5583 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5587 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5588 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5589 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5592 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5598 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5601 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5605 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5608 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5614 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5615 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5616 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5617 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5618 if ( joinInt < 1 || joinInt > 3 )
5622 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5625 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5631 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5632 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5633 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5635 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5636 if ( joinInt < 1 || joinInt > 3 )
5640 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5643 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5649 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5650 const double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5651 const double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5653 const double deflectionStart = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5654 const double deflectionEnd = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5657 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5663 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5664 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5665 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5667 return QVariant::fromValue( fGeom );
5672 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5673 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5675 const bool perPart = values.value( 3 ).toBool();
5682 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5683 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5685 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5686 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5687 t.rotate( -rotation );
5688 t.translate( -partCenter.x(), -partCenter.y() );
5689 ( *it )->transform( t );
5691 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5703 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5711 fGeom.
rotate( rotation, pt );
5712 return QVariant::fromValue( fGeom );
5718 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5719 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5720 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5721 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent ) :
QgsGeometry();
5727 pt = fGeom.boundingBox().center();
5731 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5736 pt = center.asPoint();
5739 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5740 t.scale( xScale, yScale );
5741 t.translate( -pt.
x(), -pt.
y() );
5743 return QVariant::fromValue( fGeom );
5748 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5754 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5755 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5757 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5759 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5760 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5762 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5763 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5764 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5765 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5776 QTransform transform;
5777 transform.translate( deltaX, deltaY );
5778 transform.rotate( rotationZ );
5779 transform.scale( scaleX, scaleY );
5780 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5782 return QVariant::fromValue( fGeom );
5788 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5790 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5795 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5797 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5803 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5804 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5806 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5812 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5814 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5818#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
5823 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5824 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5825 const bool allowHoles = values.value( 2 ).toBool();
5827 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5840 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5842 if ( values.length() == 2 )
5843 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5851 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5857 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5859 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5865 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5871 double area,
angle, width, height;
5884 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5885 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5887 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5898 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5909 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5919 reversed->addGeometry( curve->
reversed() );
5926 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5932 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5933 std::reverse(
string.begin(),
string.end() );
5939 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5959 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5965 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5966 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5967 return QVariant( fGeom.
distance( sGeom ) );
5972 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5973 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5976 if ( values.length() == 3 && values.at( 2 ).isValid() )
5978 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5979 densify = std::clamp( densify, 0.0, 1.0 );
5987 return res > -1 ? QVariant( res ) : QVariant();
5992 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5993 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5995 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6000 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6001 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6003 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6008 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6009 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6011 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6017 if ( values.length() < 1 || values.length() > 2 )
6020 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6022 if ( values.length() == 2 )
6023 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6024 QString wkt = fGeom.
asWkt( prec );
6025 return QVariant( wkt );
6030 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6031 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
6036 if ( values.length() != 2 )
6038 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
6042 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6043 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6071 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
6078 if ( pt1->
y() < pt2->
y() )
6080 else if ( pt1->
y() > pt2->
y() )
6088 if ( pt1->
x() < pt2->
x() )
6090 else if ( pt1->
x() > pt2->
x() )
6091 return M_PI + ( M_PI_2 );
6096 if ( pt1->
x() < pt2->
x() )
6098 if ( pt1->
y() < pt2->
y() )
6100 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
6104 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI_2 );
6110 if ( pt1->
y() > pt2->
y() )
6112 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) ) + M_PI;
6116 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI + ( M_PI_2 ) );
6123 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6124 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6126 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
6130 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
6138 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
6152 if ( ellipsoid.isEmpty() )
6154 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
6160 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
6168 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
6174 const double bearing = da.
bearing( point1, point2 );
6175 if ( std::isfinite( bearing ) )
6177 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
6190 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6198 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6199 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6200 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
6203 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6210 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6211 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6238 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6247 if ( values.length() != 3 )
6250 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6251 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6252 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6256 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6262 if ( values.length() < 2 )
6265 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6268 return values.at( 0 );
6270 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6271 QVariant cachedExpression;
6276 if ( cachedExpression.isValid() )
6283 bool asc = values.value( 2 ).toBool();
6301 Q_ASSERT( collection );
6305 QgsExpressionSorter sorter( orderBy );
6307 QList<QgsFeature> partFeatures;
6308 partFeatures.reserve( collection->
partCount() );
6309 for (
int i = 0; i < collection->
partCount(); ++i )
6315 sorter.sortFeatures( partFeatures, unconstedContext );
6319 Q_ASSERT( orderedGeom );
6324 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6329 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6332 delete unconstedContext;
6339 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6340 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6344 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6350 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6351 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6355 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6361 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6362 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6366 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6372 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6373 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6374 const bool use3DDistance = values.at( 2 ).toBool();
6376 double x, y, z, distance;
6399 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6402 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6422 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6423 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6425 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6427 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6432 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6433 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6440 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6441 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6446 vertex = count + vertex;
6454 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6455 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6460 vertex = count + vertex;
6468 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6469 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6473 return distance >= 0 ? distance : QVariant();
6478 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6479 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6480 const bool use3DDistance = values.at( 2 ).toBool();
6482 double x, y, z, distance;
6491 return found ? distance : QVariant();
6496 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6498 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6499 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6502 if ( values.length() >= 1 )
6504 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6505 return QVariant( qlonglong( std::round( number ) ) );
6520 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6521 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6522 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6529 const bool omitGroupSeparator = values.value( 3 ).toBool();
6530 const bool trimTrailingZeros = values.value( 4 ).toBool();
6532 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6533 if ( !omitGroupSeparator )
6534 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6536 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6538 QString res = locale.toString( value,
'f', places );
6540 if ( trimTrailingZeros )
6542 const QChar decimal = locale.decimalPoint().at( 0 );
6543 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6545 if ( res.contains( decimal ) )
6547 int trimPoint = res.length() - 1;
6549 while ( res.at( trimPoint ) == zeroDigit )
6552 if ( res.at( trimPoint ) == decimal )
6555 res.truncate( trimPoint + 1 );
6564 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6565 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6566 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6569 if ( format.indexOf(
"Z" ) > 0 )
6570 datetime = datetime.toUTC();
6572 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6573 return locale.toString( datetime, format );
6578 const QVariant variant = values.at( 0 );
6580 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6581 if ( !color.isValid() )
6584 const float alpha = color.alphaF();
6585 if ( color.spec() == QColor::Spec::Cmyk )
6587 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() )
6589 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6593 const float avg = ( color.redF() + color.greenF() + color.blueF() )
6595 color.setRgbF( avg, avg, avg, alpha );
6598 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6605 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6610 else if ( ratio < 0 )
6615 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6616 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6617 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6618 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6620 QColor newColor( red, green, blue, alpha );
6627 const QVariant variant1 = values.at( 0 );
6628 const QVariant variant2 = values.at( 1 );
6630 if ( variant1.userType() != variant2.userType() )
6632 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6637 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6638 if ( !color1.isValid() )
6641 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6642 if ( !color2.isValid() )
6645 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6647 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6651 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6657 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6658 if ( color1.spec() == QColor::Spec::Cmyk )
6660 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6661 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6662 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6663 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6664 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6668 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6669 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6670 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6671 newColor = QColor::fromRgbF( red, green, blue, alpha );
6676 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6681 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6682 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6683 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6684 QColor color = QColor( red, green, blue );
6685 if ( !color.isValid() )
6687 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6688 color = QColor( 0, 0, 0 );
6691 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6696 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6697 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6698 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6699 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6700 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6701 if ( !color.isValid() )
6703 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6712 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6713 QVariant value = node->
eval( parent, context );
6717 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6719 value = node->
eval( parent, context );
6727 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6729 QVariant value = node->
eval( parent, context );
6731 if ( value.toBool() )
6733 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6735 value = node->
eval( parent, context );
6740 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6742 value = node->
eval( parent, context );
6750 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6751 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6752 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6753 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6754 QColor color = QColor( red, green, blue, alpha );
6755 if ( !color.isValid() )
6757 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6758 color = QColor( 0, 0, 0 );
6767 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6769 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6774 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6778 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6783 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6784 QColor color = ramp->
color( value );
6797 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6799 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6801 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6803 QColor color = QColor::fromHslF( hue, saturation, lightness );
6805 if ( !color.isValid() )
6807 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6808 color = QColor( 0, 0, 0 );
6811 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6817 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6819 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6821 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6823 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6825 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6826 if ( !color.isValid() )
6828 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6829 color = QColor( 0, 0, 0 );
6836 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6837 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6838 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6839 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6841 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6842 if ( !color.isValid() )
6844 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6854 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6856 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6858 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6860 QColor color = QColor::fromHsvF( hue, saturation, value );
6862 if ( !color.isValid() )
6864 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6865 color = QColor( 0, 0, 0 );
6868 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6874 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6876 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6878 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6880 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6882 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6883 if ( !color.isValid() )
6885 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6886 color = QColor( 0, 0, 0 );
6893 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6894 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6895 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6896 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6897 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6899 if ( !color.isValid() )
6901 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6910 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6911 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6912 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6913 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6914 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6916 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6917 if ( !color.isValid() )
6919 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6929 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6931 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6933 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6935 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6937 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6939 if ( !color.isValid() )
6941 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6942 color = QColor( 0, 0, 0 );
6945 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6951 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6953 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6955 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6957 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6959 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6961 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6962 if ( !color.isValid() )
6964 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6965 color = QColor( 0, 0, 0 );
6972 const QVariant variant = values.at( 0 );
6974 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6975 if ( !color.isValid() )
6978 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6979 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6981 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6982 return color.green();
6983 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6984 return color.blue();
6985 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6986 return color.alpha();
6987 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6988 return static_cast< double >( color.hsvHueF() * 360 );
6989 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6990 return static_cast< double >( color.hsvSaturationF() * 100 );
6991 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6992 return static_cast< double >( color.valueF() * 100 );
6993 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6994 return static_cast< double >( color.hslHueF() * 360 );
6995 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6996 return static_cast< double >( color.hslSaturationF() * 100 );
6997 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6998 return static_cast< double >( color.lightnessF() * 100 );
6999 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7000 return static_cast< double >( color.cyanF() * 100 );
7001 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7002 return static_cast< double >( color.magentaF() * 100 );
7003 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7004 return static_cast< double >( color.yellowF() * 100 );
7005 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7006 return static_cast< double >( color.blackF() * 100 );
7008 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7014 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7017 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
7021 QList< QColor > colors;
7023 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7026 if ( !colors.last().isValid() )
7028 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
7032 double step = it.key().toDouble();
7033 if ( it == map.constBegin() )
7038 else if ( it == map.constEnd() )
7048 bool discrete = values.at( 1 ).toBool();
7050 if ( colors.empty() )
7053 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
7058 const QVariant variant = values.at( 0 );
7060 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7061 if ( !color.isValid() )
7064 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7065 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7066 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7067 color.setRed( std::clamp( value, 0, 255 ) );
7068 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7069 color.setGreen( std::clamp( value, 0, 255 ) );
7070 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7071 color.setBlue( std::clamp( value, 0, 255 ) );
7072 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7073 color.setAlpha( std::clamp( value, 0, 255 ) );
7074 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7075 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
7076 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7077 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
7078 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7079 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7080 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7081 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
7082 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7083 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
7084 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7085 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7086 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7087 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
7088 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7089 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
7090 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7091 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
7092 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7093 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7096 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7099 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7104 const QVariant variant = values.at( 0 );
7106 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7107 if ( !color.isValid() )
7110 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7112 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7117 const QVariant variant = values.at( 0 );
7119 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7120 if ( !color.isValid() )
7123 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7125 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7130 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7133 return QVariant::fromValue( geom );
7139 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7147 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
7152 return QVariant::fromValue( fGeom );
7155 return QVariant::fromValue( fGeom );
7164 return QVariant::fromValue( fGeom );
7177 bool foundLayer =
false;
7178 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7181 if ( !featureSource || !foundLayer )
7186 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
7199 result = QVariant::fromValue( fet );
7207 bool foundLayer =
false;
7208 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7211 if ( !featureSource || !foundLayer )
7216 QString cacheValueKey;
7217 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7219 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7221 QMap<QString, QVariant>::const_iterator i = attributeMap.constBegin();
7222 QString filterString;
7223 for ( ; i != attributeMap.constEnd(); ++i )
7225 if ( !filterString.isEmpty() )
7227 filterString.append(
" AND " );
7231 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7240 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7241 int attributeId = featureSource->fields().lookupField( attribute );
7242 if ( attributeId == -1 )
7247 const QVariant &attVal = values.at( 2 );
7249 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7272 res = QVariant::fromValue( fet );
7287 if ( !values.isEmpty() )
7290 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7291 fieldName = col->
name();
7292 else if ( values.size() == 2 )
7293 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7296 QVariant value = values.at( 0 );
7301 if ( fieldIndex == -1 )
7303 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7309 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7312 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7321 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7339 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7347 const QVariant data = values.at( 0 );
7348 const QMimeDatabase db;
7349 return db.mimeTypeForData( data.toByteArray() ).name();
7354 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7356 bool translate =
true;
7357 if ( values.length() >= 3 )
7359 translate = QgsExpressionUtils::getTVLValue( values.at( 2 ), parent ) == QgsExpressionUtils::TVL::True;
7362 bool foundLayer =
false;
7363 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7367 [layerProperty, translate](
QgsMapLayer *layer ) -> QVariant {
7372 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7373 return layer->name();
7374 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7376 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7377 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7378 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7379 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7380 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7382 QStringList keywords;
7383 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7384 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7386 keywords.append( it.value() );
7388 if ( !keywords.isEmpty() )
7390 return layer->serverProperties()->keywordList();
7392 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7394 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7396 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7398 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7400 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7402 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7404 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7406 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7408 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7410 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7412 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7414 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7416 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7419 QVariant result = QVariant::fromValue( extentGeom );
7422 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7424 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7427 return decodedUri.value( u
"path"_s );
7429 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7431 switch ( layer->
type() )
7434 return translate ? QCoreApplication::translate(
"expressions",
"Vector" ) : u
"Vector"_s;
7436 return translate ? QCoreApplication::translate(
"expressions",
"Raster" ) : u
"Raster"_s;
7438 return translate ? QCoreApplication::translate(
"expressions",
"Mesh" ) : u
"Mesh"_s;
7440 return translate ? QCoreApplication::translate(
"expressions",
"Vector Tile" ) : u
"Vector Tile"_s;
7442 return translate ? QCoreApplication::translate(
"expressions",
"Plugin" ) : u
"Plugin"_s;
7444 return translate ? QCoreApplication::translate(
"expressions",
"Annotation" ) : u
"Annotation"_s;
7446 return translate ? QCoreApplication::translate(
"expressions",
"Point Cloud" ) : u
"Point Cloud"_s;
7448 return translate ? QCoreApplication::translate(
"expressions",
"Group" ) : u
"Group"_s;
7450 return translate ? QCoreApplication::translate(
"expressions",
"Tiled Scene" ) : u
"Tiled Scene"_s;
7456 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7459 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7461 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7463 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7481 const QString uriPart = values.at( 1 ).toString();
7483 bool foundLayer =
false;
7485 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7489 [parent, uriPart](
QgsMapLayer *layer ) -> QVariant {
7490 if ( !layer->dataProvider() )
7492 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7498 if ( !uriPart.isNull() )
7500 return decodedUri.value( uriPart );
7512 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7523 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7524 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7526 bool foundLayer =
false;
7527 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7531 [parent, band, layerProperty](
QgsMapLayer *layer ) -> QVariant {
7532 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7536 if ( band < 1 || band > rl->bandCount() )
7538 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7544 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7546 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7548 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7550 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7552 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7554 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7558 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7588 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7605 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7606 bool ascending = values.value( 1 ).toBool();
7607 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7613 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7618 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7623 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7628 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7629 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7631 for (
const auto &item : listB )
7633 if ( listA.contains( item ) )
7637 return QVariant( match == listB.count() );
7642 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7647 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7648 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7649 if ( pos < list.length() && pos >= 0 )
7650 return list.at( pos );
7651 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7652 return list.at( list.length() + pos );
7658 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7659 return list.value( 0 );
7664 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7665 return list.value( list.size() - 1 );
7670 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7671 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7676 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7677 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7682 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7685 for (
const QVariant &item : list )
7687 switch ( item.userType() )
7689 case QMetaType::Int:
7690 case QMetaType::UInt:
7691 case QMetaType::LongLong:
7692 case QMetaType::ULongLong:
7693 case QMetaType::Float:
7694 case QMetaType::Double:
7695 total += item.toDouble();
7700 return i == 0 ? QVariant() : total / i;
7705 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7706 QVariantList numbers;
7707 for (
const auto &item : list )
7709 switch ( item.userType() )
7711 case QMetaType::Int:
7712 case QMetaType::UInt:
7713 case QMetaType::LongLong:
7714 case QMetaType::ULongLong:
7715 case QMetaType::Float:
7716 case QMetaType::Double:
7717 numbers.append( item );
7721 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7722 const int count = numbers.count();
7727 else if ( count % 2 )
7729 return numbers.at( count / 2 );
7733 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7739 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7742 for (
const QVariant &item : list )
7744 switch ( item.userType() )
7746 case QMetaType::Int:
7747 case QMetaType::UInt:
7748 case QMetaType::LongLong:
7749 case QMetaType::ULongLong:
7750 case QMetaType::Float:
7751 case QMetaType::Double:
7752 total += item.toDouble();
7757 return i == 0 ? QVariant() : total;
7760static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7762 QVariant result = value;
7763 ( void ) result.convert(
static_cast<int>( type ) );
7769 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7770 QHash< QVariant, int > hash;
7771 for (
const auto &item : list )
7775 const QList< int > occurrences = hash.values();
7776 if ( occurrences.empty() )
7777 return QVariantList();
7779 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7781 const QString option = values.at( 1 ).toString();
7782 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7784 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7786 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7788 if ( hash.isEmpty() )
7791 return QVariant( hash.key( maxValue ) );
7793 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7795 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7797 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7799 if ( maxValue * 2 <= list.size() )
7802 return QVariant( hash.key( maxValue ) );
7813 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7814 QHash< QVariant, int > hash;
7815 for (
const auto &item : list )
7819 const QList< int > occurrences = hash.values();
7820 if ( occurrences.empty() )
7821 return QVariantList();
7823 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7825 const QString option = values.at( 1 ).toString();
7826 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7828 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7830 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7832 if ( hash.isEmpty() )
7835 return QVariant( hash.key( minValue ) );
7837 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7839 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7841 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7843 if ( hash.isEmpty() )
7847 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7848 if ( maxValue * 2 > list.size() )
7849 hash.remove( hash.key( maxValue ) );
7851 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7862 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7863 list.append( values.at( 1 ) );
7864 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7869 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7870 list.prepend( values.at( 1 ) );
7871 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7876 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7877 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7878 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7883 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7884 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7886 position = position + list.length();
7887 if ( position >= 0 && position < list.length() )
7888 list.removeAt( position );
7889 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7897 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7899 const QVariant toRemove = values.at( 1 );
7902 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant &element ) { return QgsVariantUtils::isNull( element ); } ), list.end() );
7906 list.removeAll( toRemove );
7908 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7913 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7915 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7917 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7918 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7920 int index = list.indexOf( it.key() );
7921 while ( index >= 0 )
7923 list.replace( index, it.value() );
7924 index = list.indexOf( it.key() );
7928 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7930 else if ( values.count() == 3 )
7932 QVariantList before;
7934 bool isSingleReplacement =
false;
7936 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7938 before = QVariantList() << values.at( 1 );
7942 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7945 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7947 after = QVariantList() << values.at( 2 );
7948 isSingleReplacement =
true;
7952 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7955 if ( !isSingleReplacement && before.length() != after.length() )
7957 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7961 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7962 for (
int i = 0; i < before.length(); i++ )
7964 int index = list.indexOf( before.at( i ) );
7965 while ( index >= 0 )
7967 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7968 index = list.indexOf( before.at( i ) );
7972 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7976 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7983 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7984 QVariantList list_new;
7986 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
7988 while ( list.removeOne( cur ) )
7990 list_new.append( cur );
7994 list_new.append( list );
7996 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8002 for (
const QVariant &cur : values )
8004 list += QgsExpressionUtils::getListValue( cur, parent );
8006 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8011 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8012 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
8013 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
8014 int slice_length = 0;
8016 if ( start_pos < 0 )
8018 start_pos = list.length() + start_pos;
8022 slice_length = end_pos - start_pos + 1;
8026 slice_length = list.length() + end_pos - start_pos + 1;
8029 if ( slice_length < 0 )
8033 list = list.mid( start_pos, slice_length );
8039 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8040 std::reverse( list.begin(), list.end() );
8046 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8047 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
8048 for (
const QVariant &cur : array2 )
8050 if ( array1.contains( cur ) )
8051 return QVariant(
true );
8053 return QVariant(
false );
8058 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8060 QVariantList distinct;
8062 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8064 if ( !distinct.contains( *it ) )
8066 distinct += ( *it );
8075 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8076 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8077 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8081 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8083 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
8084 if ( it != ( array.constEnd() - 1 ) )
8090 return QVariant( str );
8095 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8096 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8097 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8099 QStringList list = str.split( delimiter );
8102 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
8104 array += ( !( *it ).isEmpty() ) ? *it : empty;
8112 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8113 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
8114 if ( document.isNull() )
8117 return document.toVariant();
8123 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
8124 return QString( document.toJson( QJsonDocument::Compact ) );
8129 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8130 if ( str.isEmpty() )
8131 return QVariantMap();
8132 str = str.trimmed();
8139 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8146 for (
int i = 0; i + 1 < values.length(); i += 2 )
8148 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
8155 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8156 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8157 QVariantMap resultMap;
8159 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8161 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
8169 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
8174 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
8179 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8180 map.remove( values.at( 1 ).toString() );
8186 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8187 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
8194 for (
const QVariant &cur : values )
8196 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
8197 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
8198 result.insert( it.key(), it.value() );
8205 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
8210 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
8215 const QString envVarName = values.at( 0 ).toString();
8216 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
8219 return QProcessEnvironment::systemEnvironment().value( envVarName );
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(
"base_file_name"_L1 ) );
8230 return QFileInfo( file ).completeBaseName();
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(
"file_suffix"_L1 ) );
8241 return QFileInfo( file ).completeSuffix();
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(
"file_exists"_L1 ) );
8252 return QFileInfo::exists( file );
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_name"_L1 ) );
8263 return QFileInfo( file ).fileName();
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(
"is_file"_L1 ) );
8274 return QFileInfo( file ).isFile();
8279 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8282 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8285 return QFileInfo( file ).isDir();
8290 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8293 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8296 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8301 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8304 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8307 return QFileInfo( file ).size();
8310static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8312 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8318 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8319 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8321 if ( method ==
"md4"_L1 )
8323 hash = fcnHash( str, QCryptographicHash::Md4 );
8325 else if ( method ==
"md5"_L1 )
8327 hash = fcnHash( str, QCryptographicHash::Md5 );
8329 else if ( method ==
"sha1"_L1 )
8331 hash = fcnHash( str, QCryptographicHash::Sha1 );
8333 else if ( method ==
"sha224"_L1 )
8335 hash = fcnHash( str, QCryptographicHash::Sha224 );
8337 else if ( method ==
"sha256"_L1 )
8339 hash = fcnHash( str, QCryptographicHash::Sha256 );
8341 else if ( method ==
"sha384"_L1 )
8343 hash = fcnHash( str, QCryptographicHash::Sha384 );
8345 else if ( method ==
"sha512"_L1 )
8347 hash = fcnHash( str, QCryptographicHash::Sha512 );
8349 else if ( method ==
"sha3_224"_L1 )
8351 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8353 else if ( method ==
"sha3_256"_L1 )
8355 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8357 else if ( method ==
"sha3_384"_L1 )
8359 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8361 else if ( method ==
"sha3_512"_L1 )
8363 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8365 else if ( method ==
"keccak_224"_L1 )
8367 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8369 else if ( method ==
"keccak_256"_L1 )
8371 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8373 else if ( method ==
"keccak_384"_L1 )
8375 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8377 else if ( method ==
"keccak_512"_L1 )
8379 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8383 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8390 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8395 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8400 const QByteArray input = values.at( 0 ).toByteArray();
8401 return QVariant( QString( input.toBase64() ) );
8406 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8408 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8410 query.addQueryItem( it.key(), it.value().toString() );
8412 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8417 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8418 const QByteArray base64 = value.toLocal8Bit();
8419 const QByteArray decoded = QByteArray::fromBase64( base64 );
8420 return QVariant( decoded );
8426static QVariant executeGeomOverlay(
8427 const QVariantList &values,
8431 bool invert =
false,
8432 double bboxGrow = 0,
8433 bool isNearestFunc =
false,
8434 bool isIntersectsFunc =
false
8439 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8443 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8446 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8455 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8458 const bool layerCanBeCached = node->
isStatic( parent, context );
8459 QVariant targetLayerValue = node->
eval( parent, context );
8463 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8465 QString subExpString = node->dump();
8467 bool testOnly = ( subExpString ==
"NULL" );
8470 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8474 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8479 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8481 QString filterString = node->dump();
8482 if ( filterString !=
"NULL" )
8484 request.setFilterExpression( filterString );
8488 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8490 QVariant limitValue = node->eval( parent, context );
8492 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8494 double max_distance = 0;
8495 bool cacheEnabled =
false;
8497 double minOverlap { -1 };
8498 double minInscribedCircleRadius { -1 };
8499 bool returnDetails =
false;
8500 bool sortByMeasure =
false;
8501 bool sortAscending =
false;
8502 bool requireMeasures =
false;
8503 bool overlapOrRadiusFilter =
false;
8507 if ( isNearestFunc )
8510 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8512 QVariant distanceValue = node->eval( parent, context );
8514 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8517 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8519 QVariant cacheValue = node->eval( parent, context );
8521 cacheEnabled = cacheValue.toBool();
8526 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8528 QVariant cacheValue = node->eval( parent, context );
8530 cacheEnabled = cacheValue.toBool();
8533 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8535 const QVariant minOverlapValue = node->eval( parent, context );
8537 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8540 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8542 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8544 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8547 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8549 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8552 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8554 const QString sorting { node->eval( parent, context ).toString().toLower() };
8555 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8556 sortAscending = sorting.startsWith(
"asc" );
8557 requireMeasures = sortByMeasure || returnDetails;
8558 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8561 node = QgsExpressionUtils::getNode( values.at( 9 ), parent );
8563 const QString backendStr = node->eval( parent, context ).toString().toUpper();
8569 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
8575 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8578 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8581 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8584 if ( bboxGrow != 0 )
8586 intDomain.
grow( bboxGrow );
8589 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8595 QList<QgsFeature> features;
8596 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8600 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8601 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8605 cachedTarget = targetLayer->
materialize( request );
8606 if ( layerCanBeCached )
8607 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8617 if ( layerCanBeCached )
8618 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8625 QList<QgsFeatureId> fidsList;
8626 if ( isNearestFunc )
8628 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8632 fidsList = spatialIndex.
intersects( intDomain );
8635 QListIterator<QgsFeatureId> i( fidsList );
8636 while ( i.hasNext() )
8639 if ( sameLayers && feat.
id() == fId2 )
8641 features.append( cachedTarget->
getFeature( fId2 ) );
8648 request.setFilterRect( intDomain );
8653 if ( sameLayers && feat.
id() == feat2.
id() )
8655 features.append( feat2 );
8663 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8664 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8670 subExpression.
prepare( &subContext );
8683 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double &overlapValue ) ->
bool {
8684 bool testResult {
false };
8686 QVector<double> overlapValues;
8687 const QgsGeometry merged { intersection.mergeLines() };
8692 if ( minOverlap != -1 || requireMeasures )
8694 overlapValue = geom->
length();
8695 overlapValues.append( overlapValue );
8696 if ( minOverlap != -1 )
8698 if ( overlapValue >= minOverlap )
8710 if ( !overlapValues.isEmpty() )
8712 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8719 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double &radiusValue,
double &overlapValue ) ->
bool {
8721 bool testResult {
false };
8723 QVector<double> overlapValues;
8724 QVector<double> radiusValues;
8725 for (
auto it = intersection.const_parts_begin(); ( !testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8729 if ( minOverlap != -1 || requireMeasures )
8731 overlapValue = geom->
area();
8732 overlapValues.append( geom->
area() );
8733 if ( minOverlap != -1 )
8735 if ( overlapValue >= minOverlap )
8747 if ( minInscribedCircleRadius != -1 || requireMeasures )
8750 const double width = bbox.
width();
8751 const double height = bbox.
height();
8752 const double size = width > height ? width : height;
8753 const double tolerance = size / 100.0;
8755 testResult = radiusValue >= minInscribedCircleRadius;
8756 radiusValues.append( radiusValues );
8761 if ( !radiusValues.isEmpty() )
8763 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8766 if ( !overlapValues.isEmpty() )
8768 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8777 QVariantList results;
8779 QListIterator<QgsFeature> i( features );
8782 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8787 if ( relationFunction( geometry, feat2.
geometry(), values, backend ) )
8789 double overlapValue = -1;
8790 double radiusValue = -1;
8792 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8804 for (
const auto &geom : std::as_const( geometries ) )
8806 switch ( geom.type() )
8810 poly.append( geom.asPolygon() );
8815 line.append( geom.asPolyline() );
8820 point.append( geom.asPoint() );
8831 switch ( geometry.
type() )
8859 switch ( intersection.
type() )
8864 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8866 if ( !testResult && overlapOrRadiusFilter )
8878 if ( minInscribedCircleRadius != -1 )
8884 const bool testResult { testLinestring( intersection, overlapValue ) };
8886 if ( !testResult && overlapOrRadiusFilter )
8898 if ( minInscribedCircleRadius != -1 )
8903 bool testResult {
false };
8904 if ( minOverlap != -1 || requireMeasures )
8924 testResult = testLinestring( feat2.
geometry(), overlapValue );
8929 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8935 if ( !testResult && overlapOrRadiusFilter )
8962 const QVariant expResult = subExpression.
evaluate( &subContext );
8964 if ( requireMeasures )
8966 QVariantMap resultRecord;
8967 resultRecord.insert( u
"id"_s, feat2.
id() );
8968 resultRecord.insert( u
"result"_s, expResult );
8970 resultRecord.insert( u
"overlap"_s, overlapValue );
8972 if ( radiusValue != -1 )
8974 resultRecord.insert( u
"radius"_s, radiusValue );
8976 results.append( resultRecord );
8980 results.append( expResult );
8986 results.append( feat2.
id() );
9006 if ( requireMeasures )
9008 if ( sortByMeasure )
9010 std::sort( results.begin(), results.end(), [sortAscending](
const QVariant &recordA,
const QVariant &recordB ) ->
bool {
9011 return sortAscending ? recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
9012 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
9016 if ( limit > 0 && results.size() > limit )
9018 results.erase( results.begin() + limit );
9021 if ( !returnDetails )
9023 QVariantList expResults;
9024 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
9026 expResults.append( it->toMap().value( u
"result"_s ) );
9036 QVariantList disjoint_results;
9045 if ( !results.contains( feat2.
id() ) )
9048 disjoint_results.append( subExpression.
evaluate( &subContext ) );
9051 return disjoint_results;
9059 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
false,
true );
9065 return executeGeomOverlay( values, context, parent, geomFunction );
9071 return executeGeomOverlay( values, context, parent, geomFunction );
9079 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9087 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9095 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9101 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 10 ), parent );
9103 QVariant epsilonValue = node->
eval( parent, context );
9105 double epsilon = QgsExpressionUtils::getDoubleValue( epsilonValue, parent );
9108 return geometry.
isFuzzyEqual( other, epsilon, backend );
9110 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9116 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9122 return executeGeomOverlay( values, context, parent, geomFunction );
9128 return executeGeomOverlay( values, context, parent, geomFunction,
true, 0,
false,
true );
9136 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
true );
9145 QMutexLocker locker( &sFunctionsMutex );
9147 QList<QgsExpressionFunction *> &functions = *sFunctions();
9149 if ( functions.isEmpty() )
9152 << QgsExpressionFunction::Parameter( u
"expression"_s )
9153 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
9154 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
9157 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true ) << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9160 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9166 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnAzimuth, u
"GeometryGroup"_s )
9167 <<
new QgsStaticExpressionFunction(
9170 << QgsExpressionFunction::Parameter( u
"point1"_s )
9171 << QgsExpressionFunction::Parameter( u
"point2"_s )
9172 << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() )
9173 << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ),
9177 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnInclination, u
"GeometryGroup"_s )
9178 <<
new QgsStaticExpressionFunction(
9181 << QgsExpressionFunction::Parameter( u
"point"_s )
9182 << QgsExpressionFunction::Parameter( u
"distance"_s )
9183 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9184 << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ),
9195 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
9199 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
9200 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
9202 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction(
9204 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9209 functions << randFunc;
9211 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction(
9214 << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 )
9215 << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 )
9216 << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9221 functions << randfFunc;
9224 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9225 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9226 <<
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 )
9227 <<
new QgsStaticExpressionFunction(
9230 << QgsExpressionFunction::Parameter( u
"value"_s )
9231 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9232 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9233 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9234 << QgsExpressionFunction::Parameter( u
"range_max"_s ),
9238 <<
new QgsStaticExpressionFunction(
9239 u
"scale_polynomial"_s,
9241 << QgsExpressionFunction::Parameter( u
"value"_s )
9242 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9243 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9244 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9245 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9246 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9253 QStringList() << u
"scale_exp"_s
9255 <<
new QgsStaticExpressionFunction(
9256 u
"scale_exponential"_s,
9258 << QgsExpressionFunction::Parameter( u
"value"_s )
9259 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9260 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9261 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9262 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9263 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9264 fcnExponentialScale,
9267 <<
new QgsStaticExpressionFunction(
9268 u
"scale_cubic_bezier"_s,
9270 << QgsExpressionFunction::Parameter( u
"value"_s )
9271 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9272 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9273 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9274 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9275 << QgsExpressionFunction::Parameter( u
"x1"_s )
9276 << QgsExpressionFunction::Parameter( u
"y1"_s )
9277 << QgsExpressionFunction::Parameter( u
"x2"_s )
9278 << QgsExpressionFunction::Parameter( u
"y2"_s ),
9279 fcnCubicBezierScale,
9284 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
9285 <<
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 )
9286 <<
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 )
9287 <<
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 )
9288 <<
new QgsStaticExpressionFunction(
9292 QStringList() << u
"Conversions"_s << u
"String"_s,
9297 QStringList() << u
"tostring"_s
9299 <<
new QgsStaticExpressionFunction(
9302 << QgsExpressionFunction::Parameter( u
"value"_s )
9303 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9304 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9306 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9311 QStringList() << u
"todatetime"_s
9313 <<
new QgsStaticExpressionFunction(
9316 << QgsExpressionFunction::Parameter( u
"value"_s )
9317 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9318 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9320 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9325 QStringList() << u
"todate"_s
9327 <<
new QgsStaticExpressionFunction(
9330 << QgsExpressionFunction::Parameter( u
"value"_s )
9331 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9332 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9334 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9339 QStringList() << u
"totime"_s
9341 <<
new QgsStaticExpressionFunction(
9345 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9350 QStringList() << u
"tointerval"_s
9352 <<
new QgsStaticExpressionFunction(
9355 << QgsExpressionFunction::Parameter( u
"value"_s )
9356 << QgsExpressionFunction::Parameter( u
"axis"_s )
9357 << QgsExpressionFunction::Parameter( u
"precision"_s )
9358 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9365 QStringList() << u
"todm"_s
9367 <<
new QgsStaticExpressionFunction(
9370 << QgsExpressionFunction::Parameter( u
"value"_s )
9371 << QgsExpressionFunction::Parameter( u
"axis"_s )
9372 << QgsExpressionFunction::Parameter( u
"precision"_s )
9373 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9374 fcnToDegreeMinuteSecond,
9380 QStringList() << u
"todms"_s
9382 <<
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 )
9383 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
9384 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
9385 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
9386 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9387 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
9388 <<
new QgsStaticExpressionFunction(
9391 << QgsExpressionFunction::Parameter( u
"condition"_s )
9392 << QgsExpressionFunction::Parameter( u
"result_when_true"_s )
9393 << QgsExpressionFunction::Parameter( u
"result_when_false"_s ),
9401 <<
new QgsStaticExpressionFunction(
9412 <<
new QgsStaticExpressionFunction(
9415 << QgsExpressionFunction::Parameter( u
"layer"_s )
9416 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9417 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9418 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9419 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9420 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9430 if ( !node->
args() )
9433 QSet<QString> referencedVars;
9436 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9442 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9445 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
9453 if ( !node->
args() )
9454 return QSet<QString>();
9456 QSet<QString> referencedCols;
9457 QSet<QString> referencedVars;
9461 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9467 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9472 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
9475 return referencedCols;
9480 <<
new QgsStaticExpressionFunction(
9481 u
"relation_aggregate"_s,
9483 << QgsExpressionFunction::Parameter( u
"relation"_s )
9484 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9485 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9486 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9487 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9488 fcnAggregateRelation,
9496 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9497 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9498 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9499 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9500 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9501 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9502 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9503 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9504 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9505 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9506 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9507 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9508 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9509 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9510 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9511 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9512 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9513 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9514 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9515 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9516 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9518 <<
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 )
9519 <<
new QgsStaticExpressionFunction(
9520 u
"regexp_matches"_s,
9522 << QgsExpressionFunction::Parameter( u
"string"_s )
9523 << QgsExpressionFunction::Parameter( u
"regex"_s )
9524 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
9529 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9530 <<
new QgsStaticExpressionFunction( u
"age"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime1"_s ) << QgsExpressionFunction::Parameter( u
"datetime2"_s ), fcnAge, u
"Date and Time"_s )
9539 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9540 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9541 <<
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 )
9542 <<
new QgsStaticExpressionFunction(
9544 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hour"_s ) << QgsExpressionFunction::Parameter( u
"minute"_s ) << QgsExpressionFunction::Parameter( u
"second"_s ),
9548 <<
new QgsStaticExpressionFunction(
9551 << QgsExpressionFunction::Parameter( u
"year"_s )
9552 << QgsExpressionFunction::Parameter( u
"month"_s )
9553 << QgsExpressionFunction::Parameter( u
"day"_s )
9554 << QgsExpressionFunction::Parameter( u
"hour"_s )
9555 << QgsExpressionFunction::Parameter( u
"minute"_s )
9556 << QgsExpressionFunction::Parameter( u
"second"_s ),
9560 <<
new QgsStaticExpressionFunction(
9563 << QgsExpressionFunction::Parameter( u
"years"_s,
true, 0 )
9564 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9565 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9566 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9567 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9568 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9569 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9573 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9574 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9575 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9576 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9577 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9579 <<
new QgsStaticExpressionFunction(
9582 << QgsExpressionFunction::Parameter( u
"string"_s )
9583 << QgsExpressionFunction::Parameter( u
"substring"_s )
9584 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9591 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9592 <<
new QgsStaticExpressionFunction( u
"ltrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9593 <<
new QgsStaticExpressionFunction( u
"rtrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9594 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9595 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9596 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9600 <<
new QgsStaticExpressionFunction(
9603 << QgsExpressionFunction::Parameter( u
"text"_s )
9604 << QgsExpressionFunction::Parameter( u
"length"_s )
9605 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ),
9609 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9610 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9611 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s ) }, fcnRepeat, u
"String"_s )
9612 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9613 <<
new QgsStaticExpressionFunction(
9614 u
"regexp_replace"_s,
9615 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"replacement"_s ),
9619 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9620 <<
new QgsStaticExpressionFunction(
9622 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ),
9632 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9633 <<
new QgsStaticExpressionFunction( u
"concat_ws"_s, -1, fcnConcatWs, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9634 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9635 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9636 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9637 <<
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 )
9638 <<
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 )
9639 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9640 <<
new QgsStaticExpressionFunction(
9643 << QgsExpressionFunction::Parameter( u
"number"_s )
9644 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9645 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9646 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9647 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ),
9651 <<
new QgsStaticExpressionFunction(
9654 << QgsExpressionFunction::Parameter( u
"datetime"_s )
9655 << QgsExpressionFunction::Parameter( u
"format"_s )
9656 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9658 QStringList() << u
"String"_s << u
"Date and Time"_s
9660 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9661 <<
new QgsStaticExpressionFunction(
9663 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9667 <<
new QgsStaticExpressionFunction(
9669 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9673 <<
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 )
9674 <<
new QgsStaticExpressionFunction(
9677 << QgsExpressionFunction::Parameter( u
"red"_s )
9678 << QgsExpressionFunction::Parameter( u
"green"_s )
9679 << QgsExpressionFunction::Parameter( u
"blue"_s )
9680 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9684 <<
new QgsStaticExpressionFunction(
9687 << QgsExpressionFunction::Parameter( u
"red"_s )
9688 << QgsExpressionFunction::Parameter( u
"green"_s )
9689 << QgsExpressionFunction::Parameter( u
"blue"_s )
9690 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9696 <<
new QgsStaticExpressionFunction( u
"create_ramp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ), fcnCreateRamp, u
"Color"_s )
9697 <<
new QgsStaticExpressionFunction(
9699 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9703 <<
new QgsStaticExpressionFunction(
9706 << QgsExpressionFunction::Parameter( u
"hue"_s )
9707 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9708 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9709 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9713 <<
new QgsStaticExpressionFunction(
9716 << QgsExpressionFunction::Parameter( u
"hue"_s )
9717 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9718 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9719 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9723 <<
new QgsStaticExpressionFunction(
9725 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9729 <<
new QgsStaticExpressionFunction(
9732 << QgsExpressionFunction::Parameter( u
"hue"_s )
9733 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9734 << QgsExpressionFunction::Parameter( u
"value"_s )
9735 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9739 <<
new QgsStaticExpressionFunction(
9742 << QgsExpressionFunction::Parameter( u
"hue"_s )
9743 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9744 << QgsExpressionFunction::Parameter( u
"value"_s )
9745 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9749 <<
new QgsStaticExpressionFunction(
9752 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9753 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9754 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9755 << QgsExpressionFunction::Parameter( u
"black"_s ),
9759 <<
new QgsStaticExpressionFunction(
9762 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9763 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9764 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9765 << QgsExpressionFunction::Parameter( u
"black"_s )
9766 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9770 <<
new QgsStaticExpressionFunction(
9773 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9774 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9775 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9776 << QgsExpressionFunction::Parameter( u
"black"_s )
9777 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9781 <<
new QgsStaticExpressionFunction( u
"color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ), fncColorPart, u
"Color"_s )
9782 <<
new QgsStaticExpressionFunction( u
"darker"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncDarker, u
"Color"_s )
9783 <<
new QgsStaticExpressionFunction( u
"lighter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncLighter, u
"Color"_s )
9784 <<
new QgsStaticExpressionFunction(
9785 u
"set_color_part"_s,
9786 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9792 <<
new QgsStaticExpressionFunction( u
"base_file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnBaseFileName, u
"Files and Paths"_s )
9793 <<
new QgsStaticExpressionFunction( u
"file_suffix"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSuffix, u
"Files and Paths"_s )
9794 <<
new QgsStaticExpressionFunction( u
"file_exists"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileExists, u
"Files and Paths"_s )
9795 <<
new QgsStaticExpressionFunction( u
"file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileName, u
"Files and Paths"_s )
9796 <<
new QgsStaticExpressionFunction( u
"is_file"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsFile, u
"Files and Paths"_s )
9797 <<
new QgsStaticExpressionFunction( u
"is_directory"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsDir, u
"Files and Paths"_s )
9798 <<
new QgsStaticExpressionFunction( u
"file_path"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFilePath, u
"Files and Paths"_s )
9799 <<
new QgsStaticExpressionFunction( u
"file_size"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSize, u
"Files and Paths"_s )
9801 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ), fcnExif, u
"Files and Paths"_s )
9802 <<
new QgsStaticExpressionFunction( u
"exif_geotag"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnExifGeoTag, u
"GeometryGroup"_s )
9805 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ), fcnGenericHash, u
"Conversions"_s )
9811 <<
new QgsStaticExpressionFunction( u
"from_base64"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnFromBase64, u
"Conversions"_s )
9814 <<
new QgsStaticExpressionFunction(
9815 u
"magnetic_declination"_s,
9817 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9818 << QgsExpressionFunction::Parameter( u
"date"_s )
9819 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9820 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9821 << QgsExpressionFunction::Parameter( u
"height"_s )
9822 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9823 fcnMagneticDeclination,
9826 <<
new QgsStaticExpressionFunction(
9827 u
"magnetic_inclination"_s,
9829 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9830 << QgsExpressionFunction::Parameter( u
"date"_s )
9831 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9832 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9833 << QgsExpressionFunction::Parameter( u
"height"_s )
9834 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9835 fcnMagneticInclination,
9838 <<
new QgsStaticExpressionFunction(
9839 u
"magnetic_declination_rate_of_change"_s,
9841 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9842 << QgsExpressionFunction::Parameter( u
"date"_s )
9843 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9844 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9845 << QgsExpressionFunction::Parameter( u
"height"_s )
9846 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9847 fcnMagneticDeclinationRateOfChange,
9850 <<
new QgsStaticExpressionFunction(
9851 u
"magnetic_inclination_rate_of_change"_s,
9853 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9854 << QgsExpressionFunction::Parameter( u
"date"_s )
9855 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9856 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9857 << QgsExpressionFunction::Parameter( u
"height"_s )
9858 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9859 fcnMagneticInclinationRateOfChange,
9866 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9868 functions << geomFunc;
9870 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9872 functions << areaFunc;
9874 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9876 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9878 functions << lengthFunc;
9880 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9882 functions << perimeterFunc;
9884 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9886 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnRoundness, u
"GeometryGroup"_s );
9888 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9892 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9896 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9900 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions {
9901 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9902 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9903 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9904 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9905 { u
"overlay_equals_exact"_s, fcnGeomOverlayEqualsExact },
9906 { u
"overlay_equals_topological"_s, fcnGeomOverlayEqualsTopological },
9907 { u
"overlay_equals_fuzzy"_s, fcnGeomOverlayEqualsFuzzy },
9908 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9909 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9910 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9912 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9913 while ( i.hasNext() )
9916 QString defaultBackend = i.key() ==
"overlay_equals"_L1 ? QString(
"QGIS" ) : QString(
"GEOS" );
9917 QgsStaticExpressionFunction *fcnGeomOverlayFunc =
new QgsStaticExpressionFunction(
9920 << QgsExpressionFunction::Parameter( u
"layer"_s )
9921 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9922 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9923 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9924 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9925 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9926 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9927 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9928 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false )
9929 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, defaultBackend,
false )
9930 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4,
false ),
9941 functions << fcnGeomOverlayFunc;
9944 QgsStaticExpressionFunction *fcnGeomOverlayNearestFunc =
new QgsStaticExpressionFunction(
9945 u
"overlay_nearest"_s,
9947 << QgsExpressionFunction::Parameter( u
"layer"_s )
9948 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9949 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9950 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9951 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9952 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9953 fcnGeomOverlayNearest,
9962 functions << fcnGeomOverlayNearestFunc;
9965 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9970 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9971 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9972 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9973 <<
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 )
9974 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9975 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9976 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9977 <<
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 )
9978 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
9979 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
9980 <<
new QgsStaticExpressionFunction(
9982 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ) << QgsExpressionFunction::Parameter( u
"point3"_s ),
9986 <<
new QgsStaticExpressionFunction(
9989 << QgsExpressionFunction::Parameter( u
"center"_s )
9990 << QgsExpressionFunction::Parameter( u
"radius"_s )
9991 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9995 <<
new QgsStaticExpressionFunction(
9998 << QgsExpressionFunction::Parameter( u
"center"_s )
9999 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
10000 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
10001 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10002 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
10006 <<
new QgsStaticExpressionFunction(
10007 u
"make_regular_polygon"_s,
10009 << QgsExpressionFunction::Parameter( u
"center"_s )
10010 << QgsExpressionFunction::Parameter( u
"radius"_s )
10011 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
10012 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
10013 fcnMakeRegularPolygon,
10016 <<
new QgsStaticExpressionFunction( u
"make_square"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnMakeSquare, u
"GeometryGroup"_s )
10017 <<
new QgsStaticExpressionFunction(
10018 u
"make_rectangle_3points"_s,
10020 << QgsExpressionFunction::Parameter( u
"point1"_s )
10021 << QgsExpressionFunction::Parameter( u
"point2"_s )
10022 << QgsExpressionFunction::Parameter( u
"point3"_s )
10023 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
10024 fcnMakeRectangleFrom3Points,
10027 <<
new QgsStaticExpressionFunction(
10030 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10031#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
10032 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
10034 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
10036 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
10043 <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
10045 <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
10047 <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
10049 <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
10051 QgsStaticExpressionFunction *xAtFunc
10052 =
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 );
10054 functions << xAtFunc;
10057 QgsStaticExpressionFunction *yAtFunc
10058 =
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 );
10060 functions << yAtFunc;
10063 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
10064 <<
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 )
10065 <<
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 )
10066 <<
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 )
10067 <<
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 )
10068 <<
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 )
10069 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10070 <<
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 )
10071 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
10072 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
10073 <<
new QgsStaticExpressionFunction(
10074 u
"intersects_bbox"_s,
10077 u
"GeometryGroup"_s,
10082 QStringList() << u
"bbox"_s
10084 <<
new QgsStaticExpressionFunction( u
"disjoint"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDisjoint, u
"GeometryGroup"_s )
10085 <<
new QgsStaticExpressionFunction( u
"intersects"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersects, u
"GeometryGroup"_s )
10086 <<
new QgsStaticExpressionFunction( u
"touches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnTouches, u
"GeometryGroup"_s )
10087 <<
new QgsStaticExpressionFunction( u
"crosses"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCrosses, u
"GeometryGroup"_s )
10088 <<
new QgsStaticExpressionFunction( u
"contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnContains, u
"GeometryGroup"_s )
10089 <<
new QgsStaticExpressionFunction( u
"overlaps"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnOverlaps, u
"GeometryGroup"_s )
10090 <<
new QgsStaticExpressionFunction( u
"within"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnWithin, u
"GeometryGroup"_s )
10091 <<
new QgsStaticExpressionFunction( u
"equals"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnEquals, u
"GeometryGroup"_s )
10092 <<
new QgsStaticExpressionFunction(
10095 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10096 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10097 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s ),
10101 <<
new QgsStaticExpressionFunction(
10102 u
"equals_topological"_s,
10104 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10105 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10106 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"GEOS"_s ),
10107 fcnIsEqualsTopological,
10110 <<
new QgsStaticExpressionFunction(
10113 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10114 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10115 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s )
10116 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4 ),
10120 <<
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 )
10121 <<
new QgsStaticExpressionFunction(
10124 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10125 << QgsExpressionFunction::Parameter( u
"rotation"_s )
10126 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
10127 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
10131 <<
new QgsStaticExpressionFunction(
10134 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10135 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
10136 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
10137 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
10141 <<
new QgsStaticExpressionFunction(
10142 u
"affine_transform"_s,
10144 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10145 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
10146 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
10147 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
10148 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
10149 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
10150 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
10151 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
10152 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
10153 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
10154 fcnAffineTransform,
10157 <<
new QgsStaticExpressionFunction(
10160 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10161 << QgsExpressionFunction::Parameter( u
"distance"_s )
10162 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
10163 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
10164 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
10165 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
10169 <<
new QgsStaticExpressionFunction( u
"force_rhr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForceRHR, u
"GeometryGroup"_s )
10170 <<
new QgsStaticExpressionFunction( u
"force_polygon_cw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCW, u
"GeometryGroup"_s )
10171 <<
new QgsStaticExpressionFunction( u
"force_polygon_ccw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCCW, u
"GeometryGroup"_s )
10172 <<
new QgsStaticExpressionFunction(
10175 << QgsExpressionFunction::Parameter( u
"center"_s )
10176 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10177 << QgsExpressionFunction::Parameter( u
"width"_s )
10178 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
10179 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ),
10183 <<
new QgsStaticExpressionFunction(
10184 u
"tapered_buffer"_s,
10186 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10187 << QgsExpressionFunction::Parameter( u
"start_width"_s )
10188 << QgsExpressionFunction::Parameter( u
"end_width"_s )
10189 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ),
10193 <<
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 )
10194 <<
new QgsStaticExpressionFunction(
10197 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10198 << QgsExpressionFunction::Parameter( u
"distance"_s )
10199 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10201 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10205 <<
new QgsStaticExpressionFunction(
10206 u
"single_sided_buffer"_s,
10208 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10209 << QgsExpressionFunction::Parameter( u
"distance"_s )
10210 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10212 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10213 fcnSingleSidedBuffer,
10216 <<
new QgsStaticExpressionFunction(
10219 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10220 << QgsExpressionFunction::Parameter( u
"start_distance"_s )
10221 << QgsExpressionFunction::Parameter( u
"end_distance"_s )
10222 << QgsExpressionFunction::Parameter( u
"start_deflection"_s,
true, 0 )
10223 << QgsExpressionFunction::Parameter( u
"end_deflection"_s,
true, 0 ),
10227 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
10228 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
10229 <<
new QgsStaticExpressionFunction( u
"pole_of_inaccessibility"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
10230 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
10231 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
10232 <<
new QgsStaticExpressionFunction( u
"interior_ring_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnInteriorRingN, u
"GeometryGroup"_s )
10233 <<
new QgsStaticExpressionFunction( u
"geometry_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnGeometryN, u
"GeometryGroup"_s )
10234 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
10235 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
10236 <<
new QgsStaticExpressionFunction( u
"shared_paths"_s,
QgsExpressionFunction::ParameterList { QgsExpressionFunction::Parameter( u
"geometry1"_s ), QgsExpressionFunction::Parameter( u
"geometry2"_s ) }, fcnSharedPaths, u
"GeometryGroup"_s )
10238 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
10239 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
10240 <<
new QgsStaticExpressionFunction(
10243 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10244 << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
10245 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
10246 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
10247 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ),
10251 <<
new QgsStaticExpressionFunction(
10252 u
"triangular_wave"_s,
10253 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10254 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10255 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10256 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10260 <<
new QgsStaticExpressionFunction(
10261 u
"triangular_wave_randomized"_s,
10262 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10263 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10264 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10265 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10266 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10267 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10268 fcnTriangularWaveRandomized,
10271 <<
new QgsStaticExpressionFunction(
10273 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10274 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10275 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10276 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10280 <<
new QgsStaticExpressionFunction(
10281 u
"square_wave_randomized"_s,
10282 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10283 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10284 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10285 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10286 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10287 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10288 fcnSquareWaveRandomized,
10291 <<
new QgsStaticExpressionFunction(
10293 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10294 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10295 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10296 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10300 <<
new QgsStaticExpressionFunction(
10301 u
"wave_randomized"_s,
10302 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10303 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10304 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10305 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10306 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10307 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10308 fcnRoundWaveRandomized,
10311 <<
new QgsStaticExpressionFunction(
10312 u
"apply_dash_pattern"_s,
10314 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10315 QgsExpressionFunction::Parameter( u
"pattern"_s ),
10316 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
10317 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
10318 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
10319 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
10321 fcnApplyDashPattern,
10324 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"vertices"_s ) }, fcnDensifyByCount, u
"GeometryGroup"_s )
10325 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"distance"_s ) }, fcnDensifyByDistance, u
"GeometryGroup"_s )
10326 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
10327 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
10328 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
10329 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
10330 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
10331 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
10332 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
10333 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
10334 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
10335 <<
new QgsStaticExpressionFunction(
10336 u
"is_empty_or_null"_s,
10339 u
"GeometryGroup"_s,
10347 <<
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 )
10348#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
10349 <<
new QgsStaticExpressionFunction(
10352 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10353 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
10354 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ),
10359 <<
new QgsStaticExpressionFunction( u
"oriented_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnOrientedBBox, u
"GeometryGroup"_s )
10360 <<
new QgsStaticExpressionFunction( u
"main_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnMainAngle, u
"GeometryGroup"_s )
10361 <<
new QgsStaticExpressionFunction( u
"minimal_circle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ), fcnMinimalCircle, u
"GeometryGroup"_s )
10362 <<
new QgsStaticExpressionFunction( u
"difference"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDifference, u
"GeometryGroup"_s )
10363 <<
new QgsStaticExpressionFunction( u
"distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDistance, u
"GeometryGroup"_s )
10364 <<
new QgsStaticExpressionFunction(
10365 u
"hausdorff_distance"_s,
10367 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10368 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10369 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
10370 fcnHausdorffDistance,
10373 <<
new QgsStaticExpressionFunction( u
"intersection"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersection, u
"GeometryGroup"_s )
10374 <<
new QgsStaticExpressionFunction(
10375 u
"sym_difference"_s,
10378 u
"GeometryGroup"_s,
10383 QStringList() << u
"symDifference"_s
10385 <<
new QgsStaticExpressionFunction( u
"combine"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10386 <<
new QgsStaticExpressionFunction( u
"union"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10387 <<
new QgsStaticExpressionFunction(
10391 u
"GeometryGroup"_s,
10396 QStringList() << u
"geomToWKT"_s
10398 <<
new QgsStaticExpressionFunction( u
"geom_to_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10399 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
10400 <<
new QgsStaticExpressionFunction(
10402 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"source_auth_id"_s ) << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
10403 fcnTransformGeometry,
10406 <<
new QgsStaticExpressionFunction(
10408 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ),
10410 u
"GeometryGroup"_s,
10413 <<
new QgsStaticExpressionFunction( u
"is_multipart"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsMultipart, u
"GeometryGroup"_s )
10418 <<
new QgsStaticExpressionFunction( u
"sinuosity"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSinuosity, u
"GeometryGroup"_s )
10419 <<
new QgsStaticExpressionFunction( u
"straight_distance_2d"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStraightDistance2d, u
"GeometryGroup"_s );
10422 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction(
10425 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10426 << QgsExpressionFunction::Parameter( u
"orderby"_s )
10427 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
10429 u
"GeometryGroup"_s,
10434 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10435 for ( QgsExpressionNode *argNode : argList )
10437 if ( !argNode->isStatic( parent, context ) )
10443 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10445 QString expString = argNode->
eval( parent, context ).toString();
10449 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10459 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10460 QString
expression = argNode->
eval( parent, context ).toString();
10462 e.prepare( context );
10467 functions << orderPartsFunc;
10470 <<
new QgsStaticExpressionFunction( u
"closest_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnClosestPoint, u
"GeometryGroup"_s )
10471 <<
new QgsStaticExpressionFunction( u
"shortest_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnShortestLine, u
"GeometryGroup"_s )
10472 <<
new QgsStaticExpressionFunction( u
"line_interpolate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
10473 <<
new QgsStaticExpressionFunction(
10474 u
"line_interpolate_point_by_m"_s,
10476 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10477 << QgsExpressionFunction::Parameter( u
"m"_s )
10478 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10479 fcnLineInterpolatePointByM,
10482 <<
new QgsStaticExpressionFunction( u
"line_interpolate_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
10483 <<
new QgsStaticExpressionFunction( u
"line_locate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
10484 <<
new QgsStaticExpressionFunction(
10485 u
"line_locate_m"_s,
10487 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10488 << QgsExpressionFunction::Parameter( u
"m"_s )
10489 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10493 <<
new QgsStaticExpressionFunction( u
"angle_at_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
10494 <<
new QgsStaticExpressionFunction( u
"distance_to_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
10495 <<
new QgsStaticExpressionFunction(
10496 u
"line_substring"_s,
10497 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10505 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
10507 functions << idFunc;
10509 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
10511 functions << currentFeatureFunc;
10513 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction(
10515 { QgsExpressionFunction::Parameter( u
"format"_s,
true, u
"WithBraces"_s ), QgsExpressionFunction::Parameter( u
"version"_s,
true, 4 ) },
10517 u
"Record and Attributes"_s,
10522 QStringList() << u
"$uuid"_s
10525 functions << uuidFunc;
10528 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
10529 <<
new QgsStaticExpressionFunction(
10531 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
10533 u
"Record and Attributes"_s,
10538 QStringList() << u
"QgsExpressionUtils::getFeature"_s
10540 <<
new QgsStaticExpressionFunction(
10541 u
"get_feature_by_id"_s,
10544 u
"Record and Attributes"_s,
10551 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction(
10555 u
"Record and Attributes"_s,
10561 functions << attributesFunc;
10562 QgsStaticExpressionFunction *representAttributesFunc
10563 =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1, fcnRepresentAttributes, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10565 functions << representAttributesFunc;
10567 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction(
10568 u
"is_feature_valid"_s,
10570 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10571 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10572 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10573 fcnValidateFeature,
10574 u
"Record and Attributes"_s,
10580 functions << validateFeature;
10582 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction(
10583 u
"is_attribute_valid"_s,
10585 << QgsExpressionFunction::Parameter( u
"attribute"_s,
false )
10587 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10588 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10589 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10590 fcnValidateAttribute,
10591 u
"Record and Attributes"_s,
10597 functions << validateAttribute;
10599 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction( u
"maptip"_s, -1, fcnFeatureMaptip, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10601 functions << maptipFunc;
10603 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction( u
"display_expression"_s, -1, fcnFeatureDisplayExpression, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10605 functions << displayFunc;
10607 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction( u
"is_selected"_s, -1, fcnIsSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10609 functions << isSelectedFunc;
10611 functions <<
new QgsStaticExpressionFunction( u
"num_selected"_s, -1, fcnNumSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10613 functions <<
new QgsStaticExpressionFunction(
10614 u
"sqlite_fetch_and_increment"_s,
10616 << QgsExpressionFunction::Parameter( u
"database"_s )
10617 << QgsExpressionFunction::Parameter( u
"table"_s )
10618 << QgsExpressionFunction::Parameter( u
"id_field"_s )
10619 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
10620 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
10621 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
10622 fcnSqliteFetchAndIncrement,
10623 u
"Record and Attributes"_s
10628 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
10629 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
10633 QgsStaticExpressionFunction *representValueFunc
10634 =
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 );
10637 Q_UNUSED( context )
10640 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
10647 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
10657 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
10662 functions << representValueFunc;
10666 <<
new QgsStaticExpressionFunction(
10667 u
"layer_property"_s,
10669 << QgsExpressionFunction::Parameter( u
"layer"_s )
10670 << QgsExpressionFunction::Parameter( u
"property"_s )
10671 << QgsExpressionFunction::Parameter( u
"translate"_s,
true,
true ),
10672 fcnGetLayerProperty,
10675 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"part"_s,
true ), fcnDecodeUri, u
"Map Layers"_s )
10676 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary_data"_s ), fcnMimeType, u
"General"_s )
10677 <<
new QgsStaticExpressionFunction(
10678 u
"raster_statistic"_s,
10679 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"statistic"_s ),
10680 fcnGetRasterBandStat,
10685 QgsStaticExpressionFunction *varFunction
10695 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10697 if ( !argNode->
isStatic( parent, context ) )
10700 const QString varName = argNode->
eval( parent, context ).toString();
10701 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
10705 return scope ? scope->
isStatic( varName ) :
false;
10710 if ( node && node->
args()->
count() > 0 )
10712 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10713 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
10715 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
10722 functions << varFunction;
10724 QgsStaticExpressionFunction *evalTemplateFunction
10729 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10731 if ( argNode->
isStatic( parent, context ) )
10733 QString expString = argNode->
eval( parent, context ).toString();
10737 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10744 functions << evalTemplateFunction;
10746 QgsStaticExpressionFunction *evalFunc
10751 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10753 if ( argNode->
isStatic( parent, context ) )
10755 QString expString = argNode->
eval( parent, context ).toString();
10759 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10767 functions << evalFunc;
10769 QgsStaticExpressionFunction *attributeFunc
10770 =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10772 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10773 for ( QgsExpressionNode *argNode : argList )
10775 if ( !argNode->
isStatic( parent, context ) )
10787 functions << attributeFunc;
10791 <<
new QgsWithVariableExpressionFunction()
10792 <<
new QgsStaticExpressionFunction(
10794 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10798 <<
new QgsStaticExpressionFunction(
10799 u
"raster_attributes"_s,
10800 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10801 fcnRasterAttributes,
10806 <<
new QgsArrayForeachExpressionFunction()
10807 <<
new QgsArrayFilterExpressionFunction()
10808 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10809 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10810 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10811 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10812 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10813 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayAll, u
"Arrays"_s )
10814 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10815 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10821 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10822 <<
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 )
10823 <<
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 )
10825 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10826 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10827 <<
new QgsStaticExpressionFunction(
10829 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
10833 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10834 <<
new QgsStaticExpressionFunction(
10835 u
"array_remove_all"_s,
10846 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10847 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"priority"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10848 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10849 <<
new QgsStaticExpressionFunction(
10851 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ),
10855 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10856 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10857 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10858 <<
new QgsStaticExpressionFunction(
10859 u
"array_to_string"_s,
10861 << QgsExpressionFunction::Parameter( u
"array"_s )
10862 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10863 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10867 <<
new QgsStaticExpressionFunction(
10868 u
"string_to_array"_s,
10870 << QgsExpressionFunction::Parameter( u
"string"_s )
10871 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10872 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10876 <<
new QgsStaticExpressionFunction(
10877 u
"generate_series"_s,
10878 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ),
10882 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10885 <<
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 )
10886 <<
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 )
10887 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10889 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10890 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10891 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10892 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10893 <<
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 )
10894 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10897 <<
new QgsStaticExpressionFunction( u
"map_prefix_keys"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"prefix"_s ), fcnMapPrefixKeys, u
"Maps"_s )
10898 <<
new QgsStaticExpressionFunction( u
"map_to_html_table"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlTable, u
"Maps"_s )
10899 <<
new QgsStaticExpressionFunction( u
"map_to_html_dl"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlDefinitionList, u
"Maps"_s )
10909 *sOwnedFunctions() << func;
10910 *sBuiltinFunctions() << func->name();
10911 sBuiltinFunctions()->append( func->aliases() );
10925 QMutexLocker locker( &sFunctionsMutex );
10926 sFunctions()->append( function );
10927 if ( transferOwnership )
10928 sOwnedFunctions()->append( function );
10943 QMutexLocker locker( &sFunctionsMutex );
10944 sFunctions()->removeAt( fnIdx );
10945 sFunctionIndexMap.clear();
10953 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10954 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10956 sBuiltinFunctions()->removeAll( func->name() );
10957 for (
const QString &alias : func->aliases() )
10959 sBuiltinFunctions()->removeAll( alias );
10962 sFunctions()->removeAll( func );
10965 qDeleteAll( *sOwnedFunctions() );
10966 sOwnedFunctions()->clear();
10971 if ( sBuiltinFunctions()->isEmpty() )
10975 return *sBuiltinFunctions();
10980 u
"array_foreach"_s,
10990 QgsExpressionNode::NodeList *args = node->
args();
10992 if ( args->
count() < 2 )
10995 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11005 QVariantList result;
11007 if ( args->
count() < 2 )
11011 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11013 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11014 std::unique_ptr< QgsExpressionContext > tempContext;
11017 tempContext = std::make_unique< QgsExpressionContext >();
11018 subContext = tempContext.get();
11021 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11025 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
11029 result << args->
at( 1 )->
eval( parent, subContext );
11042 Q_UNUSED( context )
11054 if ( args->
count() < 2 )
11058 args->
at( 0 )->
prepare( parent, context );
11062 subContext = *context;
11069 args->
at( 1 )->
prepare( parent, &subContext );
11082 QgsExpressionNode::NodeList *args = node->
args();
11084 if ( args->
count() < 2 )
11087 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11097 QVariantList result;
11099 if ( args->
count() < 2 )
11103 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11105 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11106 std::unique_ptr< QgsExpressionContext > tempContext;
11109 tempContext = std::make_unique< QgsExpressionContext >();
11110 subContext = tempContext.get();
11113 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11117 if ( args->
count() >= 3 )
11119 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
11121 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
11123 limit = limitVar.toInt();
11131 for (
const QVariant &value : array )
11133 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
11134 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
11138 if ( limit > 0 && limit == result.size() )
11153 Q_UNUSED( context )
11165 if ( args->
count() < 2 )
11169 args->
at( 0 )->
prepare( parent, context );
11173 subContext = *context;
11179 args->
at( 1 )->
prepare( parent, &subContext );
11191 QgsExpressionNode::NodeList *args = node->
args();
11193 if ( args->
count() < 3 )
11197 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11199 QVariant
name = args->
at( 0 )->
eval( parent, context );
11200 QVariant value = args->
at( 1 )->
eval( parent, context );
11203 appendTemporaryVariable( context,
name.toString(), value );
11204 if ( args->
at( 2 )->
isStatic( parent, context ) )
11206 popTemporaryVariable( context );
11217 if ( args->
count() < 3 )
11221 QVariant
name = args->
at( 0 )->
eval( parent, context );
11222 QVariant value = args->
at( 1 )->
eval( parent, context );
11224 const QgsExpressionContext *updatedContext = context;
11225 std::unique_ptr< QgsExpressionContext > tempContext;
11226 if ( !updatedContext )
11228 tempContext = std::make_unique< QgsExpressionContext >();
11229 updatedContext = tempContext.get();
11232 appendTemporaryVariable( updatedContext,
name.toString(), value );
11233 result = args->
at( 2 )->
eval( parent, updatedContext );
11236 popTemporaryVariable( updatedContext );
11245 Q_UNUSED( context )
11257 if ( args->
count() < 3 )
11262 QVariant value = args->
at( 1 )->
prepare( parent, context );
11265 std::unique_ptr< QgsExpressionContext > tempContext;
11266 if ( !updatedContext )
11268 tempContext = std::make_unique< QgsExpressionContext >();
11269 updatedContext = tempContext.get();
11272 appendTemporaryVariable( updatedContext,
name.toString(), value );
11273 args->
at( 2 )->
prepare( parent, updatedContext );
11276 popTemporaryVariable( updatedContext );
11281void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
11283 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
11284 delete updatedContext->
popScope();
11287void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
11289 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
11290 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
11292 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
GeometryBackend
Geometry backend for QgsGeometry.
@ GEOS
Use GEOS implementation.
@ QGIS
Use internal implementation.
@ Left
Buffer to left of line.
DashPatternSizeAdjustment
Dash pattern size adjustment options.
@ ScaleDashOnly
Only dash lengths are adjusted.
@ ScaleBothDashAndGap
Both the dash and gap lengths are adjusted equally.
@ ScaleGapOnly
Only gap lengths are adjusted.
@ Success
Operation succeeded.
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
JoinStyle
Join styles for buffers.
@ Bevel
Use beveled joins.
@ Round
Use rounded joins.
@ Miter
Use mitered joins.
RasterBandStatistic
Available raster band statistics.
@ StdDev
Standard deviation.
@ NoStatistic
No statistic.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
EndCapStyle
End cap styles for buffers.
@ Flat
Flat cap (in line with start/end of line).
@ Square
Square cap (extends past start/end of line by buffer distance).
Aggregate
Available aggregates to calculate.
@ StringMinimumLength
Minimum length of string (string fields only).
@ FirstQuartile
First quartile (numeric fields only).
@ Mean
Mean of values (numeric fields only).
@ Median
Median of values (numeric fields only).
@ StringMaximumLength
Maximum length of string (string fields only).
@ Range
Range of values (max - min) (numeric and datetime fields only).
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
@ Minority
Minority of values.
@ CountMissing
Number of missing (null) values.
@ ArrayAggregate
Create an array of values.
@ Majority
Majority of values.
@ StDevSample
Sample standard deviation of values (numeric fields only).
@ ThirdQuartile
Third quartile (numeric fields only).
@ CountDistinct
Number of distinct values.
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
DashPatternLineEndingRule
Dash pattern line ending rules.
@ HalfDash
Start or finish the pattern with a half length dash.
@ HalfGap
Start or finish the pattern with a half length gap.
@ FullGap
Start or finish the pattern with a full gap.
@ FullDash
Start or finish the pattern with a full dash.
MakeValidMethod
Algorithms to use when repairing invalid geometries.
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
@ Structure
Structured method, first makes all rings valid and then merges shells and subtracts holes from shells...
@ GeometryCollection
GeometryCollection.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
bool isMeasure() const
Returns true if the geometry contains m values.
virtual QgsRectangle boundingBox() const
Returns the minimal bounding box for the geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
virtual QgsCoordinateSequence coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
virtual int partCount() const =0
Returns count of parts contained in the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
static Qgis::Aggregate stringToAggregate(const QString &string, bool *ok=nullptr)
Converts a string to a aggregate type.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QgsArrayFilterExpressionFunction()
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
QgsArrayForeachExpressionFunction()
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
bool isEmpty() const override
Returns true if the geometry is empty.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
double roundness() const
Returns the roundness of the curve polygon.
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.
Abstract base class for curved geometry type.
double sinuosity() const
Returns the curve sinuosity, which is the ratio of the curve length() to curve straightDistance2d().
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
virtual bool isClosed() const
Returns true if the curve is closed.
double straightDistance2d() const
Returns the straight distance of the curve, i.e.
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double convertLengthMeasurement(double length, Qgis::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
double bearing(const QgsPointXY &p1, const QgsPointXY &p2) const
Computes the bearing (in radians) between two points.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
double convertAreaMeasurement(double area, Qgis::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
Defines a QGIS exception class.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
QString uniqueHash(bool &ok, const QSet< QString > &variables=QSet< QString >()) const
Returns a unique hash representing the current state of the context.
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool hasGeometry() const
Returns true if the context has a geometry associated with it.
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
An abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
bool operator==(const QgsExpressionFunction &other) const
QgsExpressionFunction(const QString &fnname, int params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters.
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
virtual bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
Will be called during prepare to determine if the function is static.
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
bool lazyEval() const
true if this function should use lazy evaluation.
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
QString name() const
The name of the function.
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)=0
Returns result of evaluating the function.
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
virtual bool handlesNull() const
Returns true if the function handles NULL values in arguments by itself, and the default NULL value h...
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
const QString helpText() const
The help text for the function.
virtual bool usesGeometry(const QgsExpressionNodeFunction *node) const
Does this function use a geometry object.
An expression node which takes its value from a feature's field.
QString name() const
The name of the column.
An expression node for expression functions.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
An expression node for literal values.
A list of expression nodes.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
int count() const
Returns the number of nodes in the list.
Abstract base class for all nodes that can appear in an expression.
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
A set of expression-related functions.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
QString expression() const
Returns the original, unmodified expression string.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
Qgis::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static const QStringList & BuiltinFunctions()
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static PRIVATE QString helpText(QString name)
Returns the help text for a specified function.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
static bool unregisterFunction(const QString &name)
Unregisters a function from the expression engine.
Qgis::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions).
friend class QgsExpressionNodeFunction
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QgsExpression(const QString &expr)
Creates a new expression based on the provided string.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Represents a list of OrderByClauses, with the most important first and the least important last.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsFeatureRequest & setRequestMayBeNested(bool requestMayBeNested)
In case this request may be run nested within another already running iteration on the same connectio...
QgsFeatureRequest & setTimeout(int timeout)
Sets the timeout (in milliseconds) for the maximum time we should wait during feature requests before...
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the iterator to check if it should be cance...
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
QgsVectorLayer * materialize(const QgsFeatureRequest &request, QgsFeedback *feedback=nullptr)
Materializes a request (query) made against this feature source, by running it over the source and re...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
ConstraintStrength
Strength of constraints.
@ ConstraintStrengthNotSet
Constraint is not set.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
int size() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
int partCount() const override
Returns count of parts contained in the geometry.
int numGeometries() const
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Encapsulates parameters under which a geometry operation is performed.
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
A geometry is the spatial representation of a feature.
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
double lineLocatePoint(const QgsGeometry &point) const
Returns a distance representing the location along this linestring of the closest point on this lines...
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points shared by this geometry and other.
double length() const
Returns the planar, 2-dimensional length of geometry.
QgsGeometry offsetCurve(double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
QgsGeometry densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
QgsGeometry poleOfInaccessibility(double precision, double *distanceToBoundary=nullptr) const
Calculates the approximate pole of inaccessibility for a surface, which is the most distant internal ...
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsGeometry squareWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs square waves along the boundary of the geometry, with the specified wavelength and amplitu...
QgsGeometry concaveHull(double targetPercent, bool allowHoles=false, QgsFeedback *feedback=nullptr) const
Returns a possibly concave polygon that contains all the points in the geometry.
QgsGeometry triangularWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs triangular waves along the boundary of the geometry, with the specified wavelength and amp...
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
Q_INVOKABLE bool touches(const QgsGeometry &geometry) const
Returns true if the geometry touches another geometry.
bool isExactlyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry applyDashPattern(const QVector< double > &pattern, Qgis::DashPatternLineEndingRule startRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternLineEndingRule endRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternSizeAdjustment adjustment=Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap, double patternOffset=0) const
Applies a dash pattern to a geometry, returning a MultiLineString geometry which is the input geometr...
QgsGeometry roundWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs rounded (sine-like) waves along the boundary of the geometry, with the specified wavelengt...
QgsGeometry nearestPoint(const QgsGeometry &other) const
Returns the nearest (closest) point on this geometry to another geometry.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
QgsGeometry mergeLines(const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Q_INVOKABLE bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
QgsGeometry singleSidedBuffer(double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle=Qgis::JoinStyle::Round, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsGeometry extendLine(double startDistance, double endDistance, double startDeflection=0, double endDeflection=0) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
Q_INVOKABLE bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
double area() const
Returns the planar, 2-dimensional area of the geometry.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
Q_INVOKABLE bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false, QgsFeedback *feedback=nullptr) const
Attempts to make an invalid geometry valid without losing vertices.
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
QgsGeometry sharedPaths(const QgsGeometry &other) const
Find paths shared between the two given lineal geometries (this and other).
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
QgsGeometry buffer(double distance, int segments, QgsFeedback *feedback=nullptr) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
bool isFuzzyEqual(const QgsGeometry &geometry, double epsilon=1e-4, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry within the tolerance epsilon using the specified backend.
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
bool isTopologicallyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::GEOS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry simplify(double tolerance, QgsFeedback *feedback=nullptr) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Q_INVOKABLE bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
Q_INVOKABLE bool overlaps(const QgsGeometry &geometry) const
Returns true if the geometry overlaps another geometry.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle(double tolerance, QString *errorMsg=nullptr, QgsFeedback *feedback=nullptr) const
Returns the maximum inscribed circle.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Represents a color stop within a QgsGradientColorRamp color ramp.
static QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
static QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.
A representation of the interval between two datetime values.
bool isValid() const
Returns true if the interval is valid.
double days() const
Returns the interval duration in days.
double weeks() const
Returns the interval duration in weeks.
double months() const
Returns the interval duration in months (based on a 30 day month).
double seconds() const
Returns the interval duration in seconds.
double years() const
Returns the interval duration in years (based on an average year length).
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
Line string geometry type, with support for z-dimension and m-values.
bool lineLocatePointByM(double m, double &x, double &y, double &z, double &distanceFromStart, bool use3DDistance=true) const
Attempts to locate a point on the linestring by m value.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
Represents a model of the Earth's magnetic field.
static bool fieldComponentsWithTimeDerivatives(double Bx, double By, double Bz, double Bxt, double Byt, double Bzt, double &H, double &F, double &D, double &I, double &Ht, double &Ft, double &Dt, double &It)
Compute various quantities dependent on a magnetic field and their rates of change.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Base class for all map layer types.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QgsLayerMetadata metadata
QString publicSource(bool hidePassword=false) const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
virtual bool isEditable() const
Returns true if the layer can be edited.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
Implementation of a geometry simplifier using the "MapToPixel" algorithm.
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Custom exception class which is raised when an operation is not supported.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
double inclination(const QgsPoint &other) const
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
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)
Decodes a string to a color.
static QString encodeColor(const QColor &color)
Lossy-encodes a color to a string.
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
Allows creation of a multi-layer database-side transaction.
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QVariant aggregate(Qgis::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters ¶meters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeatureIds *fids=nullptr, QgsFeedback *feedback=nullptr, QString *error=nullptr) const
Calculates an aggregated value from the layer's features.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QgsWithVariableExpressionFunction()
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored).
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
const QString cacheKey(const QString &pathIn)
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
std::function< bool(const QgsGeometry &geometry, const QgsGeometry &other, const QVariantList &values, Qgis::GeometryBackend backend)> RelationFunction
allows geometry function with different parameters to be used with the same executeGeomOverlay functi...
double qDateTimeToDecimalYear(const QDateTime &dateTime)
QList< QgsExpressionFunction * > ExpressionFunctionList
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColorObject(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
#define SET_EVAL_ERROR(x)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QLineF segment(int index, QRectF rect, double radius)
A bundle of parameters controlling aggregate calculation.
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
Single variable definition for use within a QgsExpressionContextScope.
The Context struct stores the current layer and coordinate transform context.
const QgsMapLayer * layer
QgsCoordinateTransformContext transformContext
Utility class for identifying a unique vertex within a geometry.