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 );
181 const QString &group,
182 const QString &helpText,
186 const QStringList &aliases,
190 , mAliases( aliases )
191 , mUsesGeometry( false )
192 , mUsesGeometryFunc( usesGeometry )
193 , mReferencedColumnsFunc( referencedColumns )
205 if ( mUsesGeometryFunc )
206 return mUsesGeometryFunc( node );
208 return mUsesGeometry;
218 if ( mReferencedColumnsFunc )
219 return mReferencedColumnsFunc( node );
221 return mReferencedColumns;
227 return mIsStaticFunc( node, parent, context );
235 return mPrepareFunc( node, parent, context );
247 mIsStaticFunc =
nullptr;
253 mPrepareFunc = prepareFunc;
258 if ( node && node->
args() )
260 const QList< QgsExpressionNode * > argList = node->
args()->
list();
263 if ( !argNode->isStatic( parent, context ) )
273 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
274 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
275 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
277 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
284 double current = start + step;
285 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
300 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
302 if ( name ==
"feature"_L1 )
304 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
306 else if ( name ==
"id"_L1 )
308 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
310 else if ( name ==
"geometry"_L1 )
326 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
335 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
337 return expression.evaluate( context );
342 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::sqrt( x ) );
348 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return QVariant( std::fabs( val ) );
354 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
355 return ( deg * M_PI ) / 180;
359 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
360 return ( 180 * rad ) / M_PI;
364 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
365 return QVariant( std::sin( x ) );
369 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
370 return QVariant( std::cos( x ) );
374 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
375 return QVariant( std::tan( x ) );
379 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
380 return QVariant( std::asin( x ) );
384 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
385 return QVariant( std::acos( x ) );
389 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
390 return QVariant( std::atan( x ) );
394 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
395 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
396 return QVariant( std::atan2( y, x ) );
400 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
401 return QVariant( std::exp( x ) );
405 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
408 return QVariant( std::log( x ) );
412 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
415 return QVariant( log10( x ) );
419 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
420 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
421 if ( x <= 0 || b <= 0 )
423 return QVariant( std::log( x ) / std::log( b ) );
427 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
428 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
432 std::random_device rd;
433 std::mt19937_64 generator( rd() );
435 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
438 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
441 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
446 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
447 std::hash<std::string> hasher;
448 seed = hasher( seedStr.toStdString() );
450 generator.seed( seed );
454 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
455 return QVariant( min + f * ( max - min ) );
459 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
460 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
464 std::random_device rd;
465 std::mt19937_64 generator( rd() );
467 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
470 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
473 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
478 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
479 std::hash<std::string> hasher;
480 seed = hasher( seedStr.toStdString() );
482 generator.seed( seed );
485 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
486 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
487 return QVariant( randomInteger );
490 return QVariant(
int( randomInteger ) );
495 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
496 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
497 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
498 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
499 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
501 if ( domainMin >= domainMax )
503 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
508 if ( val >= domainMax )
512 else if ( val <= domainMin )
518 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
519 double c = rangeMin - ( domainMin * m );
522 return QVariant( m * val +
c );
527 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
528 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
529 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
530 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
531 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
532 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
534 if ( domainMin >= domainMax )
536 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
546 if ( val >= domainMax )
550 else if ( val <= domainMin )
556 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
561 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
562 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
563 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
564 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
565 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
566 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
568 if ( domainMin >= domainMax )
570 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
580 if ( val >= domainMax )
584 else if ( val <= domainMin )
590 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
591 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
597 double maxVal = std::numeric_limits<double>::quiet_NaN();
598 for (
const QVariant &val : values )
601 if ( std::isnan( maxVal ) )
605 else if ( !std::isnan( testVal ) )
607 maxVal = std::max( maxVal, testVal );
611 if ( !std::isnan( maxVal ) )
613 result = QVariant( maxVal );
621 double minVal = std::numeric_limits<double>::quiet_NaN();
622 for (
const QVariant &val : values )
625 if ( std::isnan( minVal ) )
629 else if ( !std::isnan( testVal ) )
631 minVal = std::min( minVal, testVal );
635 if ( !std::isnan( minVal ) )
637 result = QVariant( minVal );
649 QVariant value = node->
eval( parent, context );
654 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
658 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
663 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
665 value = node->
eval( parent, context );
671 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
676 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
678 QString subExpression = node->
dump();
682 if ( values.count() > 3 )
684 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
687 if ( !nl || nl->value().isValid() )
692 if ( values.count() > 4 )
694 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
696 value = node->
eval( parent, context );
703 if ( values.count() > 5 )
705 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
708 if ( !nl || nl->value().isValid() )
710 orderBy = node->
dump();
715 QString aggregateError;
723 const QSet< QString > filterVars = filterExp.referencedVariables();
724 const QSet< QString > subExpVars = subExp.referencedVariables();
725 QSet<QString> allVars = filterVars + subExpVars;
727 bool isStatic =
true;
728 if ( filterVars.contains( u
"parent"_s )
729 || filterVars.contains( QString() )
730 || subExpVars.contains( u
"parent"_s )
731 || subExpVars.contains( QString() ) )
737 for (
const QString &varName : allVars )
740 if ( scope && !scope->
isStatic( varName ) )
748 if ( isStatic && ! parameters.
orderBy.isEmpty() )
750 for (
const auto &orderByClause : std::as_const( parameters.
orderBy ) )
752 const QgsExpression &orderByExpression { orderByClause.expression() };
764 const QString contextHash = context->
uniqueHash( ok, allVars );
767 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
768 orderBy, contextHash );
773 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
784 subContext.appendScope( subScope );
785 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
797 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
801 if ( !aggregateError.isEmpty() )
802 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
804 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
815 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
823 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
827 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
836 QVariant value = node->
eval( parent, context );
838 QString relationId = value.toString();
845 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
847 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
852 relation = relations.at( 0 );
859 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
861 value = node->
eval( parent, context );
867 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
872 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
874 QString subExpression = node->
dump();
878 if ( values.count() > 3 )
880 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
882 value = node->
eval( parent, context );
889 if ( values.count() > 4 )
891 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
894 if ( !nl || nl->value().isValid() )
896 orderBy = node->
dump();
907 const QString
cacheKey = u
"relagg:%1%:%2:%3:%4:%5:%6"_s.arg( relationId, vl->id(),
908 QString::number(
static_cast< int >( aggregate ) ),
921 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
925 if ( !error.isEmpty() )
926 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
928 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
942 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
950 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
954 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
963 QString subExpression = node->
dump();
967 if ( values.count() > 1 )
969 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
972 if ( !nl || nl->value().isValid() )
973 groupBy = node->
dump();
977 if ( values.count() > 2 )
979 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
982 if ( !nl || nl->value().isValid() )
988 if ( orderByPos >= 0 && values.count() > orderByPos )
990 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
993 if ( !nl || nl->value().isValid() )
995 orderBy = node->
dump();
1003 if ( !groupBy.isEmpty() )
1006 QVariant groupByValue = groupByExp.evaluate( context );
1007 QString groupByClause = u
"%1 %2 %3"_s.arg( groupBy,
1010 if ( !parameters.
filter.isEmpty() )
1011 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1013 parameters.
filter = groupByClause;
1019 bool isStatic =
true;
1020 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1021 for (
const QString &varName : refVars )
1024 if ( scope && !scope->
isStatic( varName ) )
1035 const QString contextHash = context->
uniqueHash( ok, refVars );
1038 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
1039 orderBy, contextHash );
1044 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1056 subContext.appendScope( subScope );
1058 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1062 if ( !error.isEmpty() )
1063 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1065 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1170 if ( values.count() > 3 )
1172 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1174 QVariant value = node->
eval( parent, context );
1176 parameters.
delimiter = value.toString();
1187 if ( values.count() > 3 )
1189 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1191 QVariant value = node->
eval( parent, context );
1193 parameters.
delimiter = value.toString();
1209 QVariant scale = context->
variable( u
"map_scale"_s );
1214 const double v = scale.toDouble( &ok );
1222 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1223 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1224 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1227 if ( testValue <= minValue )
1229 return QVariant( minValue );
1231 else if ( testValue >= maxValue )
1233 return QVariant( maxValue );
1237 return QVariant( testValue );
1243 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1244 return QVariant( std::floor( x ) );
1249 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1250 return QVariant( std::ceil( x ) );
1255 const QVariant value = values.at( 0 );
1256 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1258 return QVariant(
false );
1260 else if ( value.userType() == QMetaType::QString )
1263 return QVariant( !value.toString().isEmpty() );
1265 else if ( QgsExpressionUtils::isList( value ) )
1267 return !value.toList().isEmpty();
1269 return QVariant( value.toBool() );
1273 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1277 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1281 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1286 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1287 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1288 if ( format.isEmpty() && !language.isEmpty() )
1290 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1291 return QVariant( QDateTime() );
1294 if ( format.isEmpty() && language.isEmpty() )
1295 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1297 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1298 QLocale locale = QLocale();
1299 if ( !language.isEmpty() )
1301 locale = QLocale( language );
1304 QDateTime datetime = locale.toDateTime( datetimestring, format );
1305 if ( !datetime.isValid() )
1307 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1308 datetime = QDateTime();
1310 return QVariant( datetime );
1315 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1316 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1317 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1319 const QDate date( year, month, day );
1320 if ( !date.isValid() )
1322 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1325 return QVariant( date );
1330 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1331 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1332 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1334 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1335 if ( !time.isValid() )
1337 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1340 return QVariant( time );
1345 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1346 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1347 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1348 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1349 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1350 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1352 const QDate date( year, month, day );
1353 if ( !date.isValid() )
1355 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1358 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1359 if ( !time.isValid() )
1361 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1364 return QVariant( QDateTime( date, time ) );
1369 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1373#if QT_FEATURE_timezone > 0
1374 if ( !timeZoneId.isEmpty() )
1376 tz = QTimeZone( timeZoneId.toUtf8() );
1379 if ( !tz.isValid() )
1381 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1386 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1388 return QVariant::fromValue( tz );
1393#if QT_FEATURE_timezone > 0
1394 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1395 if ( datetime.isValid() )
1397 return QVariant::fromValue( datetime.timeZone() );
1401 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1408#if QT_FEATURE_timezone > 0
1409 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1410 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1411 if ( datetime.isValid() && tz.isValid() )
1413 datetime.setTimeZone( tz );
1414 return QVariant::fromValue( datetime );
1418 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1425#if QT_FEATURE_timezone > 0
1426 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1427 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1428 if ( datetime.isValid() && tz.isValid() )
1430 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1434 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1441#if QT_FEATURE_timezone > 0
1442 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1443 if ( timeZone.isValid() )
1445 return QString( timeZone.id() );
1449 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1456 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1457 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1458 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1459 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1460 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1461 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1462 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1464 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1469 for (
const QVariant &value : values )
1480 const QVariant val1 = values.at( 0 );
1481 const QVariant val2 = values.at( 1 );
1491 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1492 return QVariant( str.toLower() );
1496 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1497 return QVariant( str.toUpper() );
1501 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1502 QStringList elems = str.split(
' ' );
1503 for (
int i = 0; i < elems.size(); i++ )
1505 if ( elems[i].size() > 1 )
1506 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1508 return QVariant( elems.join(
' '_L1 ) );
1513 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1514 return QVariant( str.trimmed() );
1519 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1521 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1523 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1524 str.replace( re, QString() );
1525 return QVariant( str );
1530 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1532 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1534 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1535 str.replace( re, QString() );
1536 return QVariant( str );
1541 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1542 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1548 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1549 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1555 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1556 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1563 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1569 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1570 return QVariant( QString( character ) );
1575 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1577 if ( value.isEmpty() )
1582 int res = value.at( 0 ).unicode();
1583 return QVariant( res );
1588 if ( values.length() == 2 || values.length() == 3 )
1590 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1591 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1593 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1606 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1610 return QVariant( geom.
length() );
1616 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1617 return QVariant( str.length() );
1622 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1627 double totalLength = 0;
1632 totalLength += line->length3D();
1637 totalLength += segmentized->length3D();
1647 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1648 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1649 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1654 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1656 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1657 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1658 QVector< QPair< QString, QString > > mapItems;
1660 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1662 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1666 std::sort( mapItems.begin(),
1668 [](
const QPair< QString, QString > &pair1,
1669 const QPair< QString, QString > &pair2 )
1671 return ( pair1.first.length() > pair2.first.length() );
1674 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1676 str = str.replace( it->first, it->second );
1679 return QVariant( str );
1681 else if ( values.count() == 3 )
1683 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1684 QVariantList before;
1686 bool isSingleReplacement =
false;
1688 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1690 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1694 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1697 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1699 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1700 isSingleReplacement =
true;
1704 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1707 if ( !isSingleReplacement && before.length() != after.length() )
1709 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1713 for (
int i = 0; i < before.length(); i++ )
1715 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1718 return QVariant( str );
1722 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1729 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1730 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1731 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1733 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1734 if ( !re.isValid() )
1736 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1739 return QVariant( str.replace( re, after ) );
1744 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1745 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1747 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1748 if ( !re.isValid() )
1750 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1753 return QVariant( ( str.indexOf( re ) + 1 ) );
1758 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1759 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1760 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1762 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1763 if ( !re.isValid() )
1765 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1769 QRegularExpressionMatch matches = re.match( str );
1770 if ( matches.hasMatch() )
1773 QStringList list = matches.capturedTexts();
1776 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1778 array += ( !( *it ).isEmpty() ) ? *it : empty;
1781 return QVariant( array );
1791 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1792 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1794 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1795 if ( !re.isValid() )
1797 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1802 QRegularExpressionMatch match = re.match( str );
1803 if ( match.hasMatch() )
1806 if ( match.lastCapturedIndex() > 0 )
1809 return QVariant( match.captured( 1 ) );
1814 return QVariant( match.captured( 0 ) );
1819 return QVariant(
"" );
1825 QString uuid = QUuid::createUuid().toString();
1826 if ( values.at( 0 ).toString().compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1827 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1828 else if ( values.at( 0 ).toString().compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1829 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1835 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1838 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1839 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1842 if ( values.at( 2 ).isValid() )
1843 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1849 from = str.size() + from;
1855 else if ( from > 0 )
1863 len = str.size() + len - from;
1870 return QVariant( str.mid( from, len ) );
1875 return QVariant( f.
id() );
1880 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1881 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1882 bool foundLayer =
false;
1883 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1885 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1886 if ( !layer || !layer->dataProvider() )
1888 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1892 if ( bandNb < 1 || bandNb > layer->bandCount() )
1894 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1900 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1907 QgsMultiPointXY multiPoint = geom.asMultiPoint();
1908 if ( multiPoint.count() == 1 )
1910 point = multiPoint[0];
1919 double value = layer->dataProvider()->sample( point, bandNb );
1920 return std::isnan( value ) ? QVariant() : value;
1926 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1937 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1938 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1940 bool foundLayer =
false;
1941 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1943 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1944 if ( !layer || !layer->dataProvider() )
1946 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1950 if ( bandNb < 1 || bandNb > layer->bandCount() )
1952 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1956 if ( std::isnan( value ) )
1958 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1962 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1967 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1968 if ( data.isEmpty() )
1974 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1975 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1982 result.insert( fields.at( idx ).name, data.at( idx ) );
1990 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2011 if ( values.size() == 1 )
2013 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2016 else if ( values.size() == 2 )
2018 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2019 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2023 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2032 QString table { R
"html(
2035 <tr><th>%1</th></tr>
2038 <tr><td>%2</td></tr>
2042 if ( values.size() == 1 )
2044 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2048 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2052 if ( dict.isEmpty() )
2057 QStringList headers;
2060 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2062 headers.push_back( it.key().toHtmlEscaped() );
2063 cells.push_back( it.value().toString( ).toHtmlEscaped() );
2066 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2071 QString table { R
"html(
2076 if ( values.size() == 1 )
2078 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2082 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2086 if ( dict.isEmpty() )
2093 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2095 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2098 return table.arg( rows );
2106 layer = context->
variable( u
"layer"_s );
2111 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2113 layer = node->
eval( parent, context );
2124 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2128 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2129 if ( strength ==
"hard"_L1 )
2133 else if ( strength ==
"soft"_L1 )
2138 bool foundLayer =
false;
2139 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2141 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2144 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2150 for (
int i = 0; i < fields.
size(); i++ )
2165 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2177 layer = context->
variable( u
"layer"_s );
2182 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2184 layer = node->
eval( parent, context );
2195 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2199 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2200 if ( strength ==
"hard"_L1 )
2204 else if ( strength ==
"soft"_L1 )
2209 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2211 bool foundLayer =
false;
2212 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2214 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2221 if ( fieldIndex == -1 )
2223 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2234 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2250 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2255 for (
int i = 0; i < fields.
count(); ++i )
2269 if ( values.isEmpty() )
2272 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2274 else if ( values.size() == 1 )
2276 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2277 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2279 else if ( values.size() == 2 )
2281 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2282 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2286 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2293 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2299 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2305 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2307 const QString fieldName { fields.
at( fieldIndex ).
name() };
2308 const QVariant attributeVal = feature.
attribute( fieldIndex );
2309 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2312 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2321 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2333 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2335 result.insert( fields.
at( fieldIndex ).
name(), value );
2351 bool evaluate =
true;
2355 if ( values.isEmpty() )
2358 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2360 else if ( values.size() == 1 )
2362 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2363 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2365 else if ( values.size() == 2 )
2367 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2368 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2370 else if ( values.size() == 3 )
2372 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2373 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2374 evaluate = values.value( 2 ).toBool();
2380 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2384 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2416 subContext.setFeature( feature );
2425 exp.prepare( &subContext );
2426 return exp.evaluate( &subContext ).toString();
2432 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2437 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2444 if ( values.isEmpty() )
2447 layer = context->
variable( u
"layer"_s );
2449 else if ( values.size() == 1 )
2451 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2452 layer = context->
variable( u
"layer"_s );
2454 else if ( values.size() == 2 )
2456 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2457 layer = values.at( 0 );
2461 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2465 bool foundLayer =
false;
2466 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2468 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2469 if ( !layer || !feature.
isValid() )
2486 if ( values.isEmpty() )
2487 layer = context->
variable( u
"layer"_s );
2488 else if ( values.count() == 1 )
2489 layer = values.at( 0 );
2492 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2496 bool foundLayer =
false;
2497 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2499 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2515 static QMap<QString, qlonglong> counterCache;
2516 QVariant functionResult;
2518 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2522 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2527 database = decodedUri.value( u
"path"_s ).toString();
2528 if ( database.isEmpty() )
2530 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2535 database = databaseArgument;
2538 const QString table = values.at( 1 ).toString();
2539 const QString idColumn = values.at( 2 ).toString();
2540 const QString filterAttribute = values.at( 3 ).toString();
2541 const QVariant filterValue = values.at( 4 ).toString();
2542 const QVariantMap defaultValues = values.at( 5 ).toMap();
2548 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2551 functionResult = QVariant();
2555 QString errorMessage;
2556 QString currentValSql;
2558 qlonglong nextId = 0;
2559 bool cachedMode =
false;
2560 bool valueRetrieved =
false;
2562 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2569 auto cachedCounter = counterCache.find( cacheString );
2571 if ( cachedCounter != counterCache.end() )
2573 qlonglong &cachedValue = cachedCounter.value();
2574 nextId = cachedValue;
2576 cachedValue = nextId;
2577 valueRetrieved =
true;
2582 if ( !cachedMode || !valueRetrieved )
2584 int result = SQLITE_ERROR;
2587 if ( !filterAttribute.isNull() )
2592 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2594 if ( result == SQLITE_OK )
2597 if ( sqliteStatement.
step() == SQLITE_ROW )
2603 if ( cachedMode && result == SQLITE_OK )
2605 counterCache.insert( cacheString, nextId );
2609 counterCache.remove( cacheString );
2612 valueRetrieved =
true;
2616 if ( valueRetrieved )
2625 if ( !filterAttribute.isNull() )
2631 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2634 vals << iter.value().toString();
2637 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2638 upsertSql +=
" VALUES "_L1;
2639 upsertSql +=
'(' + vals.join(
',' ) +
')';
2641 int result = SQLITE_ERROR;
2645 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2652 result = sqliteDb.
exec( upsertSql, errorMessage );
2654 if ( result == SQLITE_OK )
2656 functionResult = QVariant( nextId );
2661 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2662 functionResult = QVariant();
2667 functionResult = QVariant();
2670 bool foundLayer =
false;
2671 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2673 fetchAndIncrementFunc( layer, QString() );
2677 const QString databasePath = values.at( 0 ).toString();
2680 fetchAndIncrementFunc(
nullptr, databasePath );
2684 return functionResult;
2697 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2702 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2705 return QVariant::fromValue( crs );
2711 for (
const QVariant &value : values )
2714 concat += QgsExpressionUtils::getStringValue( value, parent );
2721 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2722 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2725static QVariant fcnUnaccent(
2726 const QVariantList &values,
2735 if ( values.isEmpty() || values[0].isNull() )
2744 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2745 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2746 return string.right( pos );
2751 if ( values.length() < 2 || values.length() > 3 )
2754 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2755 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2757 bool overlapping =
false;
2758 if ( values.length() == 3 )
2760 overlapping = values.at( 2 ).toBool();
2763 if ( substring.isEmpty() )
2764 return QVariant( 0 );
2769 count = input.count( substring );
2774 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2777 pos += substring.length();
2781 return QVariant( count );
2786 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2787 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2788 return string.left( pos );
2793 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2794 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2795 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2796 return string.leftJustified( length, fill.at( 0 ),
true );
2801 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2802 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2803 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2804 return string.rightJustified( length, fill.at( 0 ),
true );
2809 if ( values.size() < 1 )
2811 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2815 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2816 for (
int n = 1; n < values.length(); n++ )
2818 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2826 return QVariant( QDateTime::currentDateTime() );
2831 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2832 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2833 if ( format.isEmpty() && !language.isEmpty() )
2835 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2836 return QVariant( QDate() );
2839 if ( format.isEmpty() && language.isEmpty() )
2840 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2842 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2843 QLocale locale = QLocale();
2844 if ( !language.isEmpty() )
2846 locale = QLocale( language );
2849 QDate date = locale.toDate( datestring, format );
2850 if ( !date.isValid() )
2852 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2855 return QVariant( date );
2860 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2861 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2862 if ( format.isEmpty() && !language.isEmpty() )
2864 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2865 return QVariant( QTime() );
2868 if ( format.isEmpty() && language.isEmpty() )
2869 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2871 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2872 QLocale locale = QLocale();
2873 if ( !language.isEmpty() )
2875 locale = QLocale( language );
2878 QTime time = locale.toTime( timestring, format );
2879 if ( !time.isValid() )
2881 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2884 return QVariant( time );
2889 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2898 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2899 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2900 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2902 QString formatString;
2903 if ( values.count() > 3 )
2904 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2907 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
2911 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
2915 else if ( ! formatString.isEmpty() )
2917 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2921 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
2925 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
2931 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2939 return floatToDegreeFormat( format, values, context, parent, node );
2946 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2948 return ok ? QVariant( value ) : QVariant();
2954 return floatToDegreeFormat( format, values, context, parent, node );
2959 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2960 return static_cast< int >( decimalDegrees );
2965 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
2966 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
2967 return static_cast< int >( remainder * 60 );
2972 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
2973 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
2974 const double remainderInMinutes = remainder * 60;
2975 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
2977 return remainderSecondsFraction * 60;
2982 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2983 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2984 qint64 seconds = d2.secsTo( d1 );
2985 return QVariant::fromValue(
QgsInterval( seconds ) );
2990 if ( !values.at( 0 ).canConvert<QDate>() )
2993 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2994 if ( !date.isValid() )
2999 return date.dayOfWeek() % 7;
3004 QVariant value = values.at( 0 );
3005 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3008 return QVariant( inter.
days() );
3012 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3013 return QVariant( d1.date().day() );
3019 QVariant value = values.at( 0 );
3020 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3023 return QVariant( inter.
years() );
3027 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3028 return QVariant( d1.date().year() );
3034 QVariant value = values.at( 0 );
3035 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3038 return QVariant( inter.
months() );
3042 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3043 return QVariant( d1.date().month() );
3049 QVariant value = values.at( 0 );
3050 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3053 return QVariant( inter.
weeks() );
3057 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3058 return QVariant( d1.date().weekNumber() );
3064 QVariant value = values.at( 0 );
3065 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3068 return QVariant( inter.
hours() );
3072 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3073 return QVariant( t1.hour() );
3079 QVariant value = values.at( 0 );
3080 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3083 return QVariant( inter.
minutes() );
3087 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3088 return QVariant( t1.minute() );
3094 QVariant value = values.at( 0 );
3095 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3098 return QVariant( inter.
seconds() );
3102 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3103 return QVariant( t1.second() );
3109 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3112 return QVariant( dt.toMSecsSinceEpoch() );
3122 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3124 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3129 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3132 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3135 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3141 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3144 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3153 if ( !dateTime.isValid() )
3158 const int year = dateTime.date().year();
3159 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3160 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3161 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3162 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3163 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3168 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3169 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3172 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3175 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3180 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3185 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3190 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3195 double declination = 0;
3202 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3214 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3215 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3218 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3221 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3226 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3231 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3236 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3241 double inclination = 0;
3248 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3260 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3261 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3264 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3267 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3272 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3277 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3282 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3287 double declination = 0;
3295 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3305 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3311 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3317 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3322 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3329 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3330 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3333 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3336 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3341 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3346 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3351 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3356 double declination = 0;
3364 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3374 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3380 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3386 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3391 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3396#define ENSURE_GEOM_TYPE(f, g, geomtype) \
3397 if ( !(f).hasGeometry() ) \
3398 return QVariant(); \
3399 QgsGeometry g = (f).geometry(); \
3400 if ( (g).type() != (geomtype) ) \
3407 if ( g.isMultipart() )
3409 return g.asMultiPoint().at( 0 ).x();
3413 return g.asPoint().x();
3421 if ( g.isMultipart() )
3423 return g.asMultiPoint().at( 0 ).y();
3427 return g.asPoint().y();
3441 if ( g.isEmpty() || !abGeom->
is3D() )
3454 if ( collection->numGeometries() > 0 )
3467 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3473 return QVariant( isValid );
3478 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3482 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3483#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
3488 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3490 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3493 const bool keepCollapsed = values.value( 2 ).toBool();
3498 valid = geom.
makeValid( method, keepCollapsed );
3502 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3506 return QVariant::fromValue( valid );
3511 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3517 for (
int i = 0; i < multiGeom.size(); ++i )
3519 array += QVariant::fromValue( multiGeom.at( i ) );
3527 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3539 QVariant result( centroid.
asPoint().
x() );
3545 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3557 QVariant result( centroid.
asPoint().
y() );
3563 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3581 if ( collection->numGeometries() == 1 )
3594 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3612 if ( collection->numGeometries() == 1 )
3625 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3630 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3657 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3674 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3691 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3696 bool ignoreClosing =
false;
3697 if ( values.length() > 1 )
3699 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3709 bool skipLast =
false;
3710 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3715 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3727 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3738 for (
int i = 0; i < line->numPoints() - 1; ++i )
3742 << line->pointN( i )
3743 << line->pointN( i + 1 ) );
3754 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3764 if ( collection->numGeometries() == 1 )
3771 if ( !curvePolygon )
3775 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3781 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3787 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3797 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3803 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3809 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3818 return QVariant::fromValue(
QgsGeometry( boundary ) );
3823 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3832 return QVariant::fromValue( merged );
3837 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3841 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3846 if ( sharedPaths.
isNull() )
3849 return QVariant::fromValue( sharedPaths );
3855 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3860 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3863 if ( simplified.
isNull() )
3871 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3876 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3881 if ( simplified.
isNull() )
3889 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3894 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3895 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3896 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3897 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3899 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3908 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3913 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3914 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3915 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3926 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3931 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3932 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3933 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3934 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3935 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3938 minAmplitude, maxAmplitude, seed );
3947 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3952 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3953 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3954 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3965 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3970 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3971 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3972 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3973 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3974 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3977 minAmplitude, maxAmplitude, seed );
3986 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3991 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3992 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3993 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4004 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4009 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4010 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4011 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4012 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4013 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4016 minAmplitude, maxAmplitude, seed );
4025 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4030 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4031 QVector< double > dashPattern;
4032 dashPattern.reserve( pattern.size() );
4033 for (
const QVariant &value : std::as_const( pattern ) )
4036 double v = value.toDouble( &ok );
4048 if ( dashPattern.size() % 2 != 0 )
4050 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4054 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4056 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4058 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4060 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4062 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4064 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4068 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4072 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4074 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4076 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4078 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4080 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4082 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4086 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4090 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4092 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4094 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4096 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4100 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4104 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4115 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4120 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4122 if ( densified.
isNull() )
4130 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4135 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4137 if ( densified.
isNull() )
4146 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4148 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4155 QVector< QgsGeometry > parts;
4156 parts.reserve( list.size() );
4157 for (
const QVariant &value : std::as_const( list ) )
4159 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4170 if ( values.count() < 2 || values.count() > 4 )
4172 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4176 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4177 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4178 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4179 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4180 switch ( values.count() )
4194 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4195 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4196 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4202 if ( values.empty() )
4207 QVector<QgsPoint> points;
4208 points.reserve( values.count() );
4210 auto addPoint = [&points](
const QgsGeometry & geom )
4225 for (
const QVariant &value : values )
4227 if ( value.userType() == QMetaType::Type::QVariantList )
4229 const QVariantList list = value.toList();
4230 for (
const QVariant &v : list )
4232 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4237 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4241 if ( points.count() < 2 )
4249 if ( values.count() < 1 )
4251 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4255 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4263 auto polygon = std::make_unique< QgsPolygon >();
4277 if ( !exteriorRing )
4280 polygon->setExteriorRing( exteriorRing->
segmentize() );
4283 for (
int i = 1; i < values.count(); ++i )
4285 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4307 polygon->addInteriorRing( ring->
segmentize() );
4310 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4315 auto tr = std::make_unique<QgsTriangle>();
4316 auto lineString = std::make_unique<QgsLineString>();
4317 lineString->clear();
4319 for (
const QVariant &value : values )
4321 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4343 lineString->addVertex( *point );
4346 tr->setExteriorRing( lineString.release() );
4348 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4353 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4360 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4361 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4383 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4388 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4395 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4396 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4397 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4398 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4418 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4419 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4425 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4432 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4439 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4442 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4449 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4489 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4495 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4510 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4516 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4522 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4531 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4555 return QVariant::fromValue( geom.
vertexAt( idx ) );
4563 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4565 const QVariant v = pointAt( geom, idx, parent );
4568 return QVariant( v.value<
QgsPoint>().
x() );
4574 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4576 return fcnOldXat( values, f, parent, node );
4578 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4580 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4583 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4589 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4591 const QVariant v = pointAt( geom, vertexNumber, parent );
4593 return QVariant( v.value<
QgsPoint>().
x() );
4603 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4605 const QVariant v = pointAt( geom, idx, parent );
4608 return QVariant( v.value<
QgsPoint>().
y() );
4614 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4616 return fcnOldYat( values, f, parent, node );
4618 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4620 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4623 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4629 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4631 const QVariant v = pointAt( geom, vertexNumber, parent );
4633 return QVariant( v.value<
QgsPoint>().
y() );
4640 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4646 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4648 const QVariant v = pointAt( geom, vertexNumber, parent );
4650 return QVariant( v.value<
QgsPoint>().
z() );
4657 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4663 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4665 const QVariant v = pointAt( geom, vertexNumber, parent );
4667 return QVariant( v.value<
QgsPoint>().
m() );
4686 return QVariant::fromValue( geom );
4694 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4696 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4702 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4708 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4713 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4720 ogcContext.
layer = mapLayerPtr.data();
4725 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4740 return QVariant( area );
4744 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4756 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4761 return QVariant( geom.
area() );
4775 return QVariant( len );
4779 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4800 return QVariant( len );
4804 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4810 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4816 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4822 return QVariant( geom.
length() );
4827 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4833 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4842 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4851 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4867 if ( !curvePolygon )
4879 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4886 return QVariant( curvePolygon->
ringCount() );
4888 bool foundPoly =
false;
4897 if ( !curvePolygon )
4908 return QVariant( ringCount );
4913 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4915 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4921 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4927 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4933 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4942 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4948 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4954 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4960 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4966 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4974 double max = std::numeric_limits< double >::lowest();
4978 double z = ( *it ).z();
4984 if ( max == std::numeric_limits< double >::lowest() )
4987 return QVariant( max );
4992 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5000 double min = std::numeric_limits< double >::max();
5004 double z = ( *it ).z();
5010 if ( min == std::numeric_limits< double >::max() )
5013 return QVariant( min );
5018 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5026 double min = std::numeric_limits< double >::max();
5030 double m = ( *it ).m();
5036 if ( min == std::numeric_limits< double >::max() )
5039 return QVariant( min );
5044 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5052 double max = std::numeric_limits< double >::lowest();
5056 double m = ( *it ).m();
5062 if ( max == std::numeric_limits< double >::lowest() )
5065 return QVariant( max );
5070 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5074 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5083 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5087 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5096 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5101 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5112 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5116 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5118 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5123 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5142 return QVariant::fromValue( curve->
isClosed() );
5147 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5160 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5161 closedLine->close();
5163 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5177 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5178 closedLine->close();
5180 closed->addGeometry( closedLine.release() );
5183 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5191 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5195 return QVariant::fromValue( fGeom.
isEmpty() );
5201 return QVariant::fromValue(
true );
5203 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5204 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5209 if ( values.length() < 2 || values.length() > 3 )
5212 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5213 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5220 if ( values.length() == 2 )
5223 QString result = engine->relate( sGeom.
constGet() );
5224 return QVariant::fromValue( result );
5229 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5230 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5231 return QVariant::fromValue( result );
5237 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5238 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5243 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5244 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5245 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5249 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5250 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5251 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5255 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5256 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5257 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5261 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5262 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5263 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5267 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5268 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5269 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5273 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5274 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5275 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5279 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5280 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5281 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5286 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5287 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5288 return fGeom.
equals( sGeom ) ? TVL_True : TVL_False;
5293 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5294 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5295 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5296 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5297 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5298 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5301 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5303 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5307 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5309 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5313 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5319 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5321 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5326 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5328 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5333 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5335 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5340 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5355 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5359 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5360 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5361 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5362 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5365 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5371 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5374 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5378 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5379 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5380 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5383 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5389 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5392 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5396 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5399 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5405 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5406 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5407 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5408 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5409 if ( joinInt < 1 || joinInt > 3 )
5413 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5416 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5422 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5423 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5424 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5426 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5427 if ( joinInt < 1 || joinInt > 3 )
5431 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5434 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5440 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5441 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5442 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5445 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5451 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5452 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5453 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5455 return QVariant::fromValue( fGeom );
5460 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5461 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5462 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
5464 const bool perPart = values.value( 3 ).toBool();
5471 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5472 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5474 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5475 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5476 t.rotate( -rotation );
5477 t.translate( -partCenter.x(), -partCenter.y() );
5478 ( *it )->transform( t );
5480 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5492 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5500 fGeom.
rotate( rotation, pt );
5501 return QVariant::fromValue( fGeom );
5507 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5508 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5509 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5510 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
5517 pt = fGeom.boundingBox().center();
5521 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5526 pt = center.asPoint();
5529 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5530 t.scale( xScale, yScale );
5531 t.translate( -pt.
x(), -pt.
y() );
5533 return QVariant::fromValue( fGeom );
5538 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5544 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5545 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5547 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5549 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5550 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5552 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5553 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5554 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5555 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5566 QTransform transform;
5567 transform.translate( deltaX, deltaY );
5568 transform.rotate( rotationZ );
5569 transform.scale( scaleX, scaleY );
5570 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5572 return QVariant::fromValue( fGeom );
5578 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5580 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5585 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5587 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5593 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5594 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5596 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5602 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5604 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5608#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5613 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5614 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5615 const bool allowHoles = values.value( 2 ).toBool();
5617 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5630 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5632 if ( values.length() == 2 )
5633 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5641 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5647 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5649 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5655 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5661 double area,
angle, width, height;
5674 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5675 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5677 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5688 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5699 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5709 reversed->addGeometry( curve->
reversed() );
5716 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5722 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5723 std::reverse(
string.begin(),
string.end() );
5729 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5749 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5755 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5756 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5757 return QVariant( fGeom.
distance( sGeom ) );
5762 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5763 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5766 if ( values.length() == 3 && values.at( 2 ).isValid() )
5768 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5769 densify = std::clamp( densify, 0.0, 1.0 );
5777 return res > -1 ? QVariant( res ) : QVariant();
5782 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5783 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5785 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5790 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5791 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5793 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5798 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5799 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5801 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5807 if ( values.length() < 1 || values.length() > 2 )
5810 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5812 if ( values.length() == 2 )
5813 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5814 QString wkt = fGeom.
asWkt( prec );
5815 return QVariant( wkt );
5820 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5821 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5826 if ( values.length() != 2 )
5828 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5832 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5833 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5861 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5868 if ( pt1->
y() < pt2->
y() )
5870 else if ( pt1->
y() > pt2->
y() )
5878 if ( pt1->
x() < pt2->
x() )
5880 else if ( pt1->
x() > pt2->
x() )
5881 return M_PI + ( M_PI_2 );
5886 if ( pt1->
x() < pt2->
x() )
5888 if ( pt1->
y() < pt2->
y() )
5890 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
5894 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5901 if ( pt1->
y() > pt2->
y() )
5903 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5908 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5909 + ( M_PI + ( M_PI_2 ) );
5916 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5917 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5919 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
5923 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
5931 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
5945 if ( ellipsoid.isEmpty() )
5947 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
5953 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
5961 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
5967 const double bearing = da.
bearing( point1, point2 );
5968 if ( std::isfinite( bearing ) )
5970 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
5983 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5991 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5992 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5993 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5996 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
6003 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6004 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6032 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6042 if ( values.length() != 3 )
6045 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6046 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6047 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6051 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6057 if ( values.length() < 2 )
6060 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6063 return values.at( 0 );
6065 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6066 QVariant cachedExpression;
6071 if ( cachedExpression.isValid() )
6078 bool asc = values.value( 2 ).toBool();
6096 Q_ASSERT( collection );
6100 QgsExpressionSorter sorter( orderBy );
6102 QList<QgsFeature> partFeatures;
6103 partFeatures.reserve( collection->
partCount() );
6104 for (
int i = 0; i < collection->
partCount(); ++i )
6110 sorter.sortFeatures( partFeatures, unconstedContext );
6114 Q_ASSERT( orderedGeom );
6119 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6124 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6127 delete unconstedContext;
6134 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6135 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6139 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6145 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6146 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6150 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6156 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6157 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6161 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6167 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6168 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6169 const bool use3DDistance = values.at( 2 ).toBool();
6171 double x, y, z, distance;
6194 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6197 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6217 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6218 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6220 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6222 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6227 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6228 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6235 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6236 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6241 vertex = count + vertex;
6249 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6250 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6255 vertex = count + vertex;
6263 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6264 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6268 return distance >= 0 ? distance : QVariant();
6273 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6274 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6275 const bool use3DDistance = values.at( 2 ).toBool();
6277 double x, y, z, distance;
6286 return found ? distance : QVariant();
6291 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6293 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6294 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6297 if ( values.length() >= 1 )
6299 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6300 return QVariant( qlonglong( std::round( number ) ) );
6315 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6316 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6317 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6324 const bool omitGroupSeparator = values.value( 3 ).toBool();
6325 const bool trimTrailingZeros = values.value( 4 ).toBool();
6327 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6328 if ( !omitGroupSeparator )
6329 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6331 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6333 QString res = locale.toString( value,
'f', places );
6335 if ( trimTrailingZeros )
6337 const QChar decimal = locale.decimalPoint().at( 0 );
6338 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6340 if ( res.contains( decimal ) )
6342 int trimPoint = res.length() - 1;
6344 while ( res.at( trimPoint ) == zeroDigit )
6347 if ( res.at( trimPoint ) == decimal )
6350 res.truncate( trimPoint + 1 );
6359 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6360 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6361 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6364 if ( format.indexOf(
"Z" ) > 0 )
6365 datetime = datetime.toUTC();
6367 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6368 return locale.toString( datetime, format );
6373 const QVariant variant = values.at( 0 );
6375 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6376 if ( !color.isValid() )
6379 const float alpha = color.alphaF();
6380 if ( color.spec() == QColor::Spec::Cmyk )
6382 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() ) / 3;
6383 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6387 const float avg = ( color.redF() + color.greenF() + color.blueF() ) / 3;
6388 color.setRgbF( avg, avg, avg, alpha );
6391 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6398 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6403 else if ( ratio < 0 )
6408 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6409 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6410 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6411 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6413 QColor newColor( red, green, blue, alpha );
6420 const QVariant variant1 = values.at( 0 );
6421 const QVariant variant2 = values.at( 1 );
6423 if ( variant1.userType() != variant2.userType() )
6425 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6430 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6431 if ( !color1.isValid() )
6434 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6435 if ( !color2.isValid() )
6438 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6440 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6444 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6450 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6451 if ( color1.spec() == QColor::Spec::Cmyk )
6453 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6454 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6455 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6456 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6457 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6461 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6462 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6463 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6464 newColor = QColor::fromRgbF( red, green, blue, alpha );
6469 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6474 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6475 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6476 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6477 QColor color = QColor( red, green, blue );
6478 if ( ! color.isValid() )
6480 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6481 color = QColor( 0, 0, 0 );
6484 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6489 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6490 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6491 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6492 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6493 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6494 if ( ! color.isValid() )
6496 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6505 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6506 QVariant value = node->
eval( parent, context );
6510 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6512 value = node->
eval( parent, context );
6520 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6522 QVariant value = node->
eval( parent, context );
6524 if ( value.toBool() )
6526 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6528 value = node->
eval( parent, context );
6533 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6535 value = node->
eval( parent, context );
6543 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6544 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6545 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6546 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6547 QColor color = QColor( red, green, blue, alpha );
6548 if ( ! color.isValid() )
6550 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6551 color = QColor( 0, 0, 0 );
6560 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6562 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6567 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6571 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6576 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6577 QColor color = ramp->
color( value );
6590 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6592 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6594 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6596 QColor color = QColor::fromHslF( hue, saturation, lightness );
6598 if ( ! color.isValid() )
6600 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6601 color = QColor( 0, 0, 0 );
6604 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6610 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6612 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6614 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6616 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6618 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6619 if ( ! color.isValid() )
6621 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6622 color = QColor( 0, 0, 0 );
6629 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6630 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6631 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6632 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6634 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6635 if ( ! color.isValid() )
6637 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6647 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6649 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6651 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6653 QColor color = QColor::fromHsvF( hue, saturation, value );
6655 if ( ! color.isValid() )
6657 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6658 color = QColor( 0, 0, 0 );
6661 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6667 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6669 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6671 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6673 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6675 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6676 if ( ! color.isValid() )
6678 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6679 color = QColor( 0, 0, 0 );
6686 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6687 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6688 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6689 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6690 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6692 if ( ! color.isValid() )
6694 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6703 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6704 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6705 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6706 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6707 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6709 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6710 if ( ! color.isValid() )
6712 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6722 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6724 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6726 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6728 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6730 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6732 if ( ! color.isValid() )
6734 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6735 color = QColor( 0, 0, 0 );
6738 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6744 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6746 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6748 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6750 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6752 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6754 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6755 if ( ! color.isValid() )
6757 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6758 color = QColor( 0, 0, 0 );
6765 const QVariant variant = values.at( 0 );
6767 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6768 if ( !color.isValid() )
6771 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6772 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6774 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6775 return color.green();
6776 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6777 return color.blue();
6778 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6779 return color.alpha();
6780 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6781 return static_cast< double >( color.hsvHueF() * 360 );
6782 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6783 return static_cast< double >( color.hsvSaturationF() * 100 );
6784 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6785 return static_cast< double >( color.valueF() * 100 );
6786 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6787 return static_cast< double >( color.hslHueF() * 360 );
6788 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6789 return static_cast< double >( color.hslSaturationF() * 100 );
6790 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6791 return static_cast< double >( color.lightnessF() * 100 );
6792 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6793 return static_cast< double >( color.cyanF() * 100 );
6794 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6795 return static_cast< double >( color.magentaF() * 100 );
6796 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6797 return static_cast< double >( color.yellowF() * 100 );
6798 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6799 return static_cast< double >( color.blackF() * 100 );
6801 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6807 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6810 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
6814 QList< QColor > colors;
6816 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6819 if ( !colors.last().isValid() )
6821 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
6825 double step = it.key().toDouble();
6826 if ( it == map.constBegin() )
6831 else if ( it == map.constEnd() )
6841 bool discrete = values.at( 1 ).toBool();
6843 if ( colors.empty() )
6846 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
6851 const QVariant variant = values.at( 0 );
6853 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6854 if ( !color.isValid() )
6857 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6858 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6859 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6860 color.setRed( std::clamp( value, 0, 255 ) );
6861 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6862 color.setGreen( std::clamp( value, 0, 255 ) );
6863 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6864 color.setBlue( std::clamp( value, 0, 255 ) );
6865 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6866 color.setAlpha( std::clamp( value, 0, 255 ) );
6867 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6868 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
6869 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6870 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
6871 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6872 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6873 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6874 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
6875 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6876 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
6877 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6878 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6879 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6880 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
6881 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6882 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
6883 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6884 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
6885 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6886 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6889 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6892 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6897 const QVariant variant = values.at( 0 );
6899 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6900 if ( !color.isValid() )
6903 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6905 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6910 const QVariant variant = values.at( 0 );
6912 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6913 if ( !color.isValid() )
6916 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6918 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6923 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
6926 return QVariant::fromValue( geom );
6932 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
6940 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6945 return QVariant::fromValue( fGeom );
6948 return QVariant::fromValue( fGeom );
6957 return QVariant::fromValue( fGeom );
6970 bool foundLayer =
false;
6971 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
6974 if ( !featureSource || !foundLayer )
6979 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
6992 result = QVariant::fromValue( fet );
7000 bool foundLayer =
false;
7001 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
7004 if ( !featureSource || !foundLayer )
7009 QString cacheValueKey;
7010 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7012 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7014 QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
7015 QString filterString;
7016 for ( ; i != attributeMap.constEnd(); ++i )
7018 if ( !filterString.isEmpty() )
7020 filterString.append(
" AND " );
7024 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7033 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7034 int attributeId = featureSource->fields().lookupField( attribute );
7035 if ( attributeId == -1 )
7040 const QVariant &attVal = values.at( 2 );
7042 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7065 res = QVariant::fromValue( fet );
7080 if ( !values.isEmpty() )
7083 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7084 fieldName = col->
name();
7085 else if ( values.size() == 2 )
7086 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7089 QVariant value = values.at( 0 );
7094 if ( fieldIndex == -1 )
7096 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7102 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7105 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7114 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7132 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7140 const QVariant data = values.at( 0 );
7141 const QMimeDatabase db;
7142 return db.mimeTypeForData( data.toByteArray() ).name();
7147 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7149 bool foundLayer =
false;
7150 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [layerProperty](
QgsMapLayer * layer )-> QVariant
7156 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7157 return layer->name();
7158 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7160 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7161 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7162 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7163 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7164 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7166 QStringList keywords;
7167 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7168 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7170 keywords.append( it.value() );
7172 if ( !keywords.isEmpty() )
7174 return layer->serverProperties()->keywordList();
7176 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7178 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7180 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7182 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7184 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7186 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7188 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7190 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7192 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7194 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7196 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7198 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7200 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7203 QVariant result = QVariant::fromValue( extentGeom );
7206 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7208 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7211 return decodedUri.value( u
"path"_s );
7213 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7215 switch ( layer->
type() )
7218 return QCoreApplication::translate(
"expressions",
"Vector" );
7220 return QCoreApplication::translate(
"expressions",
"Raster" );
7222 return QCoreApplication::translate(
"expressions",
"Mesh" );
7224 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
7226 return QCoreApplication::translate(
"expressions",
"Plugin" );
7228 return QCoreApplication::translate(
"expressions",
"Annotation" );
7230 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
7232 return QCoreApplication::translate(
"expressions",
"Group" );
7234 return QCoreApplication::translate(
"expressions",
"Tiled Scene" );
7240 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7243 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7245 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7247 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7263 const QString uriPart = values.at( 1 ).toString();
7265 bool foundLayer =
false;
7267 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, uriPart](
QgsMapLayer * layer )-> QVariant
7269 if ( !layer->dataProvider() )
7271 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7277 if ( !uriPart.isNull() )
7279 return decodedUri.value( uriPart );
7289 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7300 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7301 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7303 bool foundLayer =
false;
7304 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, band, layerProperty](
QgsMapLayer * layer )-> QVariant
7306 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7310 if ( band < 1 || band > rl->bandCount() )
7312 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7318 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7320 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7322 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7324 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7326 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7328 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7332 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7360 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7377 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7378 bool ascending = values.value( 1 ).toBool();
7379 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7385 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7390 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7395 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7400 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7401 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7403 for (
const auto &item : listB )
7405 if ( listA.contains( item ) )
7409 return QVariant( match == listB.count() );
7414 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7419 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7420 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7421 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
7422 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7423 return list.at( list.length() + pos );
7429 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7430 return list.value( 0 );
7435 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7436 return list.value( list.size() - 1 );
7441 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7442 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7447 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7448 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7453 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7456 for (
const QVariant &item : list )
7458 switch ( item.userType() )
7460 case QMetaType::Int:
7461 case QMetaType::UInt:
7462 case QMetaType::LongLong:
7463 case QMetaType::ULongLong:
7464 case QMetaType::Float:
7465 case QMetaType::Double:
7466 total += item.toDouble();
7471 return i == 0 ? QVariant() : total / i;
7476 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7477 QVariantList numbers;
7478 for (
const auto &item : list )
7480 switch ( item.userType() )
7482 case QMetaType::Int:
7483 case QMetaType::UInt:
7484 case QMetaType::LongLong:
7485 case QMetaType::ULongLong:
7486 case QMetaType::Float:
7487 case QMetaType::Double:
7488 numbers.append( item );
7492 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7493 const int count = numbers.count();
7498 else if ( count % 2 )
7500 return numbers.at( count / 2 );
7504 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7510 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7513 for (
const QVariant &item : list )
7515 switch ( item.userType() )
7517 case QMetaType::Int:
7518 case QMetaType::UInt:
7519 case QMetaType::LongLong:
7520 case QMetaType::ULongLong:
7521 case QMetaType::Float:
7522 case QMetaType::Double:
7523 total += item.toDouble();
7528 return i == 0 ? QVariant() : total;
7531static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7533 QVariant result = value;
7534 ( void )result.convert(
static_cast<int>( type ) );
7540 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7541 QHash< QVariant, int > hash;
7542 for (
const auto &item : list )
7546 const QList< int > occurrences = hash.values();
7547 if ( occurrences.empty() )
7548 return QVariantList();
7550 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7552 const QString option = values.at( 1 ).toString();
7553 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7555 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7557 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7559 if ( hash.isEmpty() )
7562 return QVariant( hash.key( maxValue ) );
7564 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7566 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7568 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7570 if ( maxValue * 2 <= list.size() )
7573 return QVariant( hash.key( maxValue ) );
7584 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7585 QHash< QVariant, int > hash;
7586 for (
const auto &item : list )
7590 const QList< int > occurrences = hash.values();
7591 if ( occurrences.empty() )
7592 return QVariantList();
7594 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7596 const QString option = values.at( 1 ).toString();
7597 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7599 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7601 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7603 if ( hash.isEmpty() )
7606 return QVariant( hash.key( minValue ) );
7608 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7610 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7612 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7614 if ( hash.isEmpty() )
7618 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7619 if ( maxValue * 2 > list.size() )
7620 hash.remove( hash.key( maxValue ) );
7622 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7633 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7634 list.append( values.at( 1 ) );
7635 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7640 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7641 list.prepend( values.at( 1 ) );
7642 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7647 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7648 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7649 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7654 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7655 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7657 position = position + list.length();
7658 if ( position >= 0 && position < list.length() )
7659 list.removeAt( position );
7660 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7668 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7670 const QVariant toRemove = values.at( 1 );
7673 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant & element )
7675 return QgsVariantUtils::isNull( element );
7680 list.removeAll( toRemove );
7682 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7687 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7689 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7691 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7692 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7694 int index = list.indexOf( it.key() );
7695 while ( index >= 0 )
7697 list.replace( index, it.value() );
7698 index = list.indexOf( it.key() );
7702 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7704 else if ( values.count() == 3 )
7706 QVariantList before;
7708 bool isSingleReplacement =
false;
7710 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7712 before = QVariantList() << values.at( 1 );
7716 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7719 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7721 after = QVariantList() << values.at( 2 );
7722 isSingleReplacement =
true;
7726 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7729 if ( !isSingleReplacement && before.length() != after.length() )
7731 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7735 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7736 for (
int i = 0; i < before.length(); i++ )
7738 int index = list.indexOf( before.at( i ) );
7739 while ( index >= 0 )
7741 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7742 index = list.indexOf( before.at( i ) );
7746 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7750 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7757 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7758 QVariantList list_new;
7760 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
7762 while ( list.removeOne( cur ) )
7764 list_new.append( cur );
7768 list_new.append( list );
7770 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7776 for (
const QVariant &cur : values )
7778 list += QgsExpressionUtils::getListValue( cur, parent );
7780 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7785 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7786 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7787 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7788 int slice_length = 0;
7790 if ( start_pos < 0 )
7792 start_pos = list.length() + start_pos;
7796 slice_length = end_pos - start_pos + 1;
7800 slice_length = list.length() + end_pos - start_pos + 1;
7803 if ( slice_length < 0 )
7807 list = list.mid( start_pos, slice_length );
7813 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7814 std::reverse( list.begin(), list.end() );
7820 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7821 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7822 for (
const QVariant &cur : array2 )
7824 if ( array1.contains( cur ) )
7825 return QVariant(
true );
7827 return QVariant(
false );
7832 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7834 QVariantList distinct;
7836 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7838 if ( !distinct.contains( *it ) )
7840 distinct += ( *it );
7849 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7850 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7851 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7855 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7857 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
7858 if ( it != ( array.constEnd() - 1 ) )
7864 return QVariant( str );
7869 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7870 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7871 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7873 QStringList list = str.split( delimiter );
7876 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
7878 array += ( !( *it ).isEmpty() ) ? *it : empty;
7886 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7887 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
7888 if ( document.isNull() )
7891 return document.toVariant();
7897 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
7898 return QString( document.toJson( QJsonDocument::Compact ) );
7903 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7904 if ( str.isEmpty() )
7905 return QVariantMap();
7906 str = str.trimmed();
7913 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7920 for (
int i = 0; i + 1 < values.length(); i += 2 )
7922 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
7929 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7930 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7931 QVariantMap resultMap;
7933 for (
auto it = map.cbegin(); it != map.cend(); it++ )
7935 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
7943 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
7948 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
7953 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7954 map.remove( values.at( 1 ).toString() );
7960 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7961 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
7968 for (
const QVariant &cur : values )
7970 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
7971 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
7972 result.insert( it.key(), it.value() );
7979 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
7984 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
7989 const QString envVarName = values.at( 0 ).toString();
7990 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
7993 return QProcessEnvironment::systemEnvironment().value( envVarName );
7998 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8001 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
8004 return QFileInfo( file ).completeBaseName();
8009 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8012 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8015 return QFileInfo( file ).completeSuffix();
8020 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8023 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8026 return QFileInfo::exists( file );
8031 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8034 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8037 return QFileInfo( file ).fileName();
8042 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8045 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8048 return QFileInfo( file ).isFile();
8053 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8056 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8059 return QFileInfo( file ).isDir();
8064 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8067 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8070 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8075 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8078 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8081 return QFileInfo( file ).size();
8084static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8086 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8092 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8093 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8095 if ( method ==
"md4"_L1 )
8097 hash = fcnHash( str, QCryptographicHash::Md4 );
8099 else if ( method ==
"md5"_L1 )
8101 hash = fcnHash( str, QCryptographicHash::Md5 );
8103 else if ( method ==
"sha1"_L1 )
8105 hash = fcnHash( str, QCryptographicHash::Sha1 );
8107 else if ( method ==
"sha224"_L1 )
8109 hash = fcnHash( str, QCryptographicHash::Sha224 );
8111 else if ( method ==
"sha256"_L1 )
8113 hash = fcnHash( str, QCryptographicHash::Sha256 );
8115 else if ( method ==
"sha384"_L1 )
8117 hash = fcnHash( str, QCryptographicHash::Sha384 );
8119 else if ( method ==
"sha512"_L1 )
8121 hash = fcnHash( str, QCryptographicHash::Sha512 );
8123 else if ( method ==
"sha3_224"_L1 )
8125 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8127 else if ( method ==
"sha3_256"_L1 )
8129 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8131 else if ( method ==
"sha3_384"_L1 )
8133 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8135 else if ( method ==
"sha3_512"_L1 )
8137 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8139 else if ( method ==
"keccak_224"_L1 )
8141 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8143 else if ( method ==
"keccak_256"_L1 )
8145 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8147 else if ( method ==
"keccak_384"_L1 )
8149 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8151 else if ( method ==
"keccak_512"_L1 )
8153 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8157 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8164 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8169 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8174 const QByteArray input = values.at( 0 ).toByteArray();
8175 return QVariant( QString( input.toBase64() ) );
8180 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8182 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8184 query.addQueryItem( it.key(), it.value().toString() );
8186 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8191 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8192 const QByteArray base64 = value.toLocal8Bit();
8193 const QByteArray decoded = QByteArray::fromBase64( base64 );
8194 return QVariant( decoded );
8199static QVariant executeGeomOverlay(
const QVariantList &values,
const QgsExpressionContext *context,
QgsExpression *parent,
const RelationFunction &relationFunction,
bool invert =
false,
double bboxGrow = 0,
bool isNearestFunc =
false,
bool isIntersectsFunc =
false )
8204 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8208 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8211 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8220 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8223 const bool layerCanBeCached = node->
isStatic( parent, context );
8224 QVariant targetLayerValue = node->
eval( parent, context );
8228 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8230 QString subExpString = node->dump();
8232 bool testOnly = ( subExpString ==
"NULL" );
8235 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8239 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8244 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8246 QString filterString = node->dump();
8247 if ( filterString !=
"NULL" )
8249 request.setFilterExpression( filterString );
8253 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8255 QVariant limitValue = node->eval( parent, context );
8257 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8260 double max_distance = 0;
8261 if ( isNearestFunc )
8263 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8265 QVariant distanceValue = node->eval( parent, context );
8267 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8271 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
8273 QVariant cacheValue = node->eval( parent, context );
8275 bool cacheEnabled = cacheValue.toBool();
8281 double minOverlap { -1 };
8282 double minInscribedCircleRadius { -1 };
8283 bool returnDetails =
false;
8284 bool sortByMeasure =
false;
8285 bool sortAscending =
false;
8286 bool requireMeasures =
false;
8287 bool overlapOrRadiusFilter =
false;
8288 if ( isIntersectsFunc )
8291 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8293 const QVariant minOverlapValue = node->eval( parent, context );
8295 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8296 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8298 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8300 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8301 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8303 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8304 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8306 const QString sorting { node->eval( parent, context ).toString().toLower() };
8307 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8308 sortAscending = sorting.startsWith(
"asc" );
8309 requireMeasures = sortByMeasure || returnDetails;
8310 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8317 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8320 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8323 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8326 if ( bboxGrow != 0 )
8328 intDomain.
grow( bboxGrow );
8331 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8337 QList<QgsFeature> features;
8338 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8342 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8343 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8347 cachedTarget = targetLayer->
materialize( request );
8348 if ( layerCanBeCached )
8349 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8359 if ( layerCanBeCached )
8360 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8367 QList<QgsFeatureId> fidsList;
8368 if ( isNearestFunc )
8370 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8374 fidsList = spatialIndex.
intersects( intDomain );
8377 QListIterator<QgsFeatureId> i( fidsList );
8378 while ( i.hasNext() )
8381 if ( sameLayers && feat.
id() == fId2 )
8383 features.append( cachedTarget->
getFeature( fId2 ) );
8391 request.setFilterRect( intDomain );
8396 if ( sameLayers && feat.
id() == feat2.
id() )
8398 features.append( feat2 );
8406 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8407 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8413 subExpression.
prepare( &subContext );
8426 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double & overlapValue ) ->
bool
8428 bool testResult {
false };
8430 QVector<double> overlapValues;
8431 const QgsGeometry merged { intersection.mergeLines() };
8436 if ( minOverlap != -1 || requireMeasures )
8438 overlapValue = geom->
length();
8439 overlapValues.append( overlapValue );
8440 if ( minOverlap != -1 )
8442 if ( overlapValue >= minOverlap )
8454 if ( ! overlapValues.isEmpty() )
8456 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8463 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double & radiusValue,
double & overlapValue ) ->
bool
8466 bool testResult {
false };
8468 QVector<double> overlapValues;
8469 QVector<double> radiusValues;
8470 for (
auto it = intersection.const_parts_begin(); ( ! testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8474 if ( minOverlap != -1 || requireMeasures )
8476 overlapValue = geom->
area();
8477 overlapValues.append( geom->
area() );
8478 if ( minOverlap != - 1 )
8480 if ( overlapValue >= minOverlap )
8492 if ( minInscribedCircleRadius != -1 || requireMeasures )
8495 const double width = bbox.
width();
8496 const double height = bbox.
height();
8497 const double size = width > height ? width : height;
8498 const double tolerance = size / 100.0;
8500 testResult = radiusValue >= minInscribedCircleRadius;
8501 radiusValues.append( radiusValues );
8506 if ( !radiusValues.isEmpty() )
8508 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8511 if ( ! overlapValues.isEmpty() )
8513 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8523 QVariantList results;
8525 QListIterator<QgsFeature> i( features );
8526 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8532 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
8535 double overlapValue = -1;
8536 double radiusValue = -1;
8538 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8551 for (
const auto &geom : std::as_const( geometries ) )
8553 switch ( geom.type() )
8557 poly.append( geom.asPolygon() );
8562 line.append( geom.asPolyline() );
8567 point.append( geom.asPoint() );
8578 switch ( geometry.
type() )
8606 switch ( intersection.
type() )
8613 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8615 if ( ! testResult && overlapOrRadiusFilter )
8628 if ( minInscribedCircleRadius != -1 )
8634 const bool testResult { testLinestring( intersection, overlapValue ) };
8636 if ( ! testResult && overlapOrRadiusFilter )
8649 if ( minInscribedCircleRadius != -1 )
8654 bool testResult {
false };
8655 if ( minOverlap != -1 || requireMeasures )
8675 testResult = testLinestring( feat2.
geometry(), overlapValue );
8680 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8686 if ( ! testResult && overlapOrRadiusFilter )
8714 const QVariant expResult = subExpression.
evaluate( &subContext );
8716 if ( requireMeasures )
8718 QVariantMap resultRecord;
8719 resultRecord.insert( u
"id"_s, feat2.
id() );
8720 resultRecord.insert( u
"result"_s, expResult );
8722 resultRecord.insert( u
"overlap"_s, overlapValue );
8724 if ( radiusValue != -1 )
8726 resultRecord.insert( u
"radius"_s, radiusValue );
8728 results.append( resultRecord );
8732 results.append( expResult );
8738 results.append( feat2.
id() );
8752 if ( requireMeasures )
8754 if ( sortByMeasure )
8756 std::sort( results.begin(), results.end(), [ sortAscending ](
const QVariant & recordA,
const QVariant & recordB ) ->
bool
8758 return sortAscending ?
8759 recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
8760 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
8764 if ( limit > 0 && results.size() > limit )
8766 results.erase( results.begin() + limit );
8769 if ( ! returnDetails )
8771 QVariantList expResults;
8772 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
8774 expResults.append( it->toMap().value( u
"result"_s ) );
8784 QVariantList disjoint_results;
8793 if ( !results.contains( feat2.
id() ) )
8796 disjoint_results.append( subExpression.
evaluate( &subContext ) );
8799 return disjoint_results;
8842 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
8851 QMutexLocker locker( &sFunctionsMutex );
8853 QList<QgsExpressionFunction *> &functions = *sFunctions();
8855 if ( functions.isEmpty() )
8858 << QgsExpressionFunction::Parameter( u
"expression"_s )
8859 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
8860 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
8863 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
8864 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
8867 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
8873 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnAzimuth, u
"GeometryGroup"_s )
8874 <<
new QgsStaticExpressionFunction( u
"bearing"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ) << QgsExpressionFunction::Parameter( u
"source_crs"_s,
true, QVariant() ) << QgsExpressionFunction::Parameter( u
"ellipsoid"_s,
true, QVariant() ), fcnBearing, u
"GeometryGroup"_s )
8875 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnInclination, u
"GeometryGroup"_s )
8876 <<
new QgsStaticExpressionFunction( u
"project"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point"_s ) << QgsExpressionFunction::Parameter( u
"distance"_s ) << QgsExpressionFunction::Parameter( u
"azimuth"_s ) << QgsExpressionFunction::Parameter( u
"elevation"_s,
true, M_PI_2 ), fcnProject, u
"GeometryGroup"_s )
8884 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
8888 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
8889 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
8891 QgsStaticExpressionFunction *randFunc =
new QgsStaticExpressionFunction( u
"rand"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s ) << QgsExpressionFunction::Parameter( u
"max"_s ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ), fcnRnd, u
"Math"_s );
8893 functions << randFunc;
8895 QgsStaticExpressionFunction *randfFunc =
new QgsStaticExpressionFunction( u
"randf"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"min"_s,
true, 0.0 ) << QgsExpressionFunction::Parameter( u
"max"_s,
true, 1.0 ) << QgsExpressionFunction::Parameter( u
"seed"_s,
true ), fcnRndF, u
"Math"_s );
8897 functions << randfFunc;
8900 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8901 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8902 <<
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 )
8903 <<
new QgsStaticExpressionFunction( u
"scale_linear"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"domain_min"_s ) << QgsExpressionFunction::Parameter( u
"domain_max"_s ) << QgsExpressionFunction::Parameter( u
"range_min"_s ) << QgsExpressionFunction::Parameter( u
"range_max"_s ), fcnLinearScale, u
"Math"_s )
8904 <<
new QgsStaticExpressionFunction( u
"scale_polynomial"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"domain_min"_s ) << QgsExpressionFunction::Parameter( u
"domain_max"_s ) << QgsExpressionFunction::Parameter( u
"range_min"_s ) << QgsExpressionFunction::Parameter( u
"range_max"_s ) << QgsExpressionFunction::Parameter( u
"exponent"_s ), fcnPolynomialScale, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"scale_exp"_s )
8905 <<
new QgsStaticExpressionFunction( u
"scale_exponential"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"domain_min"_s ) << QgsExpressionFunction::Parameter( u
"domain_max"_s ) << QgsExpressionFunction::Parameter( u
"range_min"_s ) << QgsExpressionFunction::Parameter( u
"range_max"_s ) << QgsExpressionFunction::Parameter( u
"exponent"_s ), fcnExponentialScale, u
"Math"_s )
8908 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
8909 <<
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 )
8910 <<
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 )
8911 <<
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 )
8912 <<
new QgsStaticExpressionFunction( u
"to_string"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToString, QStringList() << u
"Conversions"_s << u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"tostring"_s )
8913 <<
new QgsStaticExpressionFunction( u
"to_datetime"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() ) << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ), fcnToDateTime, QStringList() << u
"Conversions"_s << u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"todatetime"_s )
8914 <<
new QgsStaticExpressionFunction( u
"to_date"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() ) << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ), fcnToDate, QStringList() << u
"Conversions"_s << u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"todate"_s )
8915 <<
new QgsStaticExpressionFunction( u
"to_time"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"format"_s,
true, QVariant() ) << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ), fcnToTime, QStringList() << u
"Conversions"_s << u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"totime"_s )
8916 <<
new QgsStaticExpressionFunction( u
"to_interval"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ), fcnToInterval, QStringList() << u
"Conversions"_s << u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"tointerval"_s )
8917 <<
new QgsStaticExpressionFunction( u
"to_dm"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"axis"_s ) << QgsExpressionFunction::Parameter( u
"precision"_s ) << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ), fcnToDegreeMinute, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"todm"_s )
8918 <<
new QgsStaticExpressionFunction( u
"to_dms"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"axis"_s ) << QgsExpressionFunction::Parameter( u
"precision"_s ) << QgsExpressionFunction::Parameter( u
"formatting"_s,
true ), fcnToDegreeMinuteSecond, u
"Conversions"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"todms"_s )
8919 <<
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 )
8920 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
8921 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
8922 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
8923 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8924 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
8925 <<
new QgsStaticExpressionFunction( u
"if"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"condition"_s ) << QgsExpressionFunction::Parameter( u
"result_when_true"_s ) << QgsExpressionFunction::Parameter( u
"result_when_false"_s ), fcnIf, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
true )
8926 <<
new QgsStaticExpressionFunction( u
"try"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"expression"_s ) << QgsExpressionFunction::Parameter( u
"alternative"_s,
true, QVariant() ), fcnTry, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
true )
8928 <<
new QgsStaticExpressionFunction( u
"aggregate"_s,
8930 << QgsExpressionFunction::Parameter( u
"layer"_s )
8931 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
8932 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
8933 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
8934 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
8935 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
8946 if ( !node->
args() )
8949 QSet<QString> referencedVars;
8952 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
8958 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
8961 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
8970 if ( !node->
args() )
8971 return QSet<QString>();
8973 QSet<QString> referencedCols;
8974 QSet<QString> referencedVars;
8978 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
8984 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
8989 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
8992 return referencedCols;
8998 << QgsExpressionFunction::Parameter( u
"relation"_s )
8999 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
9000 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
9001 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
9002 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
9005 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9006 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9007 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9008 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9009 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9010 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9011 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9012 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9013 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9014 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9015 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9016 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9017 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9018 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9019 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9020 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9021 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9022 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9023 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9024 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9025 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9027 <<
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 )
9028 <<
new QgsStaticExpressionFunction( u
"regexp_matches"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ) << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ), fcnRegexpMatches, u
"Arrays"_s )
9030 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9032 << QgsExpressionFunction::Parameter( u
"datetime2"_s ),
9033 fcnAge, u
"Date and Time"_s )
9042 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9043 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9045 << QgsExpressionFunction::Parameter( u
"month"_s )
9046 << QgsExpressionFunction::Parameter( u
"day"_s ),
9047 fcnMakeDate, u
"Date and Time"_s )
9049 << QgsExpressionFunction::Parameter( u
"minute"_s )
9050 << QgsExpressionFunction::Parameter( u
"second"_s ),
9051 fcnMakeTime, u
"Date and Time"_s )
9053 << QgsExpressionFunction::Parameter( u
"month"_s )
9054 << QgsExpressionFunction::Parameter( u
"day"_s )
9055 << QgsExpressionFunction::Parameter( u
"hour"_s )
9056 << QgsExpressionFunction::Parameter( u
"minute"_s )
9057 << QgsExpressionFunction::Parameter( u
"second"_s ),
9058 fcnMakeDateTime, u
"Date and Time"_s )
9060 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9061 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9062 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9063 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9064 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9065 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9066 fcnMakeInterval, u
"Date and Time"_s )
9067 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9068 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9069 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9070 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9071 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9074 << QgsExpressionFunction::Parameter( u
"string"_s )
9075 << QgsExpressionFunction::Parameter( u
"substring"_s )
9076 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9082 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9084 << QgsExpressionFunction::Parameter( u
"string"_s )
9085 << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9087 << QgsExpressionFunction::Parameter( u
"string"_s )
9088 << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9089 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9090 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9091 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9095 <<
new QgsStaticExpressionFunction( u
"wordwrap"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ) << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"" ), fcnWordwrap, u
"String"_s )
9096 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9097 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9098 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s )}, fcnRepeat, u
"String"_s )
9099 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9100 <<
new QgsStaticExpressionFunction( u
"regexp_replace"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s )
9101 << QgsExpressionFunction::Parameter( u
"replacement"_s ), fcnRegexpReplace, u
"String"_s )
9102 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9103 <<
new QgsStaticExpressionFunction( u
"substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"length"_s,
true ), fcnSubstr, u
"String"_s, QString(),
9104 false, QSet< QString >(),
false, QStringList(),
true )
9105 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9106 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9107 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9108 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9109 <<
new QgsStaticExpressionFunction( u
"rpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnRPad, u
"String"_s )
9110 <<
new QgsStaticExpressionFunction( u
"lpad"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"width"_s ) << QgsExpressionFunction::Parameter( u
"fill"_s ), fcnLPad, u
"String"_s )
9111 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9113 << QgsExpressionFunction::Parameter( u
"number"_s )
9114 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9115 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9116 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9117 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ), fcnFormatNumber, u
"String"_s )
9118 <<
new QgsStaticExpressionFunction( u
"format_date"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"datetime"_s ) << QgsExpressionFunction::Parameter( u
"format"_s ) << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() ), fcnFormatDate, QStringList() << u
"String"_s << u
"Date and Time"_s )
9119 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9121 << QgsExpressionFunction::Parameter( u
"color2"_s )
9122 << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9123 fcnColorMixRgb, u
"Color"_s )
9125 << QgsExpressionFunction::Parameter( u
"color2"_s )
9126 << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9127 fcnColorMix, u
"Color"_s )
9129 << QgsExpressionFunction::Parameter( u
"green"_s )
9130 << QgsExpressionFunction::Parameter( u
"blue"_s ),
9131 fcnColorRgb, u
"Color"_s )
9133 << QgsExpressionFunction::Parameter( u
"green"_s )
9134 << QgsExpressionFunction::Parameter( u
"blue"_s )
9135 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9136 fcnColorRgbF, u
"Color"_s )
9138 << QgsExpressionFunction::Parameter( u
"green"_s )
9139 << QgsExpressionFunction::Parameter( u
"blue"_s )
9140 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9141 fncColorRgba, u
"Color"_s )
9143 << QgsExpressionFunction::Parameter( u
"value"_s ),
9146 << QgsExpressionFunction::Parameter( u
"value"_s ),
9149 << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ),
9150 fcnCreateRamp, u
"Color"_s )
9152 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9153 << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9154 fcnColorHsl, u
"Color"_s )
9156 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9157 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9158 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9159 fncColorHsla, u
"Color"_s )
9161 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9162 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9163 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9164 fcnColorHslF, u
"Color"_s )
9166 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9167 << QgsExpressionFunction::Parameter( u
"value"_s ),
9168 fcnColorHsv, u
"Color"_s )
9170 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9171 << QgsExpressionFunction::Parameter( u
"value"_s )
9172 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9173 fncColorHsva, u
"Color"_s )
9175 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9176 << QgsExpressionFunction::Parameter( u
"value"_s )
9177 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9178 fcnColorHsvF, u
"Color"_s )
9180 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9181 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9182 << QgsExpressionFunction::Parameter( u
"black"_s ),
9183 fcnColorCmyk, u
"Color"_s )
9185 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9186 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9187 << QgsExpressionFunction::Parameter( u
"black"_s )
9188 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9189 fncColorCmyka, u
"Color"_s )
9191 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9192 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9193 << QgsExpressionFunction::Parameter( u
"black"_s )
9194 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9195 fcnColorCmykF, u
"Color"_s )
9197 << QgsExpressionFunction::Parameter( u
"component"_s ),
9198 fncColorPart, u
"Color"_s )
9200 << QgsExpressionFunction::Parameter( u
"factor"_s ),
9201 fncDarker, u
"Color"_s )
9203 << QgsExpressionFunction::Parameter( u
"factor"_s ),
9204 fncLighter, u
"Color"_s )
9205 <<
new QgsStaticExpressionFunction( u
"set_color_part"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ) << QgsExpressionFunction::Parameter( u
"component"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fncSetColorPart, u
"Color"_s )
9209 fcnBaseFileName, u
"Files and Paths"_s )
9211 fcnFileSuffix, u
"Files and Paths"_s )
9213 fcnFileExists, u
"Files and Paths"_s )
9215 fcnFileName, u
"Files and Paths"_s )
9217 fcnPathIsFile, u
"Files and Paths"_s )
9219 fcnPathIsDir, u
"Files and Paths"_s )
9221 fcnFilePath, u
"Files and Paths"_s )
9223 fcnFileSize, u
"Files and Paths"_s )
9225 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ),
9226 fcnExif, u
"Files and Paths"_s )
9228 fcnExifGeoTag, u
"GeometryGroup"_s )
9231 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ),
9232 fcnGenericHash, u
"Conversions"_s )
9234 fcnHashMd5, u
"Conversions"_s )
9236 fcnHashSha256, u
"Conversions"_s )
9240 fcnToBase64, u
"Conversions"_s )
9242 fcnFromBase64, u
"Conversions"_s )
9246 << QgsExpressionFunction::Parameter( u
"date"_s )
9247 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9248 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9249 << QgsExpressionFunction::Parameter( u
"height"_s )
9250 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9251 fcnMagneticDeclination, u
"MagneticModels"_s )
9253 << QgsExpressionFunction::Parameter( u
"date"_s )
9254 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9255 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9256 << QgsExpressionFunction::Parameter( u
"height"_s )
9257 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9258 fcnMagneticInclination, u
"MagneticModels"_s )
9260 << QgsExpressionFunction::Parameter( u
"date"_s )
9261 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9262 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9263 << QgsExpressionFunction::Parameter( u
"height"_s )
9264 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9265 fcnMagneticDeclinationRateOfChange, u
"MagneticModels"_s )
9267 << QgsExpressionFunction::Parameter( u
"date"_s )
9268 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9269 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9270 << QgsExpressionFunction::Parameter( u
"height"_s )
9271 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9272 fcnMagneticInclinationRateOfChange, u
"MagneticModels"_s )
9277 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9279 functions << geomFunc;
9281 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9283 functions << areaFunc;
9285 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9287 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9289 functions << lengthFunc;
9291 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9293 functions << perimeterFunc;
9295 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9297 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
9299 fcnRoundness, u
"GeometryGroup"_s );
9301 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9305 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9309 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9313 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
9315 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9316 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9317 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9318 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9319 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9320 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9321 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9323 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9324 while ( i.hasNext() )
9328 << QgsExpressionFunction::Parameter( u
"layer"_s )
9329 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9330 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9331 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9332 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9333 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9334 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9335 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9336 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false ),
9341 functions << fcnGeomOverlayFunc;
9345 << QgsExpressionFunction::Parameter( u
"layer"_s )
9346 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9347 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9348 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9349 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9350 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9354 functions << fcnGeomOverlayNearestFunc;
9357 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9362 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9363 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9364 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9366 << QgsExpressionFunction::Parameter( u
"ignore_closing_nodes"_s,
true,
false ),
9367 fcnNodesToPoints, u
"GeometryGroup"_s )
9368 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9369 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9370 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9372 << QgsExpressionFunction::Parameter( u
"y"_s )
9373 << QgsExpressionFunction::Parameter( u
"m"_s ),
9374 fcnMakePointM, u
"GeometryGroup"_s )
9375 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
9376 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
9378 << QgsExpressionFunction::Parameter( u
"point2"_s )
9379 << QgsExpressionFunction::Parameter( u
"point3"_s ),
9380 fcnMakeTriangle, u
"GeometryGroup"_s )
9382 << QgsExpressionFunction::Parameter( u
"center"_s )
9383 << QgsExpressionFunction::Parameter( u
"radius"_s )
9384 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9385 fcnMakeCircle, u
"GeometryGroup"_s )
9387 << QgsExpressionFunction::Parameter( u
"center"_s )
9388 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
9389 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
9390 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9391 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9392 fcnMakeEllipse, u
"GeometryGroup"_s )
9394 << QgsExpressionFunction::Parameter( u
"center"_s )
9395 << QgsExpressionFunction::Parameter( u
"radius"_s )
9396 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
9397 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
9398 fcnMakeRegularPolygon, u
"GeometryGroup"_s )
9400 << QgsExpressionFunction::Parameter( u
"point1"_s )
9401 << QgsExpressionFunction::Parameter( u
"point2"_s ),
9402 fcnMakeSquare, u
"GeometryGroup"_s )
9404 << QgsExpressionFunction::Parameter( u
"point1"_s )
9405 << QgsExpressionFunction::Parameter( u
"point2"_s )
9406 << QgsExpressionFunction::Parameter( u
"point3"_s )
9407 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
9408 fcnMakeRectangleFrom3Points, u
"GeometryGroup"_s )
9411 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9412#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
9413 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
9415 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
9417 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
9418 }, fcnGeomMakeValid, u
"GeometryGroup"_s );
9420 functions <<
new QgsStaticExpressionFunction( u
"x_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnXat, u
"GeometryGroup"_s );
9421 functions <<
new QgsStaticExpressionFunction( u
"y_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s,
true ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnYat, u
"GeometryGroup"_s );
9422 functions <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
9423 functions <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
9425 QgsStaticExpressionFunction *xAtFunc =
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 );
9427 functions << xAtFunc;
9430 QgsStaticExpressionFunction *yAtFunc =
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 );
9432 functions << yAtFunc;
9435 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
9436 <<
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 )
9437 <<
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 )
9438 <<
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 )
9439 <<
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 )
9440 <<
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 )
9441 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
9442 <<
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 )
9443 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
9444 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
9445 <<
new QgsStaticExpressionFunction( u
"intersects_bbox"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s ), fcnBbox, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"bbox"_s )
9447 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9448 fcnDisjoint, u
"GeometryGroup"_s )
9450 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9451 fcnIntersects, u
"GeometryGroup"_s )
9453 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9454 fcnTouches, u
"GeometryGroup"_s )
9456 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9457 fcnCrosses, u
"GeometryGroup"_s )
9459 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9460 fcnContains, u
"GeometryGroup"_s )
9462 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9463 fcnOverlaps, u
"GeometryGroup"_s )
9465 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9466 fcnWithin, u
"GeometryGroup"_s )
9468 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9469 fcnEquals, u
"GeometryGroup"_s )
9471 << QgsExpressionFunction::Parameter( u
"dx"_s )
9472 << QgsExpressionFunction::Parameter( u
"dy"_s ),
9473 fcnTranslate, u
"GeometryGroup"_s )
9475 << QgsExpressionFunction::Parameter( u
"rotation"_s )
9476 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
9477 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
9478 fcnRotate, u
"GeometryGroup"_s )
9480 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
9481 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
9482 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
9483 fcnScale, u
"GeometryGroup"_s )
9485 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
9486 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
9487 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
9488 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
9489 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
9490 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
9491 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
9492 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
9493 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
9494 fcnAffineTransform, u
"GeometryGroup"_s )
9496 << QgsExpressionFunction::Parameter( u
"distance"_s )
9497 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
9498 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
9499 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
9500 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
9501 fcnBuffer, u
"GeometryGroup"_s )
9503 fcnForceRHR, u
"GeometryGroup"_s )
9505 fcnForcePolygonCW, u
"GeometryGroup"_s )
9507 fcnForcePolygonCCW, u
"GeometryGroup"_s )
9509 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9510 << QgsExpressionFunction::Parameter( u
"width"_s )
9511 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
9512 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ), fcnWedgeBuffer, u
"GeometryGroup"_s )
9514 << QgsExpressionFunction::Parameter( u
"start_width"_s )
9515 << QgsExpressionFunction::Parameter( u
"end_width"_s )
9516 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9517 , fcnTaperedBuffer, u
"GeometryGroup"_s )
9519 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9520 , fcnBufferByM, u
"GeometryGroup"_s )
9522 << QgsExpressionFunction::Parameter( u
"distance"_s )
9523 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9525 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
9526 fcnOffsetCurve, u
"GeometryGroup"_s )
9528 << QgsExpressionFunction::Parameter( u
"distance"_s )
9529 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9531 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
9532 fcnSingleSidedBuffer, u
"GeometryGroup"_s )
9534 << QgsExpressionFunction::Parameter( u
"start_distance"_s )
9535 << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
9536 fcnExtend, u
"GeometryGroup"_s )
9537 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
9538 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
9540 << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
9541 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
9542 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
9544 << QgsExpressionFunction::Parameter( u
"index"_s ),
9545 fcnInteriorRingN, u
"GeometryGroup"_s )
9547 << QgsExpressionFunction::Parameter( u
"index"_s ),
9548 fcnGeometryN, u
"GeometryGroup"_s )
9549 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
9550 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
9553 QgsExpressionFunction::Parameter( u
"geometry1"_s ),
9554 QgsExpressionFunction::Parameter( u
"geometry2"_s )
9555 }, fcnSharedPaths, u
"GeometryGroup"_s )
9557 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
9558 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
9559 <<
new QgsStaticExpressionFunction( u
"smooth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
9560 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
9561 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
9562 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ), fcnSmooth, u
"GeometryGroup"_s )
9563 <<
new QgsStaticExpressionFunction( u
"triangular_wave"_s,
9565 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9566 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9567 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9568 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9569 }, fcnTriangularWave, u
"GeometryGroup"_s )
9570 <<
new QgsStaticExpressionFunction( u
"triangular_wave_randomized"_s,
9572 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9573 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9574 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9575 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9576 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9577 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9578 }, fcnTriangularWaveRandomized, u
"GeometryGroup"_s )
9579 <<
new QgsStaticExpressionFunction( u
"square_wave"_s,
9581 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9582 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9583 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9584 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9585 }, fcnSquareWave, u
"GeometryGroup"_s )
9586 <<
new QgsStaticExpressionFunction( u
"square_wave_randomized"_s,
9588 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9589 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9590 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9591 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9592 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9593 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9594 }, fcnSquareWaveRandomized, u
"GeometryGroup"_s )
9595 <<
new QgsStaticExpressionFunction( u
"wave"_s,
9597 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9598 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9599 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9600 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9601 }, fcnRoundWave, u
"GeometryGroup"_s )
9602 <<
new QgsStaticExpressionFunction( u
"wave_randomized"_s,
9604 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9605 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9606 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9607 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9608 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9609 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9610 }, fcnRoundWaveRandomized, u
"GeometryGroup"_s )
9611 <<
new QgsStaticExpressionFunction( u
"apply_dash_pattern"_s,
9613 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9614 QgsExpressionFunction::Parameter( u
"pattern"_s ),
9615 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
9616 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
9617 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
9618 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
9619 }, fcnApplyDashPattern, u
"GeometryGroup"_s )
9620 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s,
9622 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9623 QgsExpressionFunction::Parameter( u
"vertices"_s )
9624 }, fcnDensifyByCount, u
"GeometryGroup"_s )
9625 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s,
9627 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9628 QgsExpressionFunction::Parameter( u
"distance"_s )
9629 }, fcnDensifyByDistance, u
"GeometryGroup"_s )
9630 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
9631 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
9632 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
9633 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
9634 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
9635 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
9636 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
9637 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
9638 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
9639 <<
new QgsStaticExpressionFunction( u
"is_empty_or_null"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmptyOrNull, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9640 <<
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 )
9641#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
9643 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
9644 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ), fcnConcaveHull, u
"GeometryGroup"_s )
9647 << QgsExpressionFunction::Parameter( u
"geometry"_s ),
9648 fcnOrientedBBox, u
"GeometryGroup"_s )
9650 << QgsExpressionFunction::Parameter( u
"geometry"_s ),
9651 fcnMainAngle, u
"GeometryGroup"_s )
9653 << QgsExpressionFunction::Parameter( u
"geometry"_s )
9654 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9655 fcnMinimalCircle, u
"GeometryGroup"_s )
9657 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9658 fcnDifference, u
"GeometryGroup"_s )
9660 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9661 fcnDistance, u
"GeometryGroup"_s )
9662 <<
new QgsStaticExpressionFunction( u
"hausdorff_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s )
9663 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
9664 fcnHausdorffDistance, u
"GeometryGroup"_s )
9666 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9667 fcnIntersection, u
"GeometryGroup"_s )
9669 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9670 fcnSymDifference, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"symDifference"_s )
9672 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9673 fcnCombine, u
"GeometryGroup"_s )
9675 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9676 fcnCombine, u
"GeometryGroup"_s )
9678 << QgsExpressionFunction::Parameter( u
"precision"_s,
true, 8.0 ),
9679 fcnGeomToWKT, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"geomToWKT"_s )
9681 fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
9682 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
9684 << QgsExpressionFunction::Parameter( u
"source_auth_id"_s )
9685 << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
9686 fcnTransformGeometry, u
"GeometryGroup"_s )
9688 << QgsExpressionFunction::Parameter( u
"x"_s )
9689 << QgsExpressionFunction::Parameter( u
"y"_s ),
9690 fcnExtrude, u
"GeometryGroup"_s, QString() )
9692 fcnGeomIsMultipart, u
"GeometryGroup"_s )
9694 fcnZMax, u
"GeometryGroup"_s )
9696 fcnZMin, u
"GeometryGroup"_s )
9698 fcnMMax, u
"GeometryGroup"_s )
9700 fcnMMin, u
"GeometryGroup"_s )
9702 fcnSinuosity, u
"GeometryGroup"_s )
9704 fcnStraightDistance2d, u
"GeometryGroup"_s );
9707 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction( u
"order_parts"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s )
9708 << QgsExpressionFunction::Parameter( u
"orderby"_s )
9709 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
9710 fcnOrderParts, u
"GeometryGroup"_s, QString() );
9715 const QList< QgsExpressionNode *> argList = node->
args()->
list();
9716 for ( QgsExpressionNode *argNode : argList )
9718 if ( !argNode->isStatic( parent, context ) )
9724 QgsExpressionNode *argNode = node->
args()->
at( 1 );
9726 QString expString = argNode->
eval( parent, context ).toString();
9730 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
9741 QgsExpressionNode *argNode = node->
args()->
at( 1 );
9742 QString
expression = argNode->
eval( parent, context ).toString();
9744 e.prepare( context );
9750 functions << orderPartsFunc;
9754 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9755 fcnClosestPoint, u
"GeometryGroup"_s )
9757 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9758 fcnShortestLine, u
"GeometryGroup"_s )
9760 << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
9762 << QgsExpressionFunction::Parameter( u
"m"_s ) << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
9763 fcnLineInterpolatePointByM, u
"GeometryGroup"_s )
9765 << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
9767 << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
9769 << QgsExpressionFunction::Parameter( u
"m"_s ) << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
9770 fcnLineLocateM, u
"GeometryGroup"_s )
9772 << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
9774 << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
9776 << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ), fcnLineSubset, u
"GeometryGroup"_s );
9781 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
9783 functions << idFunc;
9785 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
9787 functions << currentFeatureFunc;
9789 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction( u
"uuid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"format"_s,
true, u
"WithBraces"_s ), fcnUuid, u
"Record and Attributes"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$uuid"_s );
9791 functions << uuidFunc;
9794 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
9796 << QgsExpressionFunction::Parameter( u
"attribute"_s )
9797 << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
9798 fcnGetFeature, u
"Record and Attributes"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"QgsExpressionUtils::getFeature"_s )
9800 << QgsExpressionFunction::Parameter( u
"feature_id"_s ),
9801 fcnGetFeatureById, u
"Record and Attributes"_s, QString(),
false, QSet<QString>(),
false );
9803 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction( u
"attributes"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s,
true ),
9806 functions << attributesFunc;
9807 QgsStaticExpressionFunction *representAttributesFunc =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1,
9810 functions << representAttributesFunc;
9812 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction( u
"is_feature_valid"_s,
9814 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
9815 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
9818 functions << validateFeature;
9820 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction( u
"is_attribute_valid"_s,
9823 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
9824 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
9827 functions << validateAttribute;
9829 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction(
9833 u
"Record and Attributes"_s,
9839 functions << maptipFunc;
9841 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction(
9842 u
"display_expression"_s,
9844 fcnFeatureDisplayExpression,
9845 u
"Record and Attributes"_s,
9851 functions << displayFunc;
9853 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction(
9857 u
"Record and Attributes"_s,
9863 functions << isSelectedFunc;
9866 <<
new QgsStaticExpressionFunction(
9870 u
"Record and Attributes"_s,
9877 <<
new QgsStaticExpressionFunction(
9878 u
"sqlite_fetch_and_increment"_s,
9880 << QgsExpressionFunction::Parameter( u
"database"_s )
9881 << QgsExpressionFunction::Parameter( u
"table"_s )
9882 << QgsExpressionFunction::Parameter( u
"id_field"_s )
9883 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
9884 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
9885 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
9886 fcnSqliteFetchAndIncrement,
9887 u
"Record and Attributes"_s
9892 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
9893 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
9897 QgsStaticExpressionFunction *representValueFunc =
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 );
9904 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
9911 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
9921 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
9927 functions << representValueFunc;
9932 << QgsExpressionFunction::Parameter( u
"property"_s ),
9933 fcnGetLayerProperty, u
"Map Layers"_s )
9934 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
9936 << QgsExpressionFunction::Parameter( u
"layer"_s )
9937 << QgsExpressionFunction::Parameter( u
"part"_s,
true ),
9938 fcnDecodeUri, u
"Map Layers"_s )
9939 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
9941 << QgsExpressionFunction::Parameter( u
"binary_data"_s ),
9942 fcnMimeType, u
"General"_s )
9944 << QgsExpressionFunction::Parameter( u
"band"_s )
9945 << QgsExpressionFunction::Parameter( u
"statistic"_s ), fcnGetRasterBandStat, u
"Rasters"_s );
9948 QgsStaticExpressionFunction *varFunction =
new QgsStaticExpressionFunction( u
"var"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"name"_s ), fcnGetVariable, u
"General"_s );
9959 QgsExpressionNode *argNode = node->
args()->
at( 0 );
9961 if ( !argNode->
isStatic( parent, context ) )
9964 const QString varName = argNode->
eval( parent, context ).toString();
9965 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
9969 return scope ? scope->
isStatic( varName ) :
false;
9977 if ( node && node->
args()->
count() > 0 )
9979 QgsExpressionNode *argNode = node->
args()->
at( 0 );
9980 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
9982 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
9999 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10001 if ( argNode->
isStatic( parent, context ) )
10003 QString expString = argNode->
eval( parent, context ).toString();
10007 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10014 functions << evalTemplateFunction;
10022 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10024 if ( argNode->
isStatic( parent, context ) )
10026 QString expString = argNode->
eval( parent, context ).toString();
10030 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10038 functions << evalFunc;
10040 QgsStaticExpressionFunction *attributeFunc =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10044 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10045 for ( QgsExpressionNode *argNode : argList )
10047 if ( !argNode->
isStatic( parent, context ) )
10059 functions << attributeFunc;
10063 <<
new QgsWithVariableExpressionFunction()
10064 <<
new QgsStaticExpressionFunction( u
"raster_value"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnRasterValue, u
"Rasters"_s )
10065 <<
new QgsStaticExpressionFunction( u
"raster_attributes"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"layer"_s ) << QgsExpressionFunction::Parameter( u
"band"_s ) << QgsExpressionFunction::Parameter( u
"point"_s ), fcnRasterAttributes, u
"Rasters"_s )
10068 <<
new QgsArrayForeachExpressionFunction()
10069 <<
new QgsArrayFilterExpressionFunction()
10070 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10071 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10072 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10073 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10074 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10075 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array_a"_s ) << QgsExpressionFunction::Parameter( u
"array_b"_s ), fcnArrayAll, u
"Arrays"_s )
10076 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10077 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10083 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10084 <<
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 )
10085 <<
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 )
10087 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10088 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10089 <<
new QgsStaticExpressionFunction( u
"array_insert"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayInsert, u
"Arrays"_s )
10090 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10091 <<
new QgsStaticExpressionFunction( u
"array_remove_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayRemoveAll, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10092 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10093 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"array_prioritize"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10094 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10095 <<
new QgsStaticExpressionFunction( u
"array_slice"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"start_pos"_s ) << QgsExpressionFunction::Parameter( u
"end_pos"_s ), fcnArraySlice, u
"Arrays"_s )
10096 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10097 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10098 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10099 <<
new QgsStaticExpressionFunction( u
"array_to_string"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," ) << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ), fcnArrayToString, u
"Arrays"_s )
10100 <<
new QgsStaticExpressionFunction( u
"string_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"delimiter"_s,
true,
"," ) << QgsExpressionFunction::Parameter( u
"emptyvalue"_s,
true,
"" ), fcnStringToArray, u
"Arrays"_s )
10101 <<
new QgsStaticExpressionFunction( u
"generate_series"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"start"_s ) << QgsExpressionFunction::Parameter( u
"stop"_s ) << QgsExpressionFunction::Parameter( u
"step"_s,
true, 1.0 ), fcnGenerateSeries, u
"Arrays"_s )
10102 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10105 <<
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 )
10106 <<
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 )
10107 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10109 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10110 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10111 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10112 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10113 <<
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 )
10114 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10118 << QgsExpressionFunction::Parameter( u
"prefix"_s ),
10119 fcnMapPrefixKeys, u
"Maps"_s )
10121 fcnMapToHtmlTable, u
"Maps"_s )
10123 fcnMapToHtmlDefinitionList, u
"Maps"_s )
10125 fcnToFormUrlEncode, u
"Maps"_s )
10134 *sOwnedFunctions() << func;
10135 *sBuiltinFunctions() << func->name();
10136 sBuiltinFunctions()->append( func->aliases() );
10150 QMutexLocker locker( &sFunctionsMutex );
10151 sFunctions()->append( function );
10152 if ( transferOwnership )
10153 sOwnedFunctions()->append( function );
10168 QMutexLocker locker( &sFunctionsMutex );
10169 sFunctions()->removeAt( fnIdx );
10170 sFunctionIndexMap.clear();
10178 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10179 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10181 sBuiltinFunctions()->removeAll( func->name() );
10182 for (
const QString &alias : func->aliases() )
10184 sBuiltinFunctions()->removeAll( alias );
10187 sFunctions()->removeAll( func );
10190 qDeleteAll( *sOwnedFunctions() );
10191 sOwnedFunctions()->clear();
10196 if ( sBuiltinFunctions()->isEmpty() )
10200 return *sBuiltinFunctions();
10216 QgsExpressionNode::NodeList *args = node->
args();
10218 if ( args->
count() < 2 )
10221 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10231 QVariantList result;
10233 if ( args->
count() < 2 )
10237 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10239 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10240 std::unique_ptr< QgsExpressionContext > tempContext;
10243 tempContext = std::make_unique< QgsExpressionContext >();
10244 subContext = tempContext.get();
10247 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10251 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
10255 result << args->
at( 1 )->
eval( parent, subContext );
10268 Q_UNUSED( context )
10280 if ( args->
count() < 2 )
10284 args->
at( 0 )->
prepare( parent, context );
10288 subContext = *context;
10295 args->
at( 1 )->
prepare( parent, &subContext );
10316 if ( args->
count() < 2 )
10319 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10329 QVariantList result;
10331 if ( args->
count() < 2 )
10335 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10337 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10338 std::unique_ptr< QgsExpressionContext > tempContext;
10341 tempContext = std::make_unique< QgsExpressionContext >();
10342 subContext = tempContext.get();
10345 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10349 if ( args->
count() >= 3 )
10351 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
10353 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
10355 limit = limitVar.toInt();
10363 for (
const QVariant &value : array )
10365 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
10366 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
10370 if ( limit > 0 && limit == result.size() )
10385 Q_UNUSED( context )
10397 if ( args->
count() < 2 )
10401 args->
at( 0 )->
prepare( parent, context );
10405 subContext = *context;
10411 args->
at( 1 )->
prepare( parent, &subContext );
10429 QgsExpressionNode::NodeList *args = node->
args();
10431 if ( args->
count() < 3 )
10435 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10437 QVariant
name = args->
at( 0 )->
eval( parent, context );
10438 QVariant value = args->
at( 1 )->
eval( parent, context );
10441 appendTemporaryVariable( context,
name.toString(), value );
10442 if ( args->
at( 2 )->
isStatic( parent, context ) )
10444 popTemporaryVariable( context );
10455 if ( args->
count() < 3 )
10459 QVariant
name = args->
at( 0 )->
eval( parent, context );
10460 QVariant value = args->
at( 1 )->
eval( parent, context );
10462 const QgsExpressionContext *updatedContext = context;
10463 std::unique_ptr< QgsExpressionContext > tempContext;
10464 if ( !updatedContext )
10466 tempContext = std::make_unique< QgsExpressionContext >();
10467 updatedContext = tempContext.get();
10470 appendTemporaryVariable( updatedContext,
name.toString(), value );
10471 result = args->
at( 2 )->
eval( parent, updatedContext );
10474 popTemporaryVariable( updatedContext );
10483 Q_UNUSED( context )
10495 if ( args->
count() < 3 )
10500 QVariant value = args->
at( 1 )->
prepare( parent, context );
10503 std::unique_ptr< QgsExpressionContext > tempContext;
10504 if ( !updatedContext )
10506 tempContext = std::make_unique< QgsExpressionContext >();
10507 updatedContext = tempContext.get();
10510 appendTemporaryVariable( updatedContext,
name.toString(), value );
10511 args->
at( 2 )->
prepare( parent, updatedContext );
10514 popTemporaryVariable( updatedContext );
10519void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
10521 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
10522 delete updatedContext->
popScope();
10525void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
10527 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
10528 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
10530 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
@ 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...
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.
Represents a single parameter passed to a function.
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 hasGeometry() const
Returns true if the feature has an associated geometry.
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.
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 difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up 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 triangularWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs triangular waves along the boundary of the geometry, with the specified wavelength and amp...
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
bool touches(const QgsGeometry &geometry) const
Returns true if the geometry touches another geometry.
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.
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false) const
Attempts to make an invalid geometry valid without losing vertices.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
QgsGeometry combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
QgsGeometry 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 equals(const QgsGeometry &geometry) const
Test if this geometry is exactly equal to another geometry.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
double area() const
Returns the planar, 2-dimensional area of the geometry.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QgsGeometry concaveHull(double targetPercent, bool allowHoles=false) const
Returns a possibly concave polygon that contains all the points in the geometry.
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 intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
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) 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.
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry extendLine(double startDistance, double endDistance) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
QgsGeometry triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
QgsGeometry simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
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) 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 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())
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Custom exception class which is raised when an operation is not supported.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
double inclination(const QgsPoint &other) const
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Quadrilateral geometry type.
static QgsQuadrilateral squareFromDiagonal(const QgsPoint &p1, const QgsPoint &p2)
Construct a QgsQuadrilateral as a square from a diagonal.
QgsPolygon * toPolygon(bool force2D=false) const
Returns the quadrilateral as a new polygon.
static QgsQuadrilateral rectangleFrom3Points(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, ConstructionOption mode)
Construct a QgsQuadrilateral as a Rectangle from 3 points.
ConstructionOption
A quadrilateral can be constructed from 3 points where the second distance can be determined by the t...
@ Distance
Second distance is equal to the distance between 2nd and 3rd point.
@ Projected
Second distance is equal to the distance of the perpendicular projection of the 3rd point on the segm...
The Field class represents a Raster Attribute Table field, including its name, usage and type.
bool isRamp() const
Returns true if the field carries a color ramp component information (RedMin/RedMax,...
bool isColor() const
Returns true if the field carries a color component (Red, Green, Blue and optionally Alpha) informati...
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
A rectangle specified with double values.
void grow(double delta)
Grows the rectangle in place by the specified amount.
Regular Polygon geometry type.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices).
QgsPolygon * toPolygon() const
Returns as a polygon.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
Q_INVOKABLE QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
void setUsesGeometryFunction(const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry)
Set a function that will be called when determining if the function requires feature geometry or not.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
static QString unaccent(const QString &input)
Removes accents and other diacritical marks from a string, replacing accented characters with their u...
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Contains utility functions for working with symbols and symbol layers.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
Allows creation of a multi-layer database-side transaction.
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QVariant aggregate(Qgis::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters ¶meters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeatureIds *fids=nullptr, QgsFeedback *feedback=nullptr, QString *error=nullptr) const
Calculates an aggregated value from the layer's features.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QgsWithVariableExpressionFunction()
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored).
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
#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)
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 *)
bool(QgsGeometry::* RelationFunction)(const QgsGeometry &geometry) const
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
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.