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() );
1612 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1613 return QVariant( str.toUpper() );
1618 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1619 QStringList elems = str.split(
' ' );
1620 for (
int i = 0; i < elems.size(); i++ )
1622 if ( elems[i].size() > 1 )
1623 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1625 return QVariant( elems.join(
' '_L1 ) );
1630 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1631 return QVariant( str.trimmed() );
1636 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1638 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1640 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1641 str.replace( re, QString() );
1642 return QVariant( str );
1647 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1649 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1651 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1652 str.replace( re, QString() );
1653 return QVariant( str );
1658 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1659 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1665 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1666 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1672 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1673 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1680 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1686 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1687 return QVariant( QString( character ) );
1692 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1694 if ( value.isEmpty() )
1699 int res = value.at( 0 ).unicode();
1700 return QVariant( res );
1705 if ( values.length() == 2 || values.length() == 3 )
1707 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1708 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1710 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1723 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1727 return QVariant( geom.
length() );
1733 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1734 return QVariant( str.length() );
1739 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1744 double totalLength = 0;
1749 totalLength += line->length3D();
1754 totalLength += segmentized->length3D();
1764 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1765 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1766 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1771 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1773 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1774 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1775 QVector< QPair< QString, QString > > mapItems;
1777 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1779 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1783 std::sort( mapItems.begin(), mapItems.end(), [](
const QPair< QString, QString > &pair1,
const QPair< QString, QString > &pair2 ) { return ( pair1.first.length() > pair2.first.length() ); } );
1785 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1787 str = str.replace( it->first, it->second );
1790 return QVariant( str );
1792 else if ( values.count() == 3 )
1794 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1795 QVariantList before;
1797 bool isSingleReplacement =
false;
1799 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1801 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1805 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1808 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1810 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1811 isSingleReplacement =
true;
1815 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1818 if ( !isSingleReplacement && before.length() != after.length() )
1820 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1824 for (
int i = 0; i < before.length(); i++ )
1826 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1829 return QVariant( str );
1833 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1840 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1841 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1842 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1844 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1845 if ( !re.isValid() )
1847 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1850 return QVariant( str.replace( re, after ) );
1855 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1856 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1858 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1859 if ( !re.isValid() )
1861 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1864 return QVariant( ( str.indexOf( re ) + 1 ) );
1869 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1870 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1871 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1873 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1874 if ( !re.isValid() )
1876 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1880 QRegularExpressionMatch matches = re.match( str );
1881 if ( matches.hasMatch() )
1884 QStringList list = matches.capturedTexts();
1887 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1889 array += ( !( *it ).isEmpty() ) ? *it : empty;
1892 return QVariant( array );
1902 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1903 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1905 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1906 if ( !re.isValid() )
1908 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1913 QRegularExpressionMatch match = re.match( str );
1914 if ( match.hasMatch() )
1917 if ( match.lastCapturedIndex() > 0 )
1920 return QVariant( match.captured( 1 ) );
1925 return QVariant( match.captured( 0 ) );
1930 return QVariant(
"" );
1936 const int version = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1941 uuid = QUuid::createUuid();
1944#if QT_VERSION >= QT_VERSION_CHECK( 6, 9, 0 )
1945 uuid = QUuid::createUuidV7();
1947 parent->
setEvalErrorString( QObject::tr(
"UUid version 7 is not supported on this QGIS build" ) );
1952 parent->
setEvalErrorString( QObject::tr(
"UUid version %1 is not supported" ).arg( version ) );
1956 const QString format = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1957 if ( format.compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1958 return uuid.toString( QUuid::StringFormat::WithoutBraces );
1959 else if ( format.compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1960 return uuid.toString( QUuid::StringFormat::Id128 );
1961 return uuid.toString();
1966 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1969 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1970 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1973 if ( values.at( 2 ).isValid() )
1974 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1980 from = str.size() + from;
1986 else if ( from > 0 )
1994 len = str.size() + len - from;
2001 return QVariant( str.mid( from, len ) );
2006 return QVariant( f.
id() );
2011 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2012 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
2013 bool foundLayer =
false;
2014 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2019 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
2020 if ( !layer || !layer->dataProvider() )
2022 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2026 if ( bandNb < 1 || bandNb > layer->bandCount() )
2028 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
2034 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
2041 QgsMultiPointXY multiPoint = geom.asMultiPoint();
2042 if ( multiPoint.count() == 1 )
2044 point = multiPoint[0];
2053 double value = layer->dataProvider()->sample( point, bandNb );
2054 return std::isnan( value ) ? QVariant() : value;
2061 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
2072 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2073 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2075 bool foundLayer =
false;
2076 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2080 [parent, bandNb, value](
QgsMapLayer *mapLayer ) -> QVariant {
2081 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
2082 if ( !layer || !layer->dataProvider() )
2084 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2088 if ( bandNb < 1 || bandNb > layer->bandCount() )
2090 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
2094 if ( std::isnan( value ) )
2096 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
2100 if ( !layer->dataProvider()->attributeTable( bandNb ) )
2105 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
2106 if ( data.isEmpty() )
2112 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
2113 for (
int idx = 0; idx < static_cast<int>( fields.count() ) && idx < static_cast<int>( data.count() ); ++idx )
2120 result.insert( fields.at( idx ).name, data.at( idx ) );
2130 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2151 if ( values.size() == 1 )
2153 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2156 else if ( values.size() == 2 )
2158 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2159 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2163 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2172 QString table { R
"html(
2175 <tr><th>%1</th></tr>
2178 <tr><td>%2</td></tr>
2182 if ( values.size() == 1 )
2184 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2188 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2192 if ( dict.isEmpty() )
2197 QStringList headers;
2200 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2202 headers.push_back( it.key().toHtmlEscaped() );
2203 cells.push_back( it.value().toString().toHtmlEscaped() );
2206 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2211 QString table { R
"html(
2216 if ( values.size() == 1 )
2218 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2222 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2226 if ( dict.isEmpty() )
2233 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2235 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2238 return table.arg( rows );
2246 layer = context->
variable( u
"layer"_s );
2251 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2253 layer = node->
eval( parent, context );
2264 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2268 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2269 if ( strength ==
"hard"_L1 )
2273 else if ( strength ==
"soft"_L1 )
2278 bool foundLayer =
false;
2279 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2283 [parent, feature, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2284 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2287 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2293 for (
int i = 0; i < fields.
size(); i++ )
2310 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2322 layer = context->
variable( u
"layer"_s );
2327 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2329 layer = node->
eval( parent, context );
2340 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2344 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2345 if ( strength ==
"hard"_L1 )
2349 else if ( strength ==
"soft"_L1 )
2354 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2356 bool foundLayer =
false;
2357 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2361 [parent, feature, attributeName, constraintStrength](
QgsMapLayer *mapLayer ) -> QVariant {
2362 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2369 if ( fieldIndex == -1 )
2371 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2384 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2400 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2405 for (
int i = 0; i < fields.
count(); ++i )
2419 if ( values.isEmpty() )
2422 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2424 else if ( values.size() == 1 )
2426 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2427 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2429 else if ( values.size() == 2 )
2431 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2432 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2436 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2443 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2449 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2455 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2457 const QString fieldName { fields.
at( fieldIndex ).
name() };
2458 const QVariant attributeVal = feature.
attribute( fieldIndex );
2459 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2462 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2471 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2483 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2485 result.insert( fields.
at( fieldIndex ).
name(), value );
2500 bool evaluate =
true;
2504 if ( values.isEmpty() )
2507 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2509 else if ( values.size() == 1 )
2511 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2512 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2514 else if ( values.size() == 2 )
2516 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2517 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2519 else if ( values.size() == 3 )
2521 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2522 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2523 evaluate = values.value( 2 ).toBool();
2529 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2533 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2565 subContext.setFeature( feature );
2574 exp.prepare( &subContext );
2575 return exp.evaluate( &subContext ).toString();
2581 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2586 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2593 if ( values.isEmpty() )
2596 layer = context->
variable( u
"layer"_s );
2598 else if ( values.size() == 1 )
2600 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2601 layer = context->
variable( u
"layer"_s );
2603 else if ( values.size() == 2 )
2605 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2606 layer = values.at( 0 );
2610 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2614 bool foundLayer =
false;
2615 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2620 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2621 if ( !layer || !feature.
isValid() )
2640 if ( values.isEmpty() )
2641 layer = context->
variable( u
"layer"_s );
2642 else if ( values.count() == 1 )
2643 layer = values.at( 0 );
2646 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2650 bool foundLayer =
false;
2651 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
2656 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2674 static QMap<QString, qlonglong> counterCache;
2675 QVariant functionResult;
2677 auto fetchAndIncrementFunc = [values, parent, &functionResult](
QgsMapLayer *mapLayer,
const QString &databaseArgument ) {
2680 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2685 database = decodedUri.value( u
"path"_s ).toString();
2686 if ( database.isEmpty() )
2688 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2693 database = databaseArgument;
2696 const QString table = values.at( 1 ).toString();
2697 const QString idColumn = values.at( 2 ).toString();
2698 const QString filterAttribute = values.at( 3 ).toString();
2699 const QVariant filterValue = values.at( 4 ).toString();
2700 const QVariantMap defaultValues = values.at( 5 ).toMap();
2706 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2709 functionResult = QVariant();
2713 QString errorMessage;
2714 QString currentValSql;
2716 qlonglong nextId = 0;
2717 bool cachedMode =
false;
2718 bool valueRetrieved =
false;
2720 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2727 auto cachedCounter = counterCache.find( cacheString );
2729 if ( cachedCounter != counterCache.end() )
2731 qlonglong &cachedValue = cachedCounter.value();
2732 nextId = cachedValue;
2734 cachedValue = nextId;
2735 valueRetrieved =
true;
2740 if ( !cachedMode || !valueRetrieved )
2742 int result = SQLITE_ERROR;
2745 if ( !filterAttribute.isNull() )
2750 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2752 if ( result == SQLITE_OK )
2755 if ( sqliteStatement.
step() == SQLITE_ROW )
2761 if ( cachedMode && result == SQLITE_OK )
2763 counterCache.insert( cacheString, nextId );
2765 QObject::connect( layer->
dataProvider()->
transaction(), &QgsTransaction::destroyed, [cacheString]() { counterCache.remove( cacheString ); } );
2767 valueRetrieved =
true;
2771 if ( valueRetrieved )
2780 if ( !filterAttribute.isNull() )
2786 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2789 vals << iter.value().toString();
2792 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2793 upsertSql +=
" VALUES "_L1;
2794 upsertSql +=
'(' + vals.join(
',' ) +
')';
2796 int result = SQLITE_ERROR;
2800 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2807 result = sqliteDb.
exec( upsertSql, errorMessage );
2809 if ( result == SQLITE_OK )
2811 functionResult = QVariant( nextId );
2816 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2817 functionResult = QVariant();
2822 functionResult = QVariant();
2825 bool foundLayer =
false;
2826 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer *layer ) { fetchAndIncrementFunc( layer, QString() ); }, foundLayer );
2829 const QString databasePath = values.at( 0 ).toString();
2833 return functionResult;
2846 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2851 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2854 return QVariant::fromValue( crs );
2859 QString concat(
"" );
2860 for (
const QVariant &value : values )
2863 concat += QgsExpressionUtils::getStringValue( value, parent );
2870 if ( values.length() < 2 )
2872 parent->
setEvalErrorString( QObject::tr(
"Function concat_ws requires at least 2 arguments" ) );
2876 const QString separator = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2878 QStringList stringValues;
2879 stringValues.reserve( values.size() - 1 );
2880 for (
int i = 1; i < values.size(); ++i )
2882 const QVariant value = values.at( i );
2885 stringValues.append( QgsExpressionUtils::getStringValue( value, parent ) );
2889 return stringValues.join( separator );
2894 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2895 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2903 if ( values.isEmpty() || values[0].isNull() )
2911 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2912 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2913 return string.right( pos );
2918 if ( values.length() < 2 || values.length() > 3 )
2921 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2922 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2924 bool overlapping =
false;
2925 if ( values.length() == 3 )
2927 overlapping = values.at( 2 ).toBool();
2930 if ( substring.isEmpty() )
2931 return QVariant( 0 );
2936 count = input.count( substring );
2941 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2944 pos += substring.length();
2948 return QVariant( count );
2953 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2954 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2955 return string.left( pos );
2960 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2961 const int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2962 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2963 if ( fill.isEmpty() )
2967 return string.leftJustified( length, fill.at( 0 ),
true );
2972 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2973 const int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2974 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2975 if ( fill.isEmpty() )
2979 return string.rightJustified( length, fill.at( 0 ),
true );
2984 if ( values.size() < 1 )
2986 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2990 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2991 for (
int n = 1; n < values.length(); n++ )
2993 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
3001 return QVariant( QDateTime::currentDateTime() );
3006 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3007 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3008 if ( format.isEmpty() && !language.isEmpty() )
3010 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
3011 return QVariant( QDate() );
3014 if ( format.isEmpty() && language.isEmpty() )
3015 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
3017 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3018 QLocale locale = QLocale();
3019 if ( !language.isEmpty() )
3021 locale = QLocale( language );
3024 QDate date = locale.toDate( datestring, format );
3025 if ( !date.isValid() )
3027 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
3030 return QVariant( date );
3035 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3036 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3037 if ( format.isEmpty() && !language.isEmpty() )
3039 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
3040 return QVariant( QTime() );
3043 if ( format.isEmpty() && language.isEmpty() )
3044 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
3046 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3047 QLocale locale = QLocale();
3048 if ( !language.isEmpty() )
3050 locale = QLocale( language );
3053 QTime time = locale.toTime( timestring, format );
3054 if ( !time.isValid() )
3056 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
3059 return QVariant( time );
3064 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
3073 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3074 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3075 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3077 QString formatString;
3078 if ( values.count() > 3 )
3079 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
3082 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
3086 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
3090 else if ( !formatString.isEmpty() )
3092 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
3096 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
3100 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
3106 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
3114 return floatToDegreeFormat( format, values, context, parent, node );
3121 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
3123 return ok ? QVariant( value ) : QVariant();
3129 return floatToDegreeFormat( format, values, context, parent, node );
3134 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3135 return static_cast< int >( decimalDegrees );
3140 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3141 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3142 return static_cast< int >( remainder * 60 );
3147 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
3148 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
3149 const double remainderInMinutes = remainder * 60;
3150 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
3152 return remainderSecondsFraction * 60;
3157 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3158 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3159 qint64 seconds = d2.secsTo( d1 );
3160 return QVariant::fromValue(
QgsInterval( seconds ) );
3165 if ( !values.at( 0 ).canConvert<QDate>() )
3168 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
3169 if ( !date.isValid() )
3174 return date.dayOfWeek() % 7;
3179 QVariant value = values.at( 0 );
3180 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3183 return QVariant( inter.
days() );
3187 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3188 return QVariant( d1.date().day() );
3194 QVariant value = values.at( 0 );
3195 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3198 return QVariant( inter.
years() );
3202 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3203 return QVariant( d1.date().year() );
3209 QVariant value = values.at( 0 );
3210 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3213 return QVariant( inter.
months() );
3217 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3218 return QVariant( d1.date().month() );
3224 QVariant value = values.at( 0 );
3225 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3228 return QVariant( inter.
weeks() );
3232 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3233 return QVariant( d1.date().weekNumber() );
3239 QVariant value = values.at( 0 );
3240 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3243 return QVariant( inter.
hours() );
3247 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3248 return QVariant( t1.hour() );
3254 QVariant value = values.at( 0 );
3255 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3258 return QVariant( inter.
minutes() );
3262 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3263 return QVariant( t1.minute() );
3269 QVariant value = values.at( 0 );
3270 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3273 return QVariant( inter.
seconds() );
3277 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3278 return QVariant( t1.second() );
3284 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3287 return QVariant( dt.toMSecsSinceEpoch() );
3297 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3299 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3304 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3307 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3310 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3316 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3319 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3328 if ( !dateTime.isValid() )
3333 const int year = dateTime.date().year();
3334 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3335 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3336 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3337 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3338 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3343 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3344 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3347 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3350 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3355 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3360 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3365 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3370 double declination = 0;
3377 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3389 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3390 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3393 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3396 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3401 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3406 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3411 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3416 double inclination = 0;
3423 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3435 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3436 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3439 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3442 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3447 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3452 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3457 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3462 double declination = 0;
3470 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3480 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3486 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3492 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3497 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3504 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3505 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3508 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3511 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3516 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3521 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3526 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3531 double declination = 0;
3539 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3549 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3555 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3561 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3566 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3571#define ENSURE_GEOM_TYPE( f, g, geomtype ) \
3572 if ( !( f ).hasGeometry() ) \
3573 return QVariant(); \
3574 QgsGeometry g = ( f ).geometry(); \
3575 if ( ( g ).type() != ( geomtype ) ) \
3582 if ( g.isMultipart() )
3584 return g.asMultiPoint().at( 0 ).x();
3588 return g.asPoint().x();
3596 if ( g.isMultipart() )
3598 return g.asMultiPoint().at( 0 ).y();
3602 return g.asPoint().y();
3616 if ( g.isEmpty() || !abGeom->
is3D() )
3629 if ( collection->numGeometries() > 0 )
3642 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3648 return QVariant( isValid );
3653 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3657 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3658#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
3663 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3665 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3668 const bool keepCollapsed = values.value( 2 ).toBool();
3673 valid = geom.
makeValid( method, keepCollapsed );
3677 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3681 return QVariant::fromValue( valid );
3686 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3692 for (
int i = 0; i < multiGeom.size(); ++i )
3694 array += QVariant::fromValue( multiGeom.at( i ) );
3702 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3714 QVariant result( centroid.
asPoint().
x() );
3720 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3732 QVariant result( centroid.
asPoint().
y() );
3738 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3756 if ( collection->numGeometries() == 1 )
3769 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3787 if ( collection->numGeometries() == 1 )
3800 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3805 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3832 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3849 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3866 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3871 bool ignoreClosing =
false;
3872 if ( values.length() > 1 )
3874 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3884 bool skipLast =
false;
3885 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3890 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++i )
3902 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3913 for (
int i = 0; i < line->numPoints() - 1; ++i )
3927 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3937 if ( collection->numGeometries() == 1 )
3944 if ( !curvePolygon )
3948 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3954 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3960 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3970 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3976 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3982 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3991 return QVariant::fromValue(
QgsGeometry( boundary ) );
3996 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4005 return QVariant::fromValue( merged );
4010 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4014 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4019 if ( sharedPaths.
isNull() )
4022 return QVariant::fromValue( sharedPaths );
4028 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4033 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4036 if ( simplified.
isNull() )
4044 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4049 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4054 if ( simplified.
isNull() )
4062 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4067 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
4068 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
4069 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4070 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
4072 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
4081 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4086 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4087 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4088 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4099 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4104 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4105 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4106 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4107 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4108 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4119 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4124 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4125 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4126 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4137 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4142 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4143 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4144 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4145 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4146 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4157 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4162 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4163 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4164 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4175 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4180 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4181 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4182 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4183 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4184 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4195 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4200 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4201 QVector< double > dashPattern;
4202 dashPattern.reserve( pattern.size() );
4203 for (
const QVariant &value : std::as_const( pattern ) )
4206 double v = value.toDouble( &ok );
4218 if ( dashPattern.size() % 2 != 0 )
4220 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4224 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4226 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4228 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4230 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4232 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4234 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4238 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4242 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4244 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4246 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4248 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4250 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4252 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4256 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4260 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4262 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4264 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4266 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4270 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4274 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4285 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4290 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4292 if ( densified.
isNull() )
4300 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4305 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4307 if ( densified.
isNull() )
4316 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4318 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4325 QVector< QgsGeometry > parts;
4326 parts.reserve( list.size() );
4327 for (
const QVariant &value : std::as_const( list ) )
4329 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4340 if ( values.count() < 2 || values.count() > 4 )
4342 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4346 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4347 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4348 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4349 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4350 switch ( values.count() )
4364 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4365 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4366 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4372 if ( values.empty() )
4377 QVector<QgsPoint> points;
4378 points.reserve( values.count() );
4380 auto addPoint = [&points](
const QgsGeometry &geom ) {
4394 for (
const QVariant &value : values )
4396 if ( value.userType() == QMetaType::Type::QVariantList )
4398 const QVariantList list = value.toList();
4399 for (
const QVariant &v : list )
4401 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4406 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4410 if ( points.count() < 2 )
4418 if ( values.count() < 1 )
4420 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4424 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4432 auto polygon = std::make_unique< QgsPolygon >();
4446 if ( !exteriorRing )
4449 polygon->setExteriorRing( exteriorRing->
segmentize() );
4452 for (
int i = 1; i < values.count(); ++i )
4454 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4476 polygon->addInteriorRing( ring->
segmentize() );
4479 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4484 auto tr = std::make_unique<QgsTriangle>();
4485 auto lineString = std::make_unique<QgsLineString>();
4486 lineString->clear();
4488 for (
const QVariant &value : values )
4490 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4512 lineString->addVertex( *point );
4515 tr->setExteriorRing( lineString.release() );
4517 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4522 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4529 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4530 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4552 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4557 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4564 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4565 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4566 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4567 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4587 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4588 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4593 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4600 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4607 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4610 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4617 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4656 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4662 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4677 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4683 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4689 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4698 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4722 return QVariant::fromValue( geom.
vertexAt( idx ) );
4730 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4732 const QVariant v = pointAt( geom, idx, parent );
4735 return QVariant( v.value<
QgsPoint>().
x() );
4741 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4743 return fcnOldXat( values, f, parent, node );
4745 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4747 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4750 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4756 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4758 const QVariant v = pointAt( geom, vertexNumber, parent );
4760 return QVariant( v.value<
QgsPoint>().
x() );
4770 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4772 const QVariant v = pointAt( geom, idx, parent );
4775 return QVariant( v.value<
QgsPoint>().
y() );
4781 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4783 return fcnOldYat( values, f, parent, node );
4785 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4787 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4790 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4796 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4798 const QVariant v = pointAt( geom, vertexNumber, parent );
4800 return QVariant( v.value<
QgsPoint>().
y() );
4807 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4813 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4815 const QVariant v = pointAt( geom, vertexNumber, parent );
4817 return QVariant( v.value<
QgsPoint>().
z() );
4824 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4830 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4832 const QVariant v = pointAt( geom, vertexNumber, parent );
4834 return QVariant( v.value<
QgsPoint>().
m() );
4842 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4844 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4850 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4856 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4861 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4868 ogcContext.
layer = mapLayerPtr.data();
4873 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4888 return QVariant( area );
4892 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4904 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4909 return QVariant( geom.
area() );
4923 return QVariant( len );
4927 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4948 return QVariant( len );
4952 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4958 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4964 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4970 return QVariant( geom.
length() );
4975 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 );
4999 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5015 if ( !curvePolygon )
5027 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5034 return QVariant( curvePolygon->
ringCount() );
5036 bool foundPoly =
false;
5045 if ( !curvePolygon )
5056 return QVariant( ringCount );
5061 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5063 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
5069 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5075 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5081 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5090 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5096 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5102 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5108 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5114 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5122 double max = std::numeric_limits< double >::lowest();
5126 double z = ( *it ).z();
5132 if ( max == std::numeric_limits< double >::lowest() )
5135 return QVariant( max );
5140 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5148 double min = std::numeric_limits< double >::max();
5152 double z = ( *it ).z();
5158 if ( min == std::numeric_limits< double >::max() )
5161 return QVariant( min );
5166 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5174 double min = std::numeric_limits< double >::max();
5178 double m = ( *it ).m();
5184 if ( min == std::numeric_limits< double >::max() )
5187 return QVariant( min );
5192 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5200 double max = std::numeric_limits< double >::lowest();
5204 double m = ( *it ).m();
5210 if ( max == std::numeric_limits< double >::lowest() )
5213 return QVariant( max );
5218 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5222 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5231 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5235 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5244 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5249 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5259 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5263 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5265 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5270 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5289 return QVariant::fromValue( curve->
isClosed() );
5294 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5307 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5308 closedLine->close();
5310 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5324 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5325 closedLine->close();
5327 closed->addGeometry( closedLine.release() );
5330 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5338 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5342 return QVariant::fromValue( fGeom.
isEmpty() );
5348 return QVariant::fromValue(
true );
5350 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5351 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5356 if ( values.length() < 2 || values.length() > 3 )
5359 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5360 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5367 if ( values.length() == 2 )
5370 QString result = engine->relate( sGeom.
constGet() );
5371 return QVariant::fromValue( result );
5376 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5377 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5378 return QVariant::fromValue( result );
5384 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5385 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5390 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5391 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5392 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5396 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5397 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5398 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5402 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5403 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5404 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5408 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5409 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5410 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5414 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5415 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5416 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5420 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5421 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5422 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5426 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5427 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5428 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5433 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5434 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5440 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5441 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5442 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5447 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5449 QVariant ret = TVL_False;
5452 ret = fGeom.
isExactlyEqual( sGeom, backend ) ? TVL_True : TVL_False;
5463 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5464 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5465 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5470 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5472 QVariant ret = TVL_False;
5486 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5487 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5488 const QString backendStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5493 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
5495 double epsilon = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5497 QVariant ret = TVL_False;
5500 ret = fGeom.
isFuzzyEqual( sGeom, epsilon, backend ) ? TVL_True : TVL_False;
5511 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5512 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5513 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5514 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5515 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5516 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5519 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5521 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5525 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5527 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5531 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5537 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5539 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5544 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5546 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5551 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5553 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5558 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5573 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5577 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5578 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5579 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5580 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5583 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5589 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5592 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5596 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5597 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5598 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5601 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5607 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5610 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5614 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5617 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5623 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5624 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5625 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5626 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5627 if ( joinInt < 1 || joinInt > 3 )
5631 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5634 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5640 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5641 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5642 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5644 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5645 if ( joinInt < 1 || joinInt > 3 )
5649 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5652 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5658 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5659 const double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5660 const double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5662 const double deflectionStart = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5663 const double deflectionEnd = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5666 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5672 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5673 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5674 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5676 return QVariant::fromValue( fGeom );
5681 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5682 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5684 const bool perPart = values.value( 3 ).toBool();
5691 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5692 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5694 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5695 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5696 t.rotate( -rotation );
5697 t.translate( -partCenter.x(), -partCenter.y() );
5698 ( *it )->transform( t );
5700 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5712 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5720 fGeom.
rotate( rotation, pt );
5721 return QVariant::fromValue( fGeom );
5727 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5728 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5729 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5730 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent ) :
QgsGeometry();
5736 pt = fGeom.boundingBox().center();
5740 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5745 pt = center.asPoint();
5748 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5749 t.scale( xScale, yScale );
5750 t.translate( -pt.
x(), -pt.
y() );
5752 return QVariant::fromValue( fGeom );
5757 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5763 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5764 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5766 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5768 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5769 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5771 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5772 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5773 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5774 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5785 QTransform transform;
5786 transform.translate( deltaX, deltaY );
5787 transform.rotate( rotationZ );
5788 transform.scale( scaleX, scaleY );
5789 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5791 return QVariant::fromValue( fGeom );
5797 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5799 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5804 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5806 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5812 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5813 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5815 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5821 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5823 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5827#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
5832 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5833 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5834 const bool allowHoles = values.value( 2 ).toBool();
5836 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5849 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5851 if ( values.length() == 2 )
5852 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5860 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5866 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5868 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5874 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5880 double area,
angle, width, height;
5893 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5894 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5896 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5907 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5918 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5928 reversed->addGeometry( curve->
reversed() );
5935 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5941 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5942 std::reverse(
string.begin(),
string.end() );
5948 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5968 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5974 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5975 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5976 return QVariant( fGeom.
distance( sGeom ) );
5981 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5982 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5985 if ( values.length() == 3 && values.at( 2 ).isValid() )
5987 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5988 densify = std::clamp( densify, 0.0, 1.0 );
5996 return res > -1 ? QVariant( res ) : QVariant();
6001 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6002 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6004 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6009 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6010 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6012 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6017 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6018 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6020 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6026 if ( values.length() < 1 || values.length() > 2 )
6029 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6031 if ( values.length() == 2 )
6032 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6033 QString wkt = fGeom.
asWkt( prec );
6034 return QVariant( wkt );
6039 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6040 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
6045 if ( values.length() != 2 )
6047 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
6051 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6052 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6080 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
6087 if ( pt1->
y() < pt2->
y() )
6089 else if ( pt1->
y() > pt2->
y() )
6097 if ( pt1->
x() < pt2->
x() )
6099 else if ( pt1->
x() > pt2->
x() )
6100 return M_PI + ( M_PI_2 );
6105 if ( pt1->
x() < pt2->
x() )
6107 if ( pt1->
y() < pt2->
y() )
6109 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
6113 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI_2 );
6119 if ( pt1->
y() > pt2->
y() )
6121 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) ) + M_PI;
6125 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) ) + ( M_PI + ( M_PI_2 ) );
6132 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6133 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6135 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
6139 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
6147 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
6161 if ( ellipsoid.isEmpty() )
6163 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
6169 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
6177 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
6183 const double bearing = da.
bearing( point1, point2 );
6184 if ( std::isfinite( bearing ) )
6186 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
6199 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6207 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6208 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6209 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
6212 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6219 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6220 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6247 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6256 if ( values.length() != 3 )
6259 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6260 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6261 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6265 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6271 if ( values.length() < 2 )
6274 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6277 return values.at( 0 );
6279 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6280 QVariant cachedExpression;
6285 if ( cachedExpression.isValid() )
6292 bool asc = values.value( 2 ).toBool();
6310 Q_ASSERT( collection );
6314 QgsExpressionSorter sorter( orderBy );
6316 QList<QgsFeature> partFeatures;
6317 partFeatures.reserve( collection->
partCount() );
6318 for (
int i = 0; i < collection->
partCount(); ++i )
6324 sorter.sortFeatures( partFeatures, unconstedContext );
6328 Q_ASSERT( orderedGeom );
6333 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6338 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6341 delete unconstedContext;
6348 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6349 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6353 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6359 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6360 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6364 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6370 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6371 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6375 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6381 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6382 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6383 const bool use3DDistance = values.at( 2 ).toBool();
6385 double x, y, z, distance;
6408 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6411 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6431 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6432 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6434 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6436 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6441 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6442 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6449 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6450 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6455 vertex = count + vertex;
6463 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6464 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6469 vertex = count + vertex;
6477 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6478 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6482 return distance >= 0 ? distance : QVariant();
6487 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6488 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6489 const bool use3DDistance = values.at( 2 ).toBool();
6491 double x, y, z, distance;
6500 return found ? distance : QVariant();
6505 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6507 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6508 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6511 if ( values.length() >= 1 )
6513 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6514 return QVariant( qlonglong( std::round( number ) ) );
6529 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6530 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6531 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6538 const bool omitGroupSeparator = values.value( 3 ).toBool();
6539 const bool trimTrailingZeros = values.value( 4 ).toBool();
6541 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6542 if ( !omitGroupSeparator )
6543 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6545 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6547 QString res = locale.toString( value,
'f', places );
6549 if ( trimTrailingZeros )
6551 const QChar decimal = locale.decimalPoint().at( 0 );
6552 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6554 if ( res.contains( decimal ) )
6556 int trimPoint = res.length() - 1;
6558 while ( res.at( trimPoint ) == zeroDigit )
6561 if ( res.at( trimPoint ) == decimal )
6564 res.truncate( trimPoint + 1 );
6573 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6574 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6575 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6578 if ( format.indexOf(
"Z" ) > 0 )
6579 datetime = datetime.toUTC();
6581 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6582 return locale.toString( datetime, format );
6587 const QVariant variant = values.at( 0 );
6589 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6590 if ( !color.isValid() )
6593 const float alpha = color.alphaF();
6594 if ( color.spec() == QColor::Spec::Cmyk )
6596 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() )
6598 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6602 const float avg = ( color.redF() + color.greenF() + color.blueF() )
6604 color.setRgbF( avg, avg, avg, alpha );
6607 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6614 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6619 else if ( ratio < 0 )
6624 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6625 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6626 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6627 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6629 QColor newColor( red, green, blue, alpha );
6636 const QVariant variant1 = values.at( 0 );
6637 const QVariant variant2 = values.at( 1 );
6639 if ( variant1.userType() != variant2.userType() )
6641 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6646 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6647 if ( !color1.isValid() )
6650 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6651 if ( !color2.isValid() )
6654 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6656 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6660 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6666 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6667 if ( color1.spec() == QColor::Spec::Cmyk )
6669 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6670 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6671 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6672 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6673 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6677 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6678 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6679 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6680 newColor = QColor::fromRgbF( red, green, blue, alpha );
6685 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6690 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6691 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6692 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6693 QColor color = QColor( red, green, blue );
6694 if ( !color.isValid() )
6696 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6697 color = QColor( 0, 0, 0 );
6700 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6705 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6706 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6707 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6708 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6709 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6710 if ( !color.isValid() )
6712 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6721 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6722 QVariant value = node->
eval( parent, context );
6726 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6728 value = node->
eval( parent, context );
6736 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6738 QVariant value = node->
eval( parent, context );
6740 if ( value.toBool() )
6742 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6744 value = node->
eval( parent, context );
6749 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6751 value = node->
eval( parent, context );
6759 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6760 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6761 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6762 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6763 QColor color = QColor( red, green, blue, alpha );
6764 if ( !color.isValid() )
6766 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6767 color = QColor( 0, 0, 0 );
6776 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6778 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6783 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6787 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6792 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6793 QColor color = ramp->
color( value );
6806 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6808 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6810 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6812 QColor color = QColor::fromHslF( hue, saturation, lightness );
6814 if ( !color.isValid() )
6816 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6817 color = QColor( 0, 0, 0 );
6820 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6826 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6828 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6830 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6832 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6834 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6835 if ( !color.isValid() )
6837 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6838 color = QColor( 0, 0, 0 );
6845 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6846 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6847 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6848 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6850 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6851 if ( !color.isValid() )
6853 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6863 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6865 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6867 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6869 QColor color = QColor::fromHsvF( hue, saturation, value );
6871 if ( !color.isValid() )
6873 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6874 color = QColor( 0, 0, 0 );
6877 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6883 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6885 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6887 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6889 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6891 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6892 if ( !color.isValid() )
6894 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6895 color = QColor( 0, 0, 0 );
6902 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6903 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6904 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6905 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6906 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6908 if ( !color.isValid() )
6910 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6919 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6920 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6921 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6922 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6923 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6925 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6926 if ( !color.isValid() )
6928 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6938 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6940 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6942 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6944 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6946 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6948 if ( !color.isValid() )
6950 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6951 color = QColor( 0, 0, 0 );
6954 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6960 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6962 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6964 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6966 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6968 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6970 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6971 if ( !color.isValid() )
6973 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6974 color = QColor( 0, 0, 0 );
6981 const QVariant variant = values.at( 0 );
6983 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6984 if ( !color.isValid() )
6987 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6988 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6990 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6991 return color.green();
6992 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6993 return color.blue();
6994 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6995 return color.alpha();
6996 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6997 return static_cast< double >( color.hsvHueF() * 360 );
6998 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6999 return static_cast< double >( color.hsvSaturationF() * 100 );
7000 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7001 return static_cast< double >( color.valueF() * 100 );
7002 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7003 return static_cast< double >( color.hslHueF() * 360 );
7004 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7005 return static_cast< double >( color.hslSaturationF() * 100 );
7006 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7007 return static_cast< double >( color.lightnessF() * 100 );
7008 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7009 return static_cast< double >( color.cyanF() * 100 );
7010 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7011 return static_cast< double >( color.magentaF() * 100 );
7012 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7013 return static_cast< double >( color.yellowF() * 100 );
7014 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7015 return static_cast< double >( color.blackF() * 100 );
7017 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7023 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7026 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
7030 QList< QColor > colors;
7032 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7035 if ( !colors.last().isValid() )
7037 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
7041 double step = it.key().toDouble();
7042 if ( it == map.constBegin() )
7047 else if ( it == map.constEnd() )
7057 bool discrete = values.at( 1 ).toBool();
7059 if ( colors.empty() )
7062 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
7067 const QVariant variant = values.at( 0 );
7069 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7070 if ( !color.isValid() )
7073 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7074 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7075 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
7076 color.setRed( std::clamp( value, 0, 255 ) );
7077 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
7078 color.setGreen( std::clamp( value, 0, 255 ) );
7079 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
7080 color.setBlue( std::clamp( value, 0, 255 ) );
7081 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
7082 color.setAlpha( std::clamp( value, 0, 255 ) );
7083 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
7084 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
7085 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
7086 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
7087 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
7088 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7089 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
7090 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
7091 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
7092 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
7093 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
7094 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7095 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
7096 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
7097 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
7098 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
7099 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
7100 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
7101 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
7102 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
7105 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
7108 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7113 const QVariant variant = values.at( 0 );
7115 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7116 if ( !color.isValid() )
7119 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7121 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7126 const QVariant variant = values.at( 0 );
7128 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
7129 if ( !color.isValid() )
7132 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
7134 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
7139 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7142 return QVariant::fromValue( geom );
7148 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
7156 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
7161 return QVariant::fromValue( fGeom );
7164 return QVariant::fromValue( fGeom );
7173 return QVariant::fromValue( fGeom );
7186 bool foundLayer =
false;
7187 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7190 if ( !featureSource || !foundLayer )
7195 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
7208 result = QVariant::fromValue( fet );
7216 bool foundLayer =
false;
7217 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7220 if ( !featureSource || !foundLayer )
7225 QString cacheValueKey;
7226 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7228 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7230 QMap<QString, QVariant>::const_iterator i = attributeMap.constBegin();
7231 QString filterString;
7232 for ( ; i != attributeMap.constEnd(); ++i )
7234 if ( !filterString.isEmpty() )
7236 filterString.append(
" AND " );
7240 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7249 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7250 int attributeId = featureSource->fields().lookupField( attribute );
7251 if ( attributeId == -1 )
7256 const QVariant &attVal = values.at( 2 );
7258 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7281 res = QVariant::fromValue( fet );
7296 if ( !values.isEmpty() )
7299 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7300 fieldName = col->
name();
7301 else if ( values.size() == 2 )
7302 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7305 QVariant value = values.at( 0 );
7310 if ( fieldIndex == -1 )
7312 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7318 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7321 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7332 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7351 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7359 const QVariant data = values.at( 0 );
7360 const QMimeDatabase db;
7361 return db.mimeTypeForData( data.toByteArray() ).name();
7366 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7368 bool translate =
true;
7369 if ( values.length() >= 3 )
7371 translate = QgsExpressionUtils::getTVLValue( values.at( 2 ), parent ) == QgsExpressionUtils::TVL::True;
7374 bool foundLayer =
false;
7375 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7379 [layerProperty, translate](
QgsMapLayer *layer ) -> QVariant {
7384 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7385 return layer->name();
7386 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7388 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7389 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7390 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7391 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7392 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7394 QStringList keywords;
7395 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7396 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7398 keywords.append( it.value() );
7400 if ( !keywords.isEmpty() )
7402 return layer->serverProperties()->keywordList();
7404 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7406 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7408 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7410 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7412 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7414 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7416 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7418 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7420 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7422 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7424 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7426 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7428 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7431 QVariant result = QVariant::fromValue( extentGeom );
7434 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7436 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7439 return decodedUri.value( u
"path"_s );
7441 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7443 switch ( layer->
type() )
7446 return translate ? QCoreApplication::translate(
"expressions",
"Vector" ) : u
"Vector"_s;
7448 return translate ? QCoreApplication::translate(
"expressions",
"Raster" ) : u
"Raster"_s;
7450 return translate ? QCoreApplication::translate(
"expressions",
"Mesh" ) : u
"Mesh"_s;
7452 return translate ? QCoreApplication::translate(
"expressions",
"Vector Tile" ) : u
"Vector Tile"_s;
7454 return translate ? QCoreApplication::translate(
"expressions",
"Plugin" ) : u
"Plugin"_s;
7456 return translate ? QCoreApplication::translate(
"expressions",
"Annotation" ) : u
"Annotation"_s;
7458 return translate ? QCoreApplication::translate(
"expressions",
"Point Cloud" ) : u
"Point Cloud"_s;
7460 return translate ? QCoreApplication::translate(
"expressions",
"Group" ) : u
"Group"_s;
7462 return translate ? QCoreApplication::translate(
"expressions",
"Tiled Scene" ) : u
"Tiled Scene"_s;
7468 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7471 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7473 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7475 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7493 const QString uriPart = values.at( 1 ).toString();
7495 bool foundLayer =
false;
7497 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7501 [parent, uriPart](
QgsMapLayer *layer ) -> QVariant {
7502 if ( !layer->dataProvider() )
7504 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7510 if ( !uriPart.isNull() )
7512 return decodedUri.value( uriPart );
7524 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7535 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7536 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7538 bool foundLayer =
false;
7539 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe(
7543 [parent, band, layerProperty](
QgsMapLayer *layer ) -> QVariant {
7544 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7548 if ( band < 1 || band > rl->bandCount() )
7550 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7556 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7558 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7560 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7562 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7564 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7566 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7570 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7600 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7617 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7618 bool ascending = values.value( 1 ).toBool();
7619 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7625 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7630 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7635 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7640 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7641 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7643 for (
const auto &item : listB )
7645 if ( listA.contains( item ) )
7649 return QVariant( match == listB.count() );
7654 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7659 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7660 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7661 if ( pos < list.length() && pos >= 0 )
7662 return list.at( pos );
7663 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7664 return list.at( list.length() + pos );
7670 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7671 return list.value( 0 );
7676 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7677 return list.value( list.size() - 1 );
7682 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7683 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7688 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7689 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7694 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7697 for (
const QVariant &item : list )
7699 switch ( item.userType() )
7701 case QMetaType::Int:
7702 case QMetaType::UInt:
7703 case QMetaType::LongLong:
7704 case QMetaType::ULongLong:
7705 case QMetaType::Float:
7706 case QMetaType::Double:
7707 total += item.toDouble();
7712 return i == 0 ? QVariant() : total / i;
7717 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7718 QVariantList numbers;
7719 for (
const auto &item : list )
7721 switch ( item.userType() )
7723 case QMetaType::Int:
7724 case QMetaType::UInt:
7725 case QMetaType::LongLong:
7726 case QMetaType::ULongLong:
7727 case QMetaType::Float:
7728 case QMetaType::Double:
7729 numbers.append( item );
7733 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7734 const int count = numbers.count();
7739 else if ( count % 2 )
7741 return numbers.at( count / 2 );
7745 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7751 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7754 for (
const QVariant &item : list )
7756 switch ( item.userType() )
7758 case QMetaType::Int:
7759 case QMetaType::UInt:
7760 case QMetaType::LongLong:
7761 case QMetaType::ULongLong:
7762 case QMetaType::Float:
7763 case QMetaType::Double:
7764 total += item.toDouble();
7769 return i == 0 ? QVariant() : total;
7772static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7774 QVariant result = value;
7775 ( void ) result.convert(
static_cast<int>( type ) );
7781 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7782 QHash< QVariant, int > hash;
7783 for (
const auto &item : list )
7787 const QList< int > occurrences = hash.values();
7788 if ( occurrences.empty() )
7789 return QVariantList();
7791 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7793 const QString option = values.at( 1 ).toString();
7794 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7796 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7798 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7800 if ( hash.isEmpty() )
7803 return QVariant( hash.key( maxValue ) );
7805 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7807 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7809 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7811 if ( maxValue * 2 <= list.size() )
7814 return QVariant( hash.key( maxValue ) );
7825 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7826 QHash< QVariant, int > hash;
7827 for (
const auto &item : list )
7831 const QList< int > occurrences = hash.values();
7832 if ( occurrences.empty() )
7833 return QVariantList();
7835 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7837 const QString option = values.at( 1 ).toString();
7838 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7840 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7842 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7844 if ( hash.isEmpty() )
7847 return QVariant( hash.key( minValue ) );
7849 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7851 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7853 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7855 if ( hash.isEmpty() )
7859 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7860 if ( maxValue * 2 > list.size() )
7861 hash.remove( hash.key( maxValue ) );
7863 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7874 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7875 list.append( values.at( 1 ) );
7876 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7881 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7882 list.prepend( values.at( 1 ) );
7883 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7888 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7889 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7890 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7895 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7896 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7898 position = position + list.length();
7899 if ( position >= 0 && position < list.length() )
7900 list.removeAt( position );
7901 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7909 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7911 const QVariant toRemove = values.at( 1 );
7914 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant &element ) { return QgsVariantUtils::isNull( element ); } ), list.end() );
7918 list.removeAll( toRemove );
7920 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7925 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7927 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7929 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7930 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7932 int index = list.indexOf( it.key() );
7933 while ( index >= 0 )
7935 list.replace( index, it.value() );
7936 index = list.indexOf( it.key() );
7940 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7942 else if ( values.count() == 3 )
7944 QVariantList before;
7946 bool isSingleReplacement =
false;
7948 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7950 before = QVariantList() << values.at( 1 );
7954 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7957 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7959 after = QVariantList() << values.at( 2 );
7960 isSingleReplacement =
true;
7964 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7967 if ( !isSingleReplacement && before.length() != after.length() )
7969 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7973 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7974 for (
int i = 0; i < before.length(); i++ )
7976 int index = list.indexOf( before.at( i ) );
7977 while ( index >= 0 )
7979 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7980 index = list.indexOf( before.at( i ) );
7984 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7988 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7995 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7996 QVariantList list_new;
7998 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
8000 while ( list.removeOne( cur ) )
8002 list_new.append( cur );
8006 list_new.append( list );
8008 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8014 for (
const QVariant &cur : values )
8016 list += QgsExpressionUtils::getListValue( cur, parent );
8018 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
8023 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8024 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
8025 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
8026 int slice_length = 0;
8028 if ( start_pos < 0 )
8030 start_pos = list.length() + start_pos;
8034 slice_length = end_pos - start_pos + 1;
8038 slice_length = list.length() + end_pos - start_pos + 1;
8041 if ( slice_length < 0 )
8045 list = list.mid( start_pos, slice_length );
8051 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8052 std::reverse( list.begin(), list.end() );
8058 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8059 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
8060 for (
const QVariant &cur : array2 )
8062 if ( array1.contains( cur ) )
8063 return QVariant(
true );
8065 return QVariant(
false );
8070 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8072 QVariantList distinct;
8074 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8076 if ( !distinct.contains( *it ) )
8078 distinct += ( *it );
8087 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
8088 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8089 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8093 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8095 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
8096 if ( it != ( array.constEnd() - 1 ) )
8102 return QVariant( str );
8107 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8108 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8109 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
8111 QStringList list = str.split( delimiter );
8114 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
8116 array += ( !( *it ).isEmpty() ) ? *it : empty;
8124 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8125 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
8126 if ( document.isNull() )
8129 return document.toVariant();
8135 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
8136 return QString( document.toJson( QJsonDocument::Compact ) );
8141 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8142 if ( str.isEmpty() )
8143 return QVariantMap();
8144 str = str.trimmed();
8151 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8158 for (
int i = 0; i + 1 < values.length(); i += 2 )
8160 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
8167 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8168 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
8169 QVariantMap resultMap;
8171 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8173 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
8181 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
8186 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
8191 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8192 map.remove( values.at( 1 ).toString() );
8198 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8199 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
8206 for (
const QVariant &cur : values )
8208 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
8209 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
8210 result.insert( it.key(), it.value() );
8217 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
8222 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
8227 const QString envVarName = values.at( 0 ).toString();
8228 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
8231 return QProcessEnvironment::systemEnvironment().value( envVarName );
8236 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8239 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
8242 return QFileInfo( file ).completeBaseName();
8247 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8250 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8253 return QFileInfo( file ).completeSuffix();
8258 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8261 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8264 return QFileInfo::exists( file );
8269 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8272 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8275 return QFileInfo( file ).fileName();
8280 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8283 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8286 return QFileInfo( file ).isFile();
8291 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8294 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8297 return QFileInfo( file ).isDir();
8302 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8305 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8308 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8313 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8316 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8319 return QFileInfo( file ).size();
8322static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8324 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8330 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8331 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8333 if ( method ==
"md4"_L1 )
8335 hash = fcnHash( str, QCryptographicHash::Md4 );
8337 else if ( method ==
"md5"_L1 )
8339 hash = fcnHash( str, QCryptographicHash::Md5 );
8341 else if ( method ==
"sha1"_L1 )
8343 hash = fcnHash( str, QCryptographicHash::Sha1 );
8345 else if ( method ==
"sha224"_L1 )
8347 hash = fcnHash( str, QCryptographicHash::Sha224 );
8349 else if ( method ==
"sha256"_L1 )
8351 hash = fcnHash( str, QCryptographicHash::Sha256 );
8353 else if ( method ==
"sha384"_L1 )
8355 hash = fcnHash( str, QCryptographicHash::Sha384 );
8357 else if ( method ==
"sha512"_L1 )
8359 hash = fcnHash( str, QCryptographicHash::Sha512 );
8361 else if ( method ==
"sha3_224"_L1 )
8363 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8365 else if ( method ==
"sha3_256"_L1 )
8367 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8369 else if ( method ==
"sha3_384"_L1 )
8371 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8373 else if ( method ==
"sha3_512"_L1 )
8375 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8377 else if ( method ==
"keccak_224"_L1 )
8379 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8381 else if ( method ==
"keccak_256"_L1 )
8383 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8385 else if ( method ==
"keccak_384"_L1 )
8387 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8389 else if ( method ==
"keccak_512"_L1 )
8391 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8395 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8402 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8407 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8412 const QByteArray input = values.at( 0 ).toByteArray();
8413 return QVariant( QString( input.toBase64() ) );
8418 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8420 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8422 query.addQueryItem( it.key(), it.value().toString() );
8424 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8429 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8430 const QByteArray base64 = value.toLocal8Bit();
8431 const QByteArray decoded = QByteArray::fromBase64( base64 );
8432 return QVariant( decoded );
8438static QVariant executeGeomOverlay(
8439 const QVariantList &values,
8443 bool invert =
false,
8444 double bboxGrow = 0,
8445 bool isNearestFunc =
false,
8446 bool isIntersectsFunc =
false
8451 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8455 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8458 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8467 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8470 const bool layerCanBeCached = node->
isStatic( parent, context );
8471 QVariant targetLayerValue = node->
eval( parent, context );
8475 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8477 QString subExpString = node->dump();
8479 bool testOnly = ( subExpString ==
"NULL" );
8482 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8486 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8491 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8493 QString filterString = node->dump();
8494 if ( filterString !=
"NULL" )
8496 request.setFilterExpression( filterString );
8500 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8502 QVariant limitValue = node->eval( parent, context );
8504 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8506 double max_distance = 0;
8507 bool cacheEnabled =
false;
8509 double minOverlap { -1 };
8510 double minInscribedCircleRadius { -1 };
8511 bool returnDetails =
false;
8512 bool sortByMeasure =
false;
8513 bool sortAscending =
false;
8514 bool requireMeasures =
false;
8515 bool overlapOrRadiusFilter =
false;
8519 if ( isNearestFunc )
8522 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8524 QVariant distanceValue = node->eval( parent, context );
8526 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8529 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8531 QVariant cacheValue = node->eval( parent, context );
8533 cacheEnabled = cacheValue.toBool();
8538 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8540 QVariant cacheValue = node->eval( parent, context );
8542 cacheEnabled = cacheValue.toBool();
8545 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8547 const QVariant minOverlapValue = node->eval( parent, context );
8549 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8552 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8554 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8556 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8559 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8561 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8564 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8566 const QString sorting { node->eval( parent, context ).toString().toLower() };
8567 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8568 sortAscending = sorting.startsWith(
"asc" );
8569 requireMeasures = sortByMeasure || returnDetails;
8570 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8573 node = QgsExpressionUtils::getNode( values.at( 9 ), parent );
8575 const QString backendStr = node->eval( parent, context ).toString().toUpper();
8581 SET_EVAL_ERROR( u
"Geometry backend '%1' does not exist!"_s.arg( backendStr ) );
8587 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8590 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8593 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8596 if ( bboxGrow != 0 )
8598 intDomain.
grow( bboxGrow );
8601 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8607 QList<QgsFeature> features;
8608 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8612 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8613 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8617 cachedTarget = targetLayer->
materialize( request );
8618 if ( layerCanBeCached )
8619 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8629 if ( layerCanBeCached )
8630 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8637 QList<QgsFeatureId> fidsList;
8638 if ( isNearestFunc )
8640 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8644 fidsList = spatialIndex.
intersects( intDomain );
8647 QListIterator<QgsFeatureId> i( fidsList );
8648 while ( i.hasNext() )
8651 if ( sameLayers && feat.
id() == fId2 )
8653 features.append( cachedTarget->
getFeature( fId2 ) );
8660 request.setFilterRect( intDomain );
8665 if ( sameLayers && feat.
id() == feat2.
id() )
8667 features.append( feat2 );
8675 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8676 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8682 subExpression.
prepare( &subContext );
8695 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double &overlapValue ) ->
bool {
8696 bool testResult {
false };
8698 QVector<double> overlapValues;
8699 const QgsGeometry merged { intersection.mergeLines() };
8704 if ( minOverlap != -1 || requireMeasures )
8706 overlapValue = geom->
length();
8707 overlapValues.append( overlapValue );
8708 if ( minOverlap != -1 )
8710 if ( overlapValue >= minOverlap )
8722 if ( !overlapValues.isEmpty() )
8724 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8731 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double &radiusValue,
double &overlapValue ) ->
bool {
8733 bool testResult {
false };
8735 QVector<double> overlapValues;
8736 QVector<double> radiusValues;
8737 for (
auto it = intersection.const_parts_begin(); ( !testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8741 if ( minOverlap != -1 || requireMeasures )
8743 overlapValue = geom->
area();
8744 overlapValues.append( geom->
area() );
8745 if ( minOverlap != -1 )
8747 if ( overlapValue >= minOverlap )
8759 if ( minInscribedCircleRadius != -1 || requireMeasures )
8762 const double width = bbox.
width();
8763 const double height = bbox.
height();
8764 const double size = width > height ? width : height;
8765 const double tolerance = size / 100.0;
8767 testResult = radiusValue >= minInscribedCircleRadius;
8768 radiusValues.append( radiusValues );
8773 if ( !radiusValues.isEmpty() )
8775 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8778 if ( !overlapValues.isEmpty() )
8780 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8789 QVariantList results;
8791 QListIterator<QgsFeature> i( features );
8794 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8799 if ( relationFunction( geometry, feat2.
geometry(), values, backend ) )
8801 double overlapValue = -1;
8802 double radiusValue = -1;
8804 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8816 for (
const auto &geom : std::as_const( geometries ) )
8818 switch ( geom.type() )
8822 poly.append( geom.asPolygon() );
8827 line.append( geom.asPolyline() );
8832 point.append( geom.asPoint() );
8843 switch ( geometry.
type() )
8871 switch ( intersection.
type() )
8876 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8878 if ( !testResult && overlapOrRadiusFilter )
8890 if ( minInscribedCircleRadius != -1 )
8896 const bool testResult { testLinestring( intersection, overlapValue ) };
8898 if ( !testResult && overlapOrRadiusFilter )
8910 if ( minInscribedCircleRadius != -1 )
8915 bool testResult {
false };
8916 if ( minOverlap != -1 || requireMeasures )
8936 testResult = testLinestring( feat2.
geometry(), overlapValue );
8941 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8947 if ( !testResult && overlapOrRadiusFilter )
8974 const QVariant expResult = subExpression.
evaluate( &subContext );
8976 if ( requireMeasures )
8978 QVariantMap resultRecord;
8979 resultRecord.insert( u
"id"_s, feat2.
id() );
8980 resultRecord.insert( u
"result"_s, expResult );
8982 resultRecord.insert( u
"overlap"_s, overlapValue );
8984 if ( radiusValue != -1 )
8986 resultRecord.insert( u
"radius"_s, radiusValue );
8988 results.append( resultRecord );
8992 results.append( expResult );
8998 results.append( feat2.
id() );
9018 if ( requireMeasures )
9020 if ( sortByMeasure )
9022 std::sort( results.begin(), results.end(), [sortAscending](
const QVariant &recordA,
const QVariant &recordB ) ->
bool {
9023 return sortAscending ? recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
9024 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
9028 if ( limit > 0 && results.size() > limit )
9030 results.erase( results.begin() + limit );
9033 if ( !returnDetails )
9035 QVariantList expResults;
9036 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
9038 expResults.append( it->toMap().value( u
"result"_s ) );
9048 QVariantList disjoint_results;
9057 if ( !results.contains( feat2.
id() ) )
9060 disjoint_results.append( subExpression.
evaluate( &subContext ) );
9063 return disjoint_results;
9071 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
false,
true );
9077 return executeGeomOverlay( values, context, parent, geomFunction );
9083 return executeGeomOverlay( values, context, parent, geomFunction );
9091 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9099 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9107 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9113 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 10 ), parent );
9115 QVariant epsilonValue = node->
eval( parent, context );
9117 double epsilon = QgsExpressionUtils::getDoubleValue( epsilonValue, parent );
9120 return geometry.
isFuzzyEqual( other, epsilon, backend );
9122 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9128 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0.01 );
9134 return executeGeomOverlay( values, context, parent, geomFunction );
9140 return executeGeomOverlay( values, context, parent, geomFunction,
true, 0,
false,
true );
9148 return executeGeomOverlay( values, context, parent, geomFunction,
false, 0,
true );
9157 QMutexLocker locker( &sFunctionsMutex );
9159 QList<QgsExpressionFunction *> &functions = *sFunctions();
9161 if ( functions.isEmpty() )
9164 << QgsExpressionFunction::Parameter( u
"expression"_s )
9165 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
9166 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
9169 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true ) << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9172 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
9178 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnAzimuth, u
"GeometryGroup"_s )
9179 <<
new QgsStaticExpressionFunction(
9182 << QgsExpressionFunction::Parameter( u
"point1"_s )
9183 << QgsExpressionFunction::Parameter( u
"point2"_s )
9184 << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() )
9185 << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ),
9189 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnInclination, u
"GeometryGroup"_s )
9190 <<
new QgsStaticExpressionFunction(
9193 << QgsExpressionFunction::Parameter( u
"point"_s )
9194 << QgsExpressionFunction::Parameter( u
"distance"_s )
9195 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9196 << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ),
9207 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
9211 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
9212 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
9214 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction(
9216 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9221 functions << randFunc;
9223 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction(
9226 << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 )
9227 << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 )
9228 << QgsExpressionFunction::Parameter( u
"seed"_s,
true ),
9233 functions << randfFunc;
9236 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9237 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9238 <<
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 )
9239 <<
new QgsStaticExpressionFunction(
9242 << QgsExpressionFunction::Parameter( u
"value"_s )
9243 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9244 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9245 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9246 << QgsExpressionFunction::Parameter( u
"range_max"_s ),
9250 <<
new QgsStaticExpressionFunction(
9251 u
"scale_polynomial"_s,
9253 << QgsExpressionFunction::Parameter( u
"value"_s )
9254 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9255 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9256 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9257 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9258 << QgsExpressionFunction::Parameter( u
"exponent"_s ),
9265 QStringList() << u
"scale_exp"_s
9267 <<
new QgsStaticExpressionFunction(
9268 u
"scale_exponential"_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
"exponent"_s ),
9276 fcnExponentialScale,
9279 <<
new QgsStaticExpressionFunction(
9280 u
"scale_cubic_bezier"_s,
9282 << QgsExpressionFunction::Parameter( u
"value"_s )
9283 << QgsExpressionFunction::Parameter( u
"domain_min"_s )
9284 << QgsExpressionFunction::Parameter( u
"domain_max"_s )
9285 << QgsExpressionFunction::Parameter( u
"range_min"_s )
9286 << QgsExpressionFunction::Parameter( u
"range_max"_s )
9287 << QgsExpressionFunction::Parameter( u
"x1"_s )
9288 << QgsExpressionFunction::Parameter( u
"y1"_s )
9289 << QgsExpressionFunction::Parameter( u
"x2"_s )
9290 << QgsExpressionFunction::Parameter( u
"y2"_s ),
9291 fcnCubicBezierScale,
9296 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
9297 <<
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 )
9298 <<
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 )
9299 <<
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 )
9300 <<
new QgsStaticExpressionFunction(
9304 QStringList() << u
"Conversions"_s << u
"String"_s,
9309 QStringList() << u
"tostring"_s
9311 <<
new QgsStaticExpressionFunction(
9314 << QgsExpressionFunction::Parameter( u
"value"_s )
9315 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9316 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9318 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9323 QStringList() << u
"todatetime"_s
9325 <<
new QgsStaticExpressionFunction(
9328 << QgsExpressionFunction::Parameter( u
"value"_s )
9329 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9330 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9332 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9337 QStringList() << u
"todate"_s
9339 <<
new QgsStaticExpressionFunction(
9342 << QgsExpressionFunction::Parameter( u
"value"_s )
9343 << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() )
9344 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9346 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9351 QStringList() << u
"totime"_s
9353 <<
new QgsStaticExpressionFunction(
9357 QStringList() << u
"Conversions"_s << u
"Date and Time"_s,
9362 QStringList() << u
"tointerval"_s
9364 <<
new QgsStaticExpressionFunction(
9367 << QgsExpressionFunction::Parameter( u
"value"_s )
9368 << QgsExpressionFunction::Parameter( u
"axis"_s )
9369 << QgsExpressionFunction::Parameter( u
"precision"_s )
9370 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9377 QStringList() << u
"todm"_s
9379 <<
new QgsStaticExpressionFunction(
9382 << QgsExpressionFunction::Parameter( u
"value"_s )
9383 << QgsExpressionFunction::Parameter( u
"axis"_s )
9384 << QgsExpressionFunction::Parameter( u
"precision"_s )
9385 << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ),
9386 fcnToDegreeMinuteSecond,
9392 QStringList() << u
"todms"_s
9394 <<
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 )
9395 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
9396 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
9397 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter { u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
9398 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9399 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
9400 <<
new QgsStaticExpressionFunction(
9403 << QgsExpressionFunction::Parameter( u
"condition"_s )
9404 << QgsExpressionFunction::Parameter( u
"result_when_true"_s )
9405 << QgsExpressionFunction::Parameter( u
"result_when_false"_s ),
9413 <<
new QgsStaticExpressionFunction(
9424 <<
new QgsStaticExpressionFunction(
9427 << QgsExpressionFunction::Parameter( u
"layer"_s )
9428 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9429 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9430 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9431 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9432 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9442 if ( !node->
args() )
9445 QSet<QString> referencedVars;
9448 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9454 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9457 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
9465 if ( !node->
args() )
9466 return QSet<QString>();
9468 QSet<QString> referencedCols;
9469 QSet<QString> referencedVars;
9473 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
9479 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
9484 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
9487 return referencedCols;
9492 <<
new QgsStaticExpressionFunction(
9493 u
"relation_aggregate"_s,
9495 << QgsExpressionFunction::Parameter( u
"relation"_s )
9496 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9497 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9498 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9499 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9500 fcnAggregateRelation,
9508 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9509 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9510 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9511 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9512 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9513 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9514 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9515 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9516 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9517 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9518 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9519 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9520 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9521 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9522 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9523 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9524 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9525 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9526 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9527 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9528 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9530 <<
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 )
9531 <<
new QgsStaticExpressionFunction(
9532 u
"regexp_matches"_s,
9534 << QgsExpressionFunction::Parameter( u
"string"_s )
9535 << QgsExpressionFunction::Parameter( u
"regex"_s )
9536 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
9541 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9542 <<
new QgsStaticExpressionFunction( u
"age"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime1"_s ) << QgsExpressionFunction::Parameter( u
"datetime2"_s ), fcnAge, u
"Date and Time"_s )
9551 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9552 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9553 <<
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 )
9554 <<
new QgsStaticExpressionFunction(
9556 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hour"_s ) << QgsExpressionFunction::Parameter( u
"minute"_s ) << QgsExpressionFunction::Parameter( u
"second"_s ),
9560 <<
new QgsStaticExpressionFunction(
9563 << QgsExpressionFunction::Parameter( u
"year"_s )
9564 << QgsExpressionFunction::Parameter( u
"month"_s )
9565 << QgsExpressionFunction::Parameter( u
"day"_s )
9566 << QgsExpressionFunction::Parameter( u
"hour"_s )
9567 << QgsExpressionFunction::Parameter( u
"minute"_s )
9568 << QgsExpressionFunction::Parameter( u
"second"_s ),
9572 <<
new QgsStaticExpressionFunction(
9575 << QgsExpressionFunction::Parameter( u
"years"_s,
true, 0 )
9576 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9577 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9578 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9579 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9580 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9581 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9585 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9586 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9587 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9588 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9589 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9591 <<
new QgsStaticExpressionFunction(
9594 << QgsExpressionFunction::Parameter( u
"string"_s )
9595 << QgsExpressionFunction::Parameter( u
"substring"_s )
9596 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9603 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9604 <<
new QgsStaticExpressionFunction( u
"ltrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9605 <<
new QgsStaticExpressionFunction( u
"rtrim"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9606 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9607 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9608 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9612 <<
new QgsStaticExpressionFunction(
9615 << QgsExpressionFunction::Parameter( u
"text"_s )
9616 << QgsExpressionFunction::Parameter( u
"length"_s )
9617 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ),
9621 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9622 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9623 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s ) }, fcnRepeat, u
"String"_s )
9624 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9625 <<
new QgsStaticExpressionFunction(
9626 u
"regexp_replace"_s,
9627 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"replacement"_s ),
9631 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9632 <<
new QgsStaticExpressionFunction(
9634 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ),
9644 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9645 <<
new QgsStaticExpressionFunction( u
"concat_ws"_s, -1, fcnConcatWs, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9646 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9647 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9648 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9649 <<
new QgsStaticExpressionFunction(
9651 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s,
true, u
" "_s ),
9655 <<
new QgsStaticExpressionFunction(
9657 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s,
true, u
" "_s ),
9661 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9662 <<
new QgsStaticExpressionFunction(
9665 << QgsExpressionFunction::Parameter( u
"number"_s )
9666 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9667 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9668 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9669 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ),
9673 <<
new QgsStaticExpressionFunction(
9676 << QgsExpressionFunction::Parameter( u
"datetime"_s )
9677 << QgsExpressionFunction::Parameter( u
"format"_s )
9678 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ),
9680 QStringList() << u
"String"_s << u
"Date and Time"_s
9682 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9683 <<
new QgsStaticExpressionFunction(
9685 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9689 <<
new QgsStaticExpressionFunction(
9691 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color1"_s ) << QgsExpressionFunction::Parameter( u
"color2"_s ) << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9695 <<
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 )
9696 <<
new QgsStaticExpressionFunction(
9699 << QgsExpressionFunction::Parameter( u
"red"_s )
9700 << QgsExpressionFunction::Parameter( u
"green"_s )
9701 << QgsExpressionFunction::Parameter( u
"blue"_s )
9702 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9706 <<
new QgsStaticExpressionFunction(
9709 << QgsExpressionFunction::Parameter( u
"red"_s )
9710 << QgsExpressionFunction::Parameter( u
"green"_s )
9711 << QgsExpressionFunction::Parameter( u
"blue"_s )
9712 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9718 <<
new QgsStaticExpressionFunction( u
"create_ramp"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ), fcnCreateRamp, u
"Color"_s )
9719 <<
new QgsStaticExpressionFunction(
9721 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9725 <<
new QgsStaticExpressionFunction(
9728 << QgsExpressionFunction::Parameter( u
"hue"_s )
9729 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9730 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9731 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9735 <<
new QgsStaticExpressionFunction(
9738 << QgsExpressionFunction::Parameter( u
"hue"_s )
9739 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9740 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9741 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9745 <<
new QgsStaticExpressionFunction(
9747 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"hue"_s ) << QgsExpressionFunction::Parameter( u
"saturation"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9751 <<
new QgsStaticExpressionFunction(
9754 << QgsExpressionFunction::Parameter( u
"hue"_s )
9755 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9756 << QgsExpressionFunction::Parameter( u
"value"_s )
9757 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9761 <<
new QgsStaticExpressionFunction(
9764 << QgsExpressionFunction::Parameter( u
"hue"_s )
9765 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9766 << QgsExpressionFunction::Parameter( u
"value"_s )
9767 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9771 <<
new QgsStaticExpressionFunction(
9774 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9775 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9776 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9777 << QgsExpressionFunction::Parameter( u
"black"_s ),
9781 <<
new QgsStaticExpressionFunction(
9784 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9785 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9786 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9787 << QgsExpressionFunction::Parameter( u
"black"_s )
9788 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9792 <<
new QgsStaticExpressionFunction(
9795 << QgsExpressionFunction::Parameter( u
"cyan"_s )
9796 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9797 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9798 << QgsExpressionFunction::Parameter( u
"black"_s )
9799 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9803 <<
new QgsStaticExpressionFunction( u
"color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ), fncColorPart, u
"Color"_s )
9804 <<
new QgsStaticExpressionFunction( u
"darker"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncDarker, u
"Color"_s )
9805 <<
new QgsStaticExpressionFunction( u
"lighter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"factor"_s ), fncLighter, u
"Color"_s )
9806 <<
new QgsStaticExpressionFunction(
9807 u
"set_color_part"_s,
9808 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
9814 <<
new QgsStaticExpressionFunction( u
"base_file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnBaseFileName, u
"Files and Paths"_s )
9815 <<
new QgsStaticExpressionFunction( u
"file_suffix"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSuffix, u
"Files and Paths"_s )
9816 <<
new QgsStaticExpressionFunction( u
"file_exists"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileExists, u
"Files and Paths"_s )
9817 <<
new QgsStaticExpressionFunction( u
"file_name"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileName, u
"Files and Paths"_s )
9818 <<
new QgsStaticExpressionFunction( u
"is_file"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsFile, u
"Files and Paths"_s )
9819 <<
new QgsStaticExpressionFunction( u
"is_directory"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnPathIsDir, u
"Files and Paths"_s )
9820 <<
new QgsStaticExpressionFunction( u
"file_path"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFilePath, u
"Files and Paths"_s )
9821 <<
new QgsStaticExpressionFunction( u
"file_size"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnFileSize, u
"Files and Paths"_s )
9823 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ), fcnExif, u
"Files and Paths"_s )
9824 <<
new QgsStaticExpressionFunction( u
"exif_geotag"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ), fcnExifGeoTag, u
"GeometryGroup"_s )
9827 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ), fcnGenericHash, u
"Conversions"_s )
9833 <<
new QgsStaticExpressionFunction( u
"from_base64"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnFromBase64, u
"Conversions"_s )
9836 <<
new QgsStaticExpressionFunction(
9837 u
"magnetic_declination"_s,
9839 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9840 << QgsExpressionFunction::Parameter( u
"date"_s )
9841 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9842 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9843 << QgsExpressionFunction::Parameter( u
"height"_s )
9844 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9845 fcnMagneticDeclination,
9848 <<
new QgsStaticExpressionFunction(
9849 u
"magnetic_inclination"_s,
9851 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9852 << QgsExpressionFunction::Parameter( u
"date"_s )
9853 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9854 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9855 << QgsExpressionFunction::Parameter( u
"height"_s )
9856 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9857 fcnMagneticInclination,
9860 <<
new QgsStaticExpressionFunction(
9861 u
"magnetic_declination_rate_of_change"_s,
9863 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9864 << QgsExpressionFunction::Parameter( u
"date"_s )
9865 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9866 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9867 << QgsExpressionFunction::Parameter( u
"height"_s )
9868 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9869 fcnMagneticDeclinationRateOfChange,
9872 <<
new QgsStaticExpressionFunction(
9873 u
"magnetic_inclination_rate_of_change"_s,
9875 << QgsExpressionFunction::Parameter( u
"model_name"_s )
9876 << QgsExpressionFunction::Parameter( u
"date"_s )
9877 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9878 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9879 << QgsExpressionFunction::Parameter( u
"height"_s )
9880 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9881 fcnMagneticInclinationRateOfChange,
9888 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9890 functions << geomFunc;
9892 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9894 functions << areaFunc;
9896 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9898 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9900 functions << lengthFunc;
9902 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9904 functions << perimeterFunc;
9906 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9908 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnRoundness, u
"GeometryGroup"_s );
9910 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9914 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9918 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9922 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions {
9923 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9924 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9925 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9926 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9927 { u
"overlay_equals_exact"_s, fcnGeomOverlayEqualsExact },
9928 { u
"overlay_equals_topological"_s, fcnGeomOverlayEqualsTopological },
9929 { u
"overlay_equals_fuzzy"_s, fcnGeomOverlayEqualsFuzzy },
9930 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9931 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9932 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9934 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9935 while ( i.hasNext() )
9938 QString defaultBackend = i.key() ==
"overlay_equals"_L1 ? QString(
"QGIS" ) : QString(
"GEOS" );
9939 QgsStaticExpressionFunction *fcnGeomOverlayFunc =
new QgsStaticExpressionFunction(
9942 << QgsExpressionFunction::Parameter( u
"layer"_s )
9943 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9944 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9945 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9946 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9947 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9948 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9949 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9950 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false )
9951 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, defaultBackend,
false )
9952 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4,
false ),
9963 functions << fcnGeomOverlayFunc;
9966 QgsStaticExpressionFunction *fcnGeomOverlayNearestFunc =
new QgsStaticExpressionFunction(
9967 u
"overlay_nearest"_s,
9969 << QgsExpressionFunction::Parameter( u
"layer"_s )
9970 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9971 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9972 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9973 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9974 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9975 fcnGeomOverlayNearest,
9984 functions << fcnGeomOverlayNearestFunc;
9987 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9992 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9993 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9994 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9995 <<
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 )
9996 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9997 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9998 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9999 <<
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 )
10000 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
10001 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
10002 <<
new QgsStaticExpressionFunction(
10003 u
"make_triangle"_s,
10004 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ) << QgsExpressionFunction::Parameter( u
"point3"_s ),
10008 <<
new QgsStaticExpressionFunction(
10011 << QgsExpressionFunction::Parameter( u
"center"_s )
10012 << QgsExpressionFunction::Parameter( u
"radius"_s )
10013 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
10017 <<
new QgsStaticExpressionFunction(
10020 << QgsExpressionFunction::Parameter( u
"center"_s )
10021 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
10022 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
10023 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10024 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
10028 <<
new QgsStaticExpressionFunction(
10029 u
"make_regular_polygon"_s,
10031 << QgsExpressionFunction::Parameter( u
"center"_s )
10032 << QgsExpressionFunction::Parameter( u
"radius"_s )
10033 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
10034 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
10035 fcnMakeRegularPolygon,
10038 <<
new QgsStaticExpressionFunction( u
"make_square"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point1"_s ) << QgsExpressionFunction::Parameter( u
"point2"_s ), fcnMakeSquare, u
"GeometryGroup"_s )
10039 <<
new QgsStaticExpressionFunction(
10040 u
"make_rectangle_3points"_s,
10042 << QgsExpressionFunction::Parameter( u
"point1"_s )
10043 << QgsExpressionFunction::Parameter( u
"point2"_s )
10044 << QgsExpressionFunction::Parameter( u
"point3"_s )
10045 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
10046 fcnMakeRectangleFrom3Points,
10049 <<
new QgsStaticExpressionFunction(
10052 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10053#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
10054 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
10056 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
10058 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
10065 <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
10067 <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
10069 <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
10071 <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
10073 QgsStaticExpressionFunction *xAtFunc
10074 =
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 );
10076 functions << xAtFunc;
10079 QgsStaticExpressionFunction *yAtFunc
10080 =
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 );
10082 functions << yAtFunc;
10085 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
10086 <<
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 )
10087 <<
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 )
10088 <<
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 )
10089 <<
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 )
10090 <<
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 )
10091 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10092 <<
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 )
10093 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
10094 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
10095 <<
new QgsStaticExpressionFunction(
10096 u
"intersects_bbox"_s,
10099 u
"GeometryGroup"_s,
10104 QStringList() << u
"bbox"_s
10106 <<
new QgsStaticExpressionFunction( u
"disjoint"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDisjoint, u
"GeometryGroup"_s )
10107 <<
new QgsStaticExpressionFunction( u
"intersects"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersects, u
"GeometryGroup"_s )
10108 <<
new QgsStaticExpressionFunction( u
"touches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnTouches, u
"GeometryGroup"_s )
10109 <<
new QgsStaticExpressionFunction( u
"crosses"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCrosses, u
"GeometryGroup"_s )
10110 <<
new QgsStaticExpressionFunction( u
"contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnContains, u
"GeometryGroup"_s )
10111 <<
new QgsStaticExpressionFunction( u
"overlaps"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnOverlaps, u
"GeometryGroup"_s )
10112 <<
new QgsStaticExpressionFunction( u
"within"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnWithin, u
"GeometryGroup"_s )
10113 <<
new QgsStaticExpressionFunction( u
"equals"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnEquals, u
"GeometryGroup"_s )
10114 <<
new QgsStaticExpressionFunction(
10117 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10118 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10119 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s ),
10123 <<
new QgsStaticExpressionFunction(
10124 u
"equals_topological"_s,
10126 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10127 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10128 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"GEOS"_s ),
10129 fcnIsEqualsTopological,
10132 <<
new QgsStaticExpressionFunction(
10135 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10136 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10137 << QgsExpressionFunction::Parameter( u
"backend"_s,
true, u
"QGIS"_s )
10138 << QgsExpressionFunction::Parameter( u
"epsilon"_s,
true, 1e-4 ),
10142 <<
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 )
10143 <<
new QgsStaticExpressionFunction(
10146 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10147 << QgsExpressionFunction::Parameter( u
"rotation"_s )
10148 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
10149 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
10153 <<
new QgsStaticExpressionFunction(
10156 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10157 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
10158 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
10159 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
10163 <<
new QgsStaticExpressionFunction(
10164 u
"affine_transform"_s,
10166 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10167 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
10168 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
10169 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
10170 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
10171 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
10172 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
10173 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
10174 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
10175 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
10176 fcnAffineTransform,
10179 <<
new QgsStaticExpressionFunction(
10182 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10183 << QgsExpressionFunction::Parameter( u
"distance"_s )
10184 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
10185 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
10186 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
10187 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
10191 <<
new QgsStaticExpressionFunction( u
"force_rhr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForceRHR, u
"GeometryGroup"_s )
10192 <<
new QgsStaticExpressionFunction( u
"force_polygon_cw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCW, u
"GeometryGroup"_s )
10193 <<
new QgsStaticExpressionFunction( u
"force_polygon_ccw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnForcePolygonCCW, u
"GeometryGroup"_s )
10194 <<
new QgsStaticExpressionFunction(
10197 << QgsExpressionFunction::Parameter( u
"center"_s )
10198 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
10199 << QgsExpressionFunction::Parameter( u
"width"_s )
10200 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
10201 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ),
10205 <<
new QgsStaticExpressionFunction(
10206 u
"tapered_buffer"_s,
10208 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10209 << QgsExpressionFunction::Parameter( u
"start_width"_s )
10210 << QgsExpressionFunction::Parameter( u
"end_width"_s )
10211 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 ),
10215 <<
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 )
10216 <<
new QgsStaticExpressionFunction(
10219 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10220 << QgsExpressionFunction::Parameter( u
"distance"_s )
10221 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10223 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10227 <<
new QgsStaticExpressionFunction(
10228 u
"single_sided_buffer"_s,
10230 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10231 << QgsExpressionFunction::Parameter( u
"distance"_s )
10232 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
10234 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
10235 fcnSingleSidedBuffer,
10238 <<
new QgsStaticExpressionFunction(
10241 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10242 << QgsExpressionFunction::Parameter( u
"start_distance"_s )
10243 << QgsExpressionFunction::Parameter( u
"end_distance"_s )
10244 << QgsExpressionFunction::Parameter( u
"start_deflection"_s,
true, 0 )
10245 << QgsExpressionFunction::Parameter( u
"end_deflection"_s,
true, 0 ),
10249 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
10250 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
10251 <<
new QgsStaticExpressionFunction( u
"pole_of_inaccessibility"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
10252 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
10253 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
10254 <<
new QgsStaticExpressionFunction( u
"interior_ring_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnInteriorRingN, u
"GeometryGroup"_s )
10255 <<
new QgsStaticExpressionFunction( u
"geometry_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnGeometryN, u
"GeometryGroup"_s )
10256 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
10257 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
10258 <<
new QgsStaticExpressionFunction( u
"shared_paths"_s,
QgsExpressionFunction::ParameterList { QgsExpressionFunction::Parameter( u
"geometry1"_s ), QgsExpressionFunction::Parameter( u
"geometry2"_s ) }, fcnSharedPaths, u
"GeometryGroup"_s )
10260 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
10261 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
10262 <<
new QgsStaticExpressionFunction(
10265 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10266 << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
10267 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
10268 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
10269 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ),
10273 <<
new QgsStaticExpressionFunction(
10274 u
"triangular_wave"_s,
10275 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10276 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10277 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10278 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10282 <<
new QgsStaticExpressionFunction(
10283 u
"triangular_wave_randomized"_s,
10284 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10285 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10286 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10287 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10288 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10289 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10290 fcnTriangularWaveRandomized,
10293 <<
new QgsStaticExpressionFunction(
10295 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10296 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10297 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10298 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10302 <<
new QgsStaticExpressionFunction(
10303 u
"square_wave_randomized"_s,
10304 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10305 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10306 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10307 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10308 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10309 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10310 fcnSquareWaveRandomized,
10313 <<
new QgsStaticExpressionFunction(
10315 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10316 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
10317 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
10318 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false ) },
10322 <<
new QgsStaticExpressionFunction(
10323 u
"wave_randomized"_s,
10324 { QgsExpressionFunction::Parameter( u
"geometry"_s ),
10325 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
10326 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
10327 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
10328 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
10329 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 ) },
10330 fcnRoundWaveRandomized,
10333 <<
new QgsStaticExpressionFunction(
10334 u
"apply_dash_pattern"_s,
10336 QgsExpressionFunction::Parameter( u
"geometry"_s ),
10337 QgsExpressionFunction::Parameter( u
"pattern"_s ),
10338 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
10339 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
10340 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
10341 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
10343 fcnApplyDashPattern,
10346 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"vertices"_s ) }, fcnDensifyByCount, u
"GeometryGroup"_s )
10347 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s, { QgsExpressionFunction::Parameter( u
"geometry"_s ), QgsExpressionFunction::Parameter( u
"distance"_s ) }, fcnDensifyByDistance, u
"GeometryGroup"_s )
10348 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
10349 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
10350 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
10351 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
10352 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
10353 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
10354 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
10355 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
10356 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
10357 <<
new QgsStaticExpressionFunction(
10358 u
"is_empty_or_null"_s,
10361 u
"GeometryGroup"_s,
10369 <<
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 )
10370#if GEOS_VERSION_MAJOR > 3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 )
10371 <<
new QgsStaticExpressionFunction(
10374 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10375 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
10376 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ),
10381 <<
new QgsStaticExpressionFunction( u
"oriented_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnOrientedBBox, u
"GeometryGroup"_s )
10382 <<
new QgsStaticExpressionFunction( u
"main_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnMainAngle, u
"GeometryGroup"_s )
10383 <<
new QgsStaticExpressionFunction( u
"minimal_circle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ), fcnMinimalCircle, u
"GeometryGroup"_s )
10384 <<
new QgsStaticExpressionFunction( u
"difference"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDifference, u
"GeometryGroup"_s )
10385 <<
new QgsStaticExpressionFunction( u
"distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnDistance, u
"GeometryGroup"_s )
10386 <<
new QgsStaticExpressionFunction(
10387 u
"hausdorff_distance"_s,
10389 << QgsExpressionFunction::Parameter( u
"geometry1"_s )
10390 << QgsExpressionFunction::Parameter( u
"geometry2"_s )
10391 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
10392 fcnHausdorffDistance,
10395 <<
new QgsStaticExpressionFunction( u
"intersection"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnIntersection, u
"GeometryGroup"_s )
10396 <<
new QgsStaticExpressionFunction(
10397 u
"sym_difference"_s,
10400 u
"GeometryGroup"_s,
10405 QStringList() << u
"symDifference"_s
10407 <<
new QgsStaticExpressionFunction( u
"combine"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10408 <<
new QgsStaticExpressionFunction( u
"union"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnCombine, u
"GeometryGroup"_s )
10409 <<
new QgsStaticExpressionFunction(
10413 u
"GeometryGroup"_s,
10418 QStringList() << u
"geomToWKT"_s
10420 <<
new QgsStaticExpressionFunction( u
"geom_to_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
10421 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
10422 <<
new QgsStaticExpressionFunction(
10424 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"source_auth_id"_s ) << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
10425 fcnTransformGeometry,
10428 <<
new QgsStaticExpressionFunction(
10430 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"x"_s ) << QgsExpressionFunction::Parameter( u
"y"_s ),
10432 u
"GeometryGroup"_s,
10435 <<
new QgsStaticExpressionFunction( u
"is_multipart"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsMultipart, u
"GeometryGroup"_s )
10440 <<
new QgsStaticExpressionFunction( u
"sinuosity"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSinuosity, u
"GeometryGroup"_s )
10441 <<
new QgsStaticExpressionFunction( u
"straight_distance_2d"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStraightDistance2d, u
"GeometryGroup"_s );
10444 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction(
10447 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10448 << QgsExpressionFunction::Parameter( u
"orderby"_s )
10449 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
10451 u
"GeometryGroup"_s,
10456 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10457 for ( QgsExpressionNode *argNode : argList )
10459 if ( !argNode->isStatic( parent, context ) )
10465 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10467 QString expString = argNode->
eval( parent, context ).toString();
10471 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10481 QgsExpressionNode *argNode = node->
args()->
at( 1 );
10482 QString
expression = argNode->
eval( parent, context ).toString();
10484 e.prepare( context );
10489 functions << orderPartsFunc;
10492 <<
new QgsStaticExpressionFunction( u
"closest_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnClosestPoint, u
"GeometryGroup"_s )
10493 <<
new QgsStaticExpressionFunction( u
"shortest_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnShortestLine, u
"GeometryGroup"_s )
10494 <<
new QgsStaticExpressionFunction( u
"line_interpolate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
10495 <<
new QgsStaticExpressionFunction(
10496 u
"line_interpolate_point_by_m"_s,
10498 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10499 << QgsExpressionFunction::Parameter( u
"m"_s )
10500 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10501 fcnLineInterpolatePointByM,
10504 <<
new QgsStaticExpressionFunction( u
"line_interpolate_angle"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
10505 <<
new QgsStaticExpressionFunction( u
"line_locate_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
10506 <<
new QgsStaticExpressionFunction(
10507 u
"line_locate_m"_s,
10509 << QgsExpressionFunction::Parameter( u
"geometry"_s )
10510 << QgsExpressionFunction::Parameter( u
"m"_s )
10511 << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
10515 <<
new QgsStaticExpressionFunction( u
"angle_at_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
10516 <<
new QgsStaticExpressionFunction( u
"distance_to_vertex"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
10517 <<
new QgsStaticExpressionFunction(
10518 u
"line_substring"_s,
10519 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
10527 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
10529 functions << idFunc;
10531 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
10533 functions << currentFeatureFunc;
10535 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction(
10537 { QgsExpressionFunction::Parameter( u
"format"_s,
true, u
"WithBraces"_s ), QgsExpressionFunction::Parameter( u
"version"_s,
true, 4 ) },
10539 u
"Record and Attributes"_s,
10544 QStringList() << u
"$uuid"_s
10547 functions << uuidFunc;
10550 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
10551 <<
new QgsStaticExpressionFunction(
10553 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"attribute"_s ) << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
10555 u
"Record and Attributes"_s,
10560 QStringList() << u
"QgsExpressionUtils::getFeature"_s
10562 <<
new QgsStaticExpressionFunction(
10563 u
"get_feature_by_id"_s,
10566 u
"Record and Attributes"_s,
10573 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction(
10577 u
"Record and Attributes"_s,
10583 functions << attributesFunc;
10584 QgsStaticExpressionFunction *representAttributesFunc
10585 =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1, fcnRepresentAttributes, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10587 functions << representAttributesFunc;
10589 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction(
10590 u
"is_feature_valid"_s,
10592 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10593 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10594 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10595 fcnValidateFeature,
10596 u
"Record and Attributes"_s,
10602 functions << validateFeature;
10604 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction(
10605 u
"is_attribute_valid"_s,
10607 << QgsExpressionFunction::Parameter( u
"attribute"_s,
false )
10609 << QgsExpressionFunction::Parameter( u
"layer"_s,
true )
10610 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
10611 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
10612 fcnValidateAttribute,
10613 u
"Record and Attributes"_s,
10619 functions << validateAttribute;
10621 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction( u
"maptip"_s, -1, fcnFeatureMaptip, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10623 functions << maptipFunc;
10625 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction( u
"display_expression"_s, -1, fcnFeatureDisplayExpression, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10627 functions << displayFunc;
10629 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction( u
"is_selected"_s, -1, fcnIsSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10631 functions << isSelectedFunc;
10633 functions <<
new QgsStaticExpressionFunction( u
"num_selected"_s, -1, fcnNumSelected, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() );
10635 functions <<
new QgsStaticExpressionFunction(
10636 u
"sqlite_fetch_and_increment"_s,
10638 << QgsExpressionFunction::Parameter( u
"database"_s )
10639 << QgsExpressionFunction::Parameter( u
"table"_s )
10640 << QgsExpressionFunction::Parameter( u
"id_field"_s )
10641 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
10642 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
10643 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
10644 fcnSqliteFetchAndIncrement,
10645 u
"Record and Attributes"_s
10650 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
10651 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
10655 QgsStaticExpressionFunction *representValueFunc
10656 =
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 );
10659 Q_UNUSED( context )
10662 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
10669 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
10679 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
10684 functions << representValueFunc;
10688 <<
new QgsStaticExpressionFunction(
10689 u
"layer_property"_s,
10691 << QgsExpressionFunction::Parameter( u
"layer"_s )
10692 << QgsExpressionFunction::Parameter( u
"property"_s )
10693 << QgsExpressionFunction::Parameter( u
"translate"_s,
true,
true ),
10694 fcnGetLayerProperty,
10697 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"part"_s,
true ), fcnDecodeUri, u
"Map Layers"_s )
10698 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary_data"_s ), fcnMimeType, u
"General"_s )
10699 <<
new QgsStaticExpressionFunction(
10700 u
"raster_statistic"_s,
10701 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"statistic"_s ),
10702 fcnGetRasterBandStat,
10707 QgsStaticExpressionFunction *varFunction
10717 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10719 if ( !argNode->
isStatic( parent, context ) )
10722 const QString varName = argNode->
eval( parent, context ).toString();
10723 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
10727 return scope ? scope->
isStatic( varName ) :
false;
10732 if ( node && node->
args()->
count() > 0 )
10734 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10735 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
10737 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
10744 functions << varFunction;
10746 QgsStaticExpressionFunction *evalTemplateFunction
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 ) )
10766 functions << evalTemplateFunction;
10768 QgsStaticExpressionFunction *evalFunc
10773 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10775 if ( argNode->
isStatic( parent, context ) )
10777 QString expString = argNode->
eval( parent, context ).toString();
10781 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10789 functions << evalFunc;
10791 QgsStaticExpressionFunction *attributeFunc
10792 =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10794 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10795 for ( QgsExpressionNode *argNode : argList )
10797 if ( !argNode->
isStatic( parent, context ) )
10809 functions << attributeFunc;
10813 <<
new QgsWithVariableExpressionFunction()
10814 <<
new QgsStaticExpressionFunction(
10816 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10820 <<
new QgsStaticExpressionFunction(
10821 u
"raster_attributes"_s,
10822 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ),
10823 fcnRasterAttributes,
10828 <<
new QgsArrayForeachExpressionFunction()
10829 <<
new QgsArrayFilterExpressionFunction()
10830 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10831 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10832 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10833 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10834 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10835 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayAll, u
"Arrays"_s )
10836 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10837 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10843 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10844 <<
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 )
10845 <<
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 )
10847 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10848 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10849 <<
new QgsStaticExpressionFunction(
10851 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ),
10855 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10856 <<
new QgsStaticExpressionFunction(
10857 u
"array_remove_all"_s,
10868 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10869 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"priority"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10870 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10871 <<
new QgsStaticExpressionFunction(
10873 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ),
10877 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10878 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10879 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10880 <<
new QgsStaticExpressionFunction(
10881 u
"array_to_string"_s,
10883 << QgsExpressionFunction::Parameter( u
"array"_s )
10884 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10885 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10889 <<
new QgsStaticExpressionFunction(
10890 u
"string_to_array"_s,
10892 << QgsExpressionFunction::Parameter( u
"string"_s )
10893 << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," )
10894 << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ),
10898 <<
new QgsStaticExpressionFunction(
10899 u
"generate_series"_s,
10900 QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ),
10904 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10907 <<
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 )
10908 <<
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 )
10909 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10911 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10912 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10913 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10914 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10915 <<
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 )
10916 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10919 <<
new QgsStaticExpressionFunction( u
"map_prefix_keys"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"prefix"_s ), fcnMapPrefixKeys, u
"Maps"_s )
10920 <<
new QgsStaticExpressionFunction( u
"map_to_html_table"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlTable, u
"Maps"_s )
10921 <<
new QgsStaticExpressionFunction( u
"map_to_html_dl"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ), fcnMapToHtmlDefinitionList, u
"Maps"_s )
10931 *sOwnedFunctions() << func;
10932 *sBuiltinFunctions() << func->name();
10933 sBuiltinFunctions()->append( func->aliases() );
10947 QMutexLocker locker( &sFunctionsMutex );
10948 sFunctions()->append( function );
10949 if ( transferOwnership )
10950 sOwnedFunctions()->append( function );
10965 QMutexLocker locker( &sFunctionsMutex );
10966 sFunctions()->removeAt( fnIdx );
10967 sFunctionIndexMap.clear();
10975 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10976 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10978 sBuiltinFunctions()->removeAll( func->name() );
10979 for (
const QString &alias : func->aliases() )
10981 sBuiltinFunctions()->removeAll( alias );
10984 sFunctions()->removeAll( func );
10987 qDeleteAll( *sOwnedFunctions() );
10988 sOwnedFunctions()->clear();
10993 if ( sBuiltinFunctions()->isEmpty() )
10997 return *sBuiltinFunctions();
11002 u
"array_foreach"_s,
11012 QgsExpressionNode::NodeList *args = node->
args();
11014 if ( args->
count() < 2 )
11017 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11027 QVariantList result;
11029 if ( args->
count() < 2 )
11033 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11035 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11036 std::unique_ptr< QgsExpressionContext > tempContext;
11039 tempContext = std::make_unique< QgsExpressionContext >();
11040 subContext = tempContext.get();
11043 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11047 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
11051 result << args->
at( 1 )->
eval( parent, subContext );
11064 Q_UNUSED( context )
11076 if ( args->
count() < 2 )
11080 args->
at( 0 )->
prepare( parent, context );
11084 subContext = *context;
11091 args->
at( 1 )->
prepare( parent, &subContext );
11104 QgsExpressionNode::NodeList *args = node->
args();
11106 if ( args->
count() < 2 )
11109 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11119 QVariantList result;
11121 if ( args->
count() < 2 )
11125 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
11127 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
11128 std::unique_ptr< QgsExpressionContext > tempContext;
11131 tempContext = std::make_unique< QgsExpressionContext >();
11132 subContext = tempContext.get();
11135 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
11139 if ( args->
count() >= 3 )
11141 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
11143 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
11145 limit = limitVar.toInt();
11153 for (
const QVariant &value : array )
11155 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
11156 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
11160 if ( limit > 0 && limit == result.size() )
11175 Q_UNUSED( context )
11187 if ( args->
count() < 2 )
11191 args->
at( 0 )->
prepare( parent, context );
11195 subContext = *context;
11201 args->
at( 1 )->
prepare( parent, &subContext );
11213 QgsExpressionNode::NodeList *args = node->
args();
11215 if ( args->
count() < 3 )
11219 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
11221 QVariant
name = args->
at( 0 )->
eval( parent, context );
11222 QVariant value = args->
at( 1 )->
eval( parent, context );
11225 appendTemporaryVariable( context,
name.toString(), value );
11226 if ( args->
at( 2 )->
isStatic( parent, context ) )
11228 popTemporaryVariable( context );
11239 if ( args->
count() < 3 )
11243 QVariant
name = args->
at( 0 )->
eval( parent, context );
11244 QVariant value = args->
at( 1 )->
eval( parent, context );
11246 const QgsExpressionContext *updatedContext = context;
11247 std::unique_ptr< QgsExpressionContext > tempContext;
11248 if ( !updatedContext )
11250 tempContext = std::make_unique< QgsExpressionContext >();
11251 updatedContext = tempContext.get();
11254 appendTemporaryVariable( updatedContext,
name.toString(), value );
11255 result = args->
at( 2 )->
eval( parent, updatedContext );
11258 popTemporaryVariable( updatedContext );
11267 Q_UNUSED( context )
11279 if ( args->
count() < 3 )
11284 QVariant value = args->
at( 1 )->
prepare( parent, context );
11287 std::unique_ptr< QgsExpressionContext > tempContext;
11288 if ( !updatedContext )
11290 tempContext = std::make_unique< QgsExpressionContext >();
11291 updatedContext = tempContext.get();
11294 appendTemporaryVariable( updatedContext,
name.toString(), value );
11295 args->
at( 2 )->
prepare( parent, updatedContext );
11298 popTemporaryVariable( updatedContext );
11303void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
11305 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
11306 delete updatedContext->
popScope();
11309void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
11311 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
11312 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
11314 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.