70#include <QCryptographicHash>
71#include <QMimeDatabase>
72#include <QProcessEnvironment>
73#include <QRegularExpression>
96 QVariantList argValues;
100 const QList< QgsExpressionNode * > argList = args->
list();
101 argValues.reserve( argList.size() );
108 v = QVariant::fromValue( n );
112 v = n->eval( parent, context );
114 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
115 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
118 argValues.append( v );
123 return func( argValues, context, parent, node );
134 return QStringList();
161 return mGroups.isEmpty() ? false : mGroups.contains( u
"deprecated"_s );
166 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
178 const QString &group,
179 const QString &helpText,
183 const QStringList &aliases,
187 , mAliases( aliases )
188 , mUsesGeometry( false )
189 , mUsesGeometryFunc( usesGeometry )
190 , mReferencedColumnsFunc( referencedColumns )
202 if ( mUsesGeometryFunc )
203 return mUsesGeometryFunc( node );
205 return mUsesGeometry;
215 if ( mReferencedColumnsFunc )
216 return mReferencedColumnsFunc( node );
218 return mReferencedColumns;
224 return mIsStaticFunc( node, parent, context );
232 return mPrepareFunc( node, parent, context );
244 mIsStaticFunc =
nullptr;
250 mPrepareFunc = prepareFunc;
255 if ( node && node->
args() )
257 const QList< QgsExpressionNode * > argList = node->
args()->
list();
260 if ( !argNode->isStatic( parent, context ) )
270 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
271 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
272 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
274 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
281 double current = start + step;
282 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
297 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
299 if ( name ==
"feature"_L1 )
301 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
303 else if ( name ==
"id"_L1 )
305 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
307 else if ( name ==
"geometry"_L1 )
323 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
332 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
334 return expression.evaluate( context );
339 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
340 return QVariant( std::sqrt( x ) );
345 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
346 return QVariant( std::fabs( val ) );
351 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
352 return ( deg * M_PI ) / 180;
356 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
357 return ( 180 * rad ) / M_PI;
361 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
362 return QVariant( std::sin( x ) );
366 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
367 return QVariant( std::cos( x ) );
371 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
372 return QVariant( std::tan( x ) );
376 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
377 return QVariant( std::asin( x ) );
381 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
382 return QVariant( std::acos( x ) );
386 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
387 return QVariant( std::atan( x ) );
391 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
392 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
393 return QVariant( std::atan2( y, x ) );
397 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
398 return QVariant( std::exp( x ) );
402 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
405 return QVariant( std::log( x ) );
409 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
412 return QVariant( log10( x ) );
416 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
417 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
418 if ( x <= 0 || b <= 0 )
420 return QVariant( std::log( x ) / std::log( b ) );
424 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
425 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
429 std::random_device rd;
430 std::mt19937_64 generator( rd() );
432 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
435 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
438 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
443 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
444 std::hash<std::string> hasher;
445 seed = hasher( seedStr.toStdString() );
447 generator.seed( seed );
451 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
452 return QVariant( min + f * ( max - min ) );
456 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
457 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
461 std::random_device rd;
462 std::mt19937_64 generator( rd() );
464 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
467 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
470 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
475 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
476 std::hash<std::string> hasher;
477 seed = hasher( seedStr.toStdString() );
479 generator.seed( seed );
482 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
483 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
484 return QVariant( randomInteger );
487 return QVariant(
int( randomInteger ) );
492 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
493 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
494 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
495 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
496 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
498 if ( domainMin >= domainMax )
500 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
505 if ( val >= domainMax )
509 else if ( val <= domainMin )
515 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
516 double c = rangeMin - ( domainMin * m );
519 return QVariant( m * val +
c );
524 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
525 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
526 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
527 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
528 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
529 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
531 if ( domainMin >= domainMax )
533 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
543 if ( val >= domainMax )
547 else if ( val <= domainMin )
553 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
558 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
559 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
560 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
561 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
562 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
563 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
565 if ( domainMin >= domainMax )
567 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
577 if ( val >= domainMax )
581 else if ( val <= domainMin )
587 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
588 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
594 double maxVal = std::numeric_limits<double>::quiet_NaN();
595 for (
const QVariant &val : values )
598 if ( std::isnan( maxVal ) )
602 else if ( !std::isnan( testVal ) )
604 maxVal = std::max( maxVal, testVal );
608 if ( !std::isnan( maxVal ) )
610 result = QVariant( maxVal );
618 double minVal = std::numeric_limits<double>::quiet_NaN();
619 for (
const QVariant &val : values )
622 if ( std::isnan( minVal ) )
626 else if ( !std::isnan( testVal ) )
628 minVal = std::min( minVal, testVal );
632 if ( !std::isnan( minVal ) )
634 result = QVariant( minVal );
646 QVariant value = node->
eval( parent, context );
651 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
655 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
660 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
662 value = node->
eval( parent, context );
668 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
673 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
675 QString subExpression = node->
dump();
679 if ( values.count() > 3 )
681 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
684 if ( !nl || nl->value().isValid() )
689 if ( values.count() > 4 )
691 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
693 value = node->
eval( parent, context );
700 if ( values.count() > 5 )
702 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
705 if ( !nl || nl->value().isValid() )
707 orderBy = node->
dump();
712 QString aggregateError;
720 const QSet< QString > filterVars = filterExp.referencedVariables();
721 const QSet< QString > subExpVars = subExp.referencedVariables();
722 QSet<QString> allVars = filterVars + subExpVars;
724 bool isStatic =
true;
725 if ( filterVars.contains( u
"parent"_s )
726 || filterVars.contains( QString() )
727 || subExpVars.contains( u
"parent"_s )
728 || subExpVars.contains( QString() ) )
734 for (
const QString &varName : allVars )
737 if ( scope && !scope->
isStatic( varName ) )
745 if ( isStatic && ! parameters.
orderBy.isEmpty() )
747 for (
const auto &orderByClause : std::as_const( parameters.
orderBy ) )
749 const QgsExpression &orderByExpression { orderByClause.expression() };
761 const QString contextHash = context->
uniqueHash( ok, allVars );
764 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
765 orderBy, contextHash );
770 cacheKey = u
"aggfcn:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
781 subContext.appendScope( subScope );
782 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
794 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
798 if ( !aggregateError.isEmpty() )
799 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
801 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
812 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
820 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
824 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
833 QVariant value = node->
eval( parent, context );
835 QString relationId = value.toString();
842 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
844 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
849 relation = relations.at( 0 );
856 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
858 value = node->
eval( parent, context );
864 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
869 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
871 QString subExpression = node->
dump();
875 if ( values.count() > 3 )
877 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
879 value = node->
eval( parent, context );
886 if ( values.count() > 4 )
888 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
891 if ( !nl || nl->value().isValid() )
893 orderBy = node->
dump();
904 const QString
cacheKey = u
"relagg:%1%:%2:%3:%4:%5:%6"_s.arg( relationId, vl->id(),
905 QString::number(
static_cast< int >( aggregate ) ),
918 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
922 if ( !error.isEmpty() )
923 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
925 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
939 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
947 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
951 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
960 QString subExpression = node->
dump();
964 if ( values.count() > 1 )
966 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
969 if ( !nl || nl->value().isValid() )
970 groupBy = node->
dump();
974 if ( values.count() > 2 )
976 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
979 if ( !nl || nl->value().isValid() )
985 if ( orderByPos >= 0 && values.count() > orderByPos )
987 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
990 if ( !nl || nl->value().isValid() )
992 orderBy = node->
dump();
1000 if ( !groupBy.isEmpty() )
1003 QVariant groupByValue = groupByExp.evaluate( context );
1004 QString groupByClause = u
"%1 %2 %3"_s.arg( groupBy,
1007 if ( !parameters.
filter.isEmpty() )
1008 parameters.
filter = u
"(%1) AND (%2)"_s.arg( parameters.
filter, groupByClause );
1010 parameters.
filter = groupByClause;
1016 bool isStatic =
true;
1017 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1018 for (
const QString &varName : refVars )
1021 if ( scope && !scope->
isStatic( varName ) )
1032 const QString contextHash = context->
uniqueHash( ok, refVars );
1035 cacheKey = u
"agg:%1:%2:%3:%4:%5:%6"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
1036 orderBy, contextHash );
1041 cacheKey = u
"agg:%1:%2:%3:%4:%5"_s.arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1053 subContext.appendScope( subScope );
1055 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1059 if ( !error.isEmpty() )
1060 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1062 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1167 if ( values.count() > 3 )
1169 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1171 QVariant value = node->
eval( parent, context );
1173 parameters.
delimiter = value.toString();
1184 if ( values.count() > 3 )
1186 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1188 QVariant value = node->
eval( parent, context );
1190 parameters.
delimiter = value.toString();
1206 QVariant scale = context->
variable( u
"map_scale"_s );
1211 const double v = scale.toDouble( &ok );
1219 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1220 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1221 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1224 if ( testValue <= minValue )
1226 return QVariant( minValue );
1228 else if ( testValue >= maxValue )
1230 return QVariant( maxValue );
1234 return QVariant( testValue );
1240 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1241 return QVariant( std::floor( x ) );
1246 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1247 return QVariant( std::ceil( x ) );
1252 const QVariant value = values.at( 0 );
1253 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1255 return QVariant(
false );
1257 else if ( value.userType() == QMetaType::QString )
1260 return QVariant( !value.toString().isEmpty() );
1262 else if ( QgsExpressionUtils::isList( value ) )
1264 return !value.toList().isEmpty();
1266 return QVariant( value.toBool() );
1270 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1274 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1278 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1283 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1284 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1285 if ( format.isEmpty() && !language.isEmpty() )
1287 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1288 return QVariant( QDateTime() );
1291 if ( format.isEmpty() && language.isEmpty() )
1292 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1294 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1295 QLocale locale = QLocale();
1296 if ( !language.isEmpty() )
1298 locale = QLocale( language );
1301 QDateTime datetime = locale.toDateTime( datetimestring, format );
1302 if ( !datetime.isValid() )
1304 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1305 datetime = QDateTime();
1307 return QVariant( datetime );
1312 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1313 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1314 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1316 const QDate date( year, month, day );
1317 if ( !date.isValid() )
1319 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1322 return QVariant( date );
1327 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1328 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1329 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1331 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1332 if ( !time.isValid() )
1334 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1337 return QVariant( time );
1342 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1343 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1344 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1345 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1346 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1347 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1349 const QDate date( year, month, day );
1350 if ( !date.isValid() )
1352 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1355 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1356 if ( !time.isValid() )
1358 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1361 return QVariant( QDateTime( date, time ) );
1366 const QString timeZoneId = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1370#if QT_FEATURE_timezone > 0
1371 if ( !timeZoneId.isEmpty() )
1373 tz = QTimeZone( timeZoneId.toUtf8() );
1376 if ( !tz.isValid() )
1378 parent->
setEvalErrorString( QObject::tr(
"'%1' is not a valid time zone ID" ).arg( timeZoneId ) );
1383 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneFromId" ) );
1385 return QVariant::fromValue( tz );
1390#if QT_FEATURE_timezone > 0
1391 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1392 if ( datetime.isValid() )
1394 return QVariant::fromValue( datetime.timeZone() );
1398 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnGetTimeZone" ) );
1405#if QT_FEATURE_timezone > 0
1406 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1407 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1408 if ( datetime.isValid() && tz.isValid() )
1410 datetime.setTimeZone( tz );
1411 return QVariant::fromValue( datetime );
1415 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnSetTimeZone" ) );
1422#if QT_FEATURE_timezone > 0
1423 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
1424 const QTimeZone tz = QgsExpressionUtils::getTimeZoneValue( values.at( 1 ), parent );
1425 if ( datetime.isValid() && tz.isValid() )
1427 return QVariant::fromValue( datetime.toTimeZone( tz ) );
1431 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnConvertTimeZone" ) );
1438#if QT_FEATURE_timezone > 0
1439 const QTimeZone timeZone = QgsExpressionUtils::getTimeZoneValue( values.at( 0 ), parent );
1440 if ( timeZone.isValid() )
1442 return QString( timeZone.id() );
1446 parent->
setEvalErrorString( QObject::tr(
"Qt is built without Qt timezone support, cannot use fcnTimeZoneToId" ) );
1453 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1454 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1455 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1456 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1457 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1458 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1459 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1461 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1466 for (
const QVariant &value : values )
1477 const QVariant val1 = values.at( 0 );
1478 const QVariant val2 = values.at( 1 );
1488 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1489 return QVariant( str.toLower() );
1493 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1494 return QVariant( str.toUpper() );
1498 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1499 QStringList elems = str.split(
' ' );
1500 for (
int i = 0; i < elems.size(); i++ )
1502 if ( elems[i].size() > 1 )
1503 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1505 return QVariant( elems.join(
' '_L1 ) );
1510 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1511 return QVariant( str.trimmed() );
1516 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1518 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1520 const QRegularExpression re( u
"^([%1]*)"_s.arg( QRegularExpression::escape( characters ) ) );
1521 str.replace( re, QString() );
1522 return QVariant( str );
1527 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1529 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1531 const QRegularExpression re( u
"([%1]*)$"_s.arg( QRegularExpression::escape( characters ) ) );
1532 str.replace( re, QString() );
1533 return QVariant( str );
1538 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1539 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1545 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1546 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1552 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1553 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1560 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1566 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1567 return QVariant( QString( character ) );
1572 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1574 if ( value.isEmpty() )
1579 int res = value.at( 0 ).unicode();
1580 return QVariant( res );
1585 if ( values.length() == 2 || values.length() == 3 )
1587 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1588 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1590 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1603 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1607 return QVariant( geom.
length() );
1613 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1614 return QVariant( str.length() );
1619 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1624 double totalLength = 0;
1629 totalLength += line->length3D();
1634 totalLength += segmentized->length3D();
1644 const QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1645 const qlonglong number = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1646 return string.repeated( std::max(
static_cast< int >( number ), 0 ) );
1651 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1653 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1654 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1655 QVector< QPair< QString, QString > > mapItems;
1657 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1659 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1663 std::sort( mapItems.begin(),
1665 [](
const QPair< QString, QString > &pair1,
1666 const QPair< QString, QString > &pair2 )
1668 return ( pair1.first.length() > pair2.first.length() );
1671 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1673 str = str.replace( it->first, it->second );
1676 return QVariant( str );
1678 else if ( values.count() == 3 )
1680 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1681 QVariantList before;
1683 bool isSingleReplacement =
false;
1685 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1687 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1691 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1694 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1696 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1697 isSingleReplacement =
true;
1701 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1704 if ( !isSingleReplacement && before.length() != after.length() )
1706 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1710 for (
int i = 0; i < before.length(); i++ )
1712 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1715 return QVariant( str );
1719 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1726 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1727 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1728 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1730 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1731 if ( !re.isValid() )
1733 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1736 return QVariant( str.replace( re, after ) );
1741 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1742 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1744 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1745 if ( !re.isValid() )
1747 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1750 return QVariant( ( str.indexOf( re ) + 1 ) );
1755 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1756 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1757 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1759 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1760 if ( !re.isValid() )
1762 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1766 QRegularExpressionMatch matches = re.match( str );
1767 if ( matches.hasMatch() )
1770 QStringList list = matches.capturedTexts();
1773 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1775 array += ( !( *it ).isEmpty() ) ? *it : empty;
1778 return QVariant( array );
1788 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1789 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1791 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1792 if ( !re.isValid() )
1794 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1799 QRegularExpressionMatch match = re.match( str );
1800 if ( match.hasMatch() )
1803 if ( match.lastCapturedIndex() > 0 )
1806 return QVariant( match.captured( 1 ) );
1811 return QVariant( match.captured( 0 ) );
1816 return QVariant(
"" );
1822 QString uuid = QUuid::createUuid().toString();
1823 if ( values.at( 0 ).toString().compare( u
"WithoutBraces"_s, Qt::CaseInsensitive ) == 0 )
1824 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1825 else if ( values.at( 0 ).toString().compare( u
"Id128"_s, Qt::CaseInsensitive ) == 0 )
1826 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1832 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1835 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1836 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1839 if ( values.at( 2 ).isValid() )
1840 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1846 from = str.size() + from;
1852 else if ( from > 0 )
1860 len = str.size() + len - from;
1867 return QVariant( str.mid( from, len ) );
1872 return QVariant( f.
id() );
1877 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1878 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1879 bool foundLayer =
false;
1880 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1882 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1883 if ( !layer || !layer->dataProvider() )
1885 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1889 if ( bandNb < 1 || bandNb > layer->bandCount() )
1891 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1897 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1904 QgsMultiPointXY multiPoint = geom.asMultiPoint();
1905 if ( multiPoint.count() == 1 )
1907 point = multiPoint[0];
1916 double value = layer->dataProvider()->sample( point, bandNb );
1917 return std::isnan( value ) ? QVariant() : value;
1923 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1934 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1935 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1937 bool foundLayer =
false;
1938 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1940 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1941 if ( !layer || !layer->dataProvider() )
1943 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1947 if ( bandNb < 1 || bandNb > layer->bandCount() )
1949 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1953 if ( std::isnan( value ) )
1955 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1959 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1964 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1965 if ( data.isEmpty() )
1971 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1972 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1979 result.insert( fields.at( idx ).name, data.at( idx ) );
1987 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
2008 if ( values.size() == 1 )
2010 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2013 else if ( values.size() == 2 )
2015 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2016 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2020 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
2029 QString table { R
"html(
2032 <tr><th>%1</th></tr>
2035 <tr><td>%2</td></tr>
2039 if ( values.size() == 1 )
2041 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2045 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
2049 if ( dict.isEmpty() )
2054 QStringList headers;
2057 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2059 headers.push_back( it.key().toHtmlEscaped() );
2060 cells.push_back( it.value().toString( ).toHtmlEscaped() );
2063 return table.arg( headers.join(
"</th><th>"_L1 ), cells.join(
"</td><td>"_L1 ) );
2068 QString table { R
"html(
2073 if ( values.size() == 1 )
2075 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
2079 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
2083 if ( dict.isEmpty() )
2090 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
2092 rows.append( u
"<dt>%1</dt><dd>%2</dd>"_s.arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
2095 return table.arg( rows );
2103 layer = context->
variable( u
"layer"_s );
2108 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2110 layer = node->
eval( parent, context );
2121 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2125 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2126 if ( strength ==
"hard"_L1 )
2130 else if ( strength ==
"soft"_L1 )
2135 bool foundLayer =
false;
2136 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2138 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2141 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2147 for (
int i = 0; i < fields.
size(); i++ )
2162 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2174 layer = context->
variable( u
"layer"_s );
2179 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2181 layer = node->
eval( parent, context );
2192 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2196 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2197 if ( strength ==
"hard"_L1 )
2201 else if ( strength ==
"soft"_L1 )
2206 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2208 bool foundLayer =
false;
2209 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2211 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2218 if ( fieldIndex == -1 )
2220 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2231 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2247 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2252 for (
int i = 0; i < fields.
count(); ++i )
2266 if ( values.isEmpty() )
2269 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2271 else if ( values.size() == 1 )
2273 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2274 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2276 else if ( values.size() == 2 )
2278 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2279 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2283 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2290 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2296 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2302 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2304 const QString fieldName { fields.
at( fieldIndex ).
name() };
2305 const QVariant attributeVal = feature.
attribute( fieldIndex );
2306 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer->
id(), fieldName, attributeVal.toString() );
2309 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2318 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer->
id(), fieldName );
2330 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2332 result.insert( fields.
at( fieldIndex ).
name(), value );
2348 bool evaluate =
true;
2352 if ( values.isEmpty() )
2355 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2357 else if ( values.size() == 1 )
2359 layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
2360 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2362 else if ( values.size() == 2 )
2364 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2365 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2367 else if ( values.size() == 3 )
2369 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2370 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2371 evaluate = values.value( 2 ).toBool();
2377 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2381 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2413 subContext.setFeature( feature );
2422 exp.prepare( &subContext );
2423 return exp.evaluate( &subContext ).toString();
2429 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2434 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2441 if ( values.isEmpty() )
2444 layer = context->
variable( u
"layer"_s );
2446 else if ( values.size() == 1 )
2448 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2449 layer = context->
variable( u
"layer"_s );
2451 else if ( values.size() == 2 )
2453 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2454 layer = values.at( 0 );
2458 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2462 bool foundLayer =
false;
2463 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2465 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2466 if ( !layer || !feature.
isValid() )
2483 if ( values.isEmpty() )
2484 layer = context->
variable( u
"layer"_s );
2485 else if ( values.count() == 1 )
2486 layer = values.at( 0 );
2489 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2493 bool foundLayer =
false;
2494 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2496 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2512 static QMap<QString, qlonglong> counterCache;
2513 QVariant functionResult;
2515 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2519 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2524 database = decodedUri.value( u
"path"_s ).toString();
2525 if ( database.isEmpty() )
2527 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2532 database = databaseArgument;
2535 const QString table = values.at( 1 ).toString();
2536 const QString idColumn = values.at( 2 ).toString();
2537 const QString filterAttribute = values.at( 3 ).toString();
2538 const QVariant filterValue = values.at( 4 ).toString();
2539 const QVariantMap defaultValues = values.at( 5 ).toMap();
2545 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2548 functionResult = QVariant();
2552 QString errorMessage;
2553 QString currentValSql;
2555 qlonglong nextId = 0;
2556 bool cachedMode =
false;
2557 bool valueRetrieved =
false;
2559 QString cacheString = u
"%1:%2:%3:%4:%5"_s.arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2566 auto cachedCounter = counterCache.find( cacheString );
2568 if ( cachedCounter != counterCache.end() )
2570 qlonglong &cachedValue = cachedCounter.value();
2571 nextId = cachedValue;
2573 cachedValue = nextId;
2574 valueRetrieved =
true;
2579 if ( !cachedMode || !valueRetrieved )
2581 int result = SQLITE_ERROR;
2584 if ( !filterAttribute.isNull() )
2589 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2591 if ( result == SQLITE_OK )
2594 if ( sqliteStatement.
step() == SQLITE_ROW )
2600 if ( cachedMode && result == SQLITE_OK )
2602 counterCache.insert( cacheString, nextId );
2606 counterCache.remove( cacheString );
2609 valueRetrieved =
true;
2613 if ( valueRetrieved )
2622 if ( !filterAttribute.isNull() )
2628 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2631 vals << iter.value().toString();
2634 upsertSql +=
" ("_L1 + cols.join(
',' ) +
')';
2635 upsertSql +=
" VALUES "_L1;
2636 upsertSql +=
'(' + vals.join(
',' ) +
')';
2638 int result = SQLITE_ERROR;
2642 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2649 result = sqliteDb.
exec( upsertSql, errorMessage );
2651 if ( result == SQLITE_OK )
2653 functionResult = QVariant( nextId );
2658 parent->
setEvalErrorString( u
"Could not increment value: SQLite error: \"%1\" (%2)."_s.arg( errorMessage, QString::number( result ) ) );
2659 functionResult = QVariant();
2664 functionResult = QVariant();
2667 bool foundLayer =
false;
2668 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2670 fetchAndIncrementFunc( layer, QString() );
2674 const QString databasePath = values.at( 0 ).toString();
2677 fetchAndIncrementFunc(
nullptr, databasePath );
2681 return functionResult;
2694 QString definition = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2699 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to coordinate reference system" ).arg( definition ) );
2702 return QVariant::fromValue( crs );
2708 for (
const QVariant &value : values )
2711 concat += QgsExpressionUtils::getStringValue( value, parent );
2718 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2719 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2722static QVariant fcnUnaccent(
2723 const QVariantList &values,
2732 if ( values.isEmpty() || values[0].isNull() )
2741 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2742 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2743 return string.right( pos );
2748 if ( values.length() < 2 || values.length() > 3 )
2751 const QString input = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2752 const QString substring = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2754 bool overlapping =
false;
2755 if ( values.length() == 3 )
2757 overlapping = values.at( 2 ).toBool();
2760 if ( substring.isEmpty() )
2761 return QVariant( 0 );
2766 count = input.count( substring );
2771 while ( ( pos = input.indexOf( substring, pos ) ) != -1 )
2774 pos += substring.length();
2778 return QVariant( count );
2783 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2784 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2785 return string.left( pos );
2790 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2791 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2792 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2793 return string.leftJustified( length, fill.at( 0 ),
true );
2798 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2799 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2800 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2801 return string.rightJustified( length, fill.at( 0 ),
true );
2806 if ( values.size() < 1 )
2808 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2812 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2813 for (
int n = 1; n < values.length(); n++ )
2815 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2823 return QVariant( QDateTime::currentDateTime() );
2828 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2829 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2830 if ( format.isEmpty() && !language.isEmpty() )
2832 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2833 return QVariant( QDate() );
2836 if ( format.isEmpty() && language.isEmpty() )
2837 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2839 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2840 QLocale locale = QLocale();
2841 if ( !language.isEmpty() )
2843 locale = QLocale( language );
2846 QDate date = locale.toDate( datestring, format );
2847 if ( !date.isValid() )
2849 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2852 return QVariant( date );
2857 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2858 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2859 if ( format.isEmpty() && !language.isEmpty() )
2861 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2862 return QVariant( QTime() );
2865 if ( format.isEmpty() && language.isEmpty() )
2866 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2868 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2869 QLocale locale = QLocale();
2870 if ( !language.isEmpty() )
2872 locale = QLocale( language );
2875 QTime time = locale.toTime( timestring, format );
2876 if ( !time.isValid() )
2878 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2881 return QVariant( time );
2886 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2895 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2896 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2897 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2899 QString formatString;
2900 if ( values.count() > 3 )
2901 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2904 if ( formatString.compare(
"suffix"_L1, Qt::CaseInsensitive ) == 0 )
2908 else if ( formatString.compare(
"aligned"_L1, Qt::CaseInsensitive ) == 0 )
2912 else if ( ! formatString.isEmpty() )
2914 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2918 if ( axis.compare(
'x'_L1, Qt::CaseInsensitive ) == 0 )
2922 else if ( axis.compare(
'y'_L1, Qt::CaseInsensitive ) == 0 )
2928 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2936 return floatToDegreeFormat( format, values, context, parent, node );
2943 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2945 return ok ? QVariant( value ) : QVariant();
2951 return floatToDegreeFormat( format, values, context, parent, node );
2956 const double decimalDegrees = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2957 return static_cast< int >( decimalDegrees );
2962 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
2963 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
2964 return static_cast< int >( remainder * 60 );
2969 const double absoluteDecimalDegrees = std::abs( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
2970 const double remainder = absoluteDecimalDegrees -
static_cast<int>( absoluteDecimalDegrees );
2971 const double remainderInMinutes = remainder * 60;
2972 const double remainderSecondsFraction = remainderInMinutes -
static_cast< int >( remainderInMinutes );
2974 return remainderSecondsFraction * 60;
2979 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2980 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2981 qint64 seconds = d2.secsTo( d1 );
2982 return QVariant::fromValue(
QgsInterval( seconds ) );
2987 if ( !values.at( 0 ).canConvert<QDate>() )
2990 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2991 if ( !date.isValid() )
2996 return date.dayOfWeek() % 7;
3001 QVariant value = values.at( 0 );
3002 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3005 return QVariant( inter.
days() );
3009 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3010 return QVariant( d1.date().day() );
3016 QVariant value = values.at( 0 );
3017 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3020 return QVariant( inter.
years() );
3024 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3025 return QVariant( d1.date().year() );
3031 QVariant value = values.at( 0 );
3032 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3035 return QVariant( inter.
months() );
3039 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3040 return QVariant( d1.date().month() );
3046 QVariant value = values.at( 0 );
3047 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3050 return QVariant( inter.
weeks() );
3054 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
3055 return QVariant( d1.date().weekNumber() );
3061 QVariant value = values.at( 0 );
3062 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3065 return QVariant( inter.
hours() );
3069 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3070 return QVariant( t1.hour() );
3076 QVariant value = values.at( 0 );
3077 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3080 return QVariant( inter.
minutes() );
3084 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3085 return QVariant( t1.minute() );
3091 QVariant value = values.at( 0 );
3092 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
3095 return QVariant( inter.
seconds() );
3099 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
3100 return QVariant( t1.second() );
3106 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
3109 return QVariant( dt.toMSecsSinceEpoch() );
3119 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
3121 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
3126 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3129 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif"_L1 ) );
3132 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
3138 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
3141 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"exif_geotag"_L1 ) );
3150 if ( !dateTime.isValid() )
3155 const int year = dateTime.date().year();
3156 const QDateTime startOfYear( QDate( year, 1, 1 ), QTime( 0, 0, 0 ) );
3157 const QDateTime startOfNextYear( QDate( year + 1, 1, 1 ), QTime( 0, 0, 0 ) );
3158 const qint64 secondsFromStartOfYear = startOfYear.secsTo( dateTime );
3159 const qint64 totalSecondsInYear = startOfYear.secsTo( startOfNextYear );
3160 return static_cast<double>( year ) + (
static_cast<double>( secondsFromStartOfYear ) /
static_cast< double >( totalSecondsInYear ) );
3165 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3166 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3169 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination"_L1 ) );
3172 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3177 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3182 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3187 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3192 double declination = 0;
3199 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination: %1" ).arg( model.error() ) );
3211 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3212 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3215 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination"_L1 ) );
3218 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3223 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3228 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3233 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3238 double inclination = 0;
3245 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination: %1" ).arg( model.error() ) );
3257 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3258 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3261 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_declination_rate_of_change"_L1 ) );
3264 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3269 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3274 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3279 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3284 double declination = 0;
3292 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3302 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3308 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change" ) );
3314 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( model.error() ) );
3319 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic declination rate of change: %1" ).arg( e.
what() ) );
3326 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3327 const QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
3330 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a valid date" ).arg(
"magnetic_inclination_rate_of_change"_L1 ) );
3333 const double latitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3338 const double longitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3343 const double height = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3348 const QString filePath = QgsExpressionUtils::getFilePathValue( values.at( 5 ), context, parent );
3353 double declination = 0;
3361 if ( model.getComponentsWithTimeDerivatives(
qDateTimeToDecimalYear( dt ), latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt ) )
3371 if (
QgsMagneticModel::fieldComponentsWithTimeDerivatives( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It ) )
3377 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change" ) );
3383 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( model.error() ) );
3388 parent->
setEvalErrorString( QObject::tr(
"Cannot evaluate magnetic inclination rate of change: %1" ).arg( e.
what() ) );
3393#define ENSURE_GEOM_TYPE(f, g, geomtype) \
3394 if ( !(f).hasGeometry() ) \
3395 return QVariant(); \
3396 QgsGeometry g = (f).geometry(); \
3397 if ( (g).type() != (geomtype) ) \
3404 if ( g.isMultipart() )
3406 return g.asMultiPoint().at( 0 ).x();
3410 return g.asPoint().x();
3418 if ( g.isMultipart() )
3420 return g.asMultiPoint().at( 0 ).y();
3424 return g.asPoint().y();
3438 if ( g.isEmpty() || !abGeom->
is3D() )
3451 if ( collection->numGeometries() > 0 )
3464 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3470 return QVariant( isValid );
3475 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3479 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3480#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
3485 if ( methodString.compare(
"linework"_L1, Qt::CaseInsensitive ) == 0 )
3487 else if ( methodString.compare(
"structure"_L1, Qt::CaseInsensitive ) == 0 )
3490 const bool keepCollapsed = values.value( 2 ).toBool();
3495 valid = geom.
makeValid( method, keepCollapsed );
3499 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3503 return QVariant::fromValue( valid );
3508 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3514 for (
int i = 0; i < multiGeom.size(); ++i )
3516 array += QVariant::fromValue( multiGeom.at( i ) );
3524 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3536 QVariant result( centroid.
asPoint().
x() );
3542 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3554 QVariant result( centroid.
asPoint().
y() );
3560 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3578 if ( collection->numGeometries() == 1 )
3591 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3609 if ( collection->numGeometries() == 1 )
3622 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3627 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3654 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3671 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3688 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3693 bool ignoreClosing =
false;
3694 if ( values.length() > 1 )
3696 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3706 bool skipLast =
false;
3707 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3712 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3724 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3735 for (
int i = 0; i < line->numPoints() - 1; ++i )
3739 << line->pointN( i )
3740 << line->pointN( i + 1 ) );
3751 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3761 if ( collection->numGeometries() == 1 )
3768 if ( !curvePolygon )
3772 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3778 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3784 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3794 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3800 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3806 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3815 return QVariant::fromValue(
QgsGeometry( boundary ) );
3820 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3829 return QVariant::fromValue( merged );
3834 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3838 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3843 if ( sharedPaths.
isNull() )
3846 return QVariant::fromValue( sharedPaths );
3852 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3857 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3860 if ( simplified.
isNull() )
3868 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3873 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3878 if ( simplified.
isNull() )
3886 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3891 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3892 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3893 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3894 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3896 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3905 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3910 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3911 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3912 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3923 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3928 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3929 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3930 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3931 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3932 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3935 minAmplitude, maxAmplitude, seed );
3944 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3949 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3950 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3951 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3962 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3967 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3968 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3969 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3970 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3971 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3974 minAmplitude, maxAmplitude, seed );
3983 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3988 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3989 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3990 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4001 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4006 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4007 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4008 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4009 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4010 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
4013 minAmplitude, maxAmplitude, seed );
4022 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4027 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
4028 QVector< double > dashPattern;
4029 dashPattern.reserve( pattern.size() );
4030 for (
const QVariant &value : std::as_const( pattern ) )
4033 double v = value.toDouble( &ok );
4045 if ( dashPattern.size() % 2 != 0 )
4047 parent->
setEvalErrorString( u
"Dash pattern must contain an even number of elements"_s );
4051 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
4053 if ( startRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4055 else if ( startRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4057 else if ( startRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4059 else if ( startRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4061 else if ( startRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4065 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( startRuleString ) );
4069 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4071 if ( endRuleString.compare(
"no_rule"_L1, Qt::CaseInsensitive ) == 0 )
4073 else if ( endRuleString.compare(
"full_dash"_L1, Qt::CaseInsensitive ) == 0 )
4075 else if ( endRuleString.compare(
"half_dash"_L1, Qt::CaseInsensitive ) == 0 )
4077 else if ( endRuleString.compare(
"full_gap"_L1, Qt::CaseInsensitive ) == 0 )
4079 else if ( endRuleString.compare(
"half_gap"_L1, Qt::CaseInsensitive ) == 0 )
4083 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern rule"_s.arg( endRuleString ) );
4087 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4089 if ( adjustString.compare(
"both"_L1, Qt::CaseInsensitive ) == 0 )
4091 else if ( adjustString.compare(
"dash"_L1, Qt::CaseInsensitive ) == 0 )
4093 else if ( adjustString.compare(
"gap"_L1, Qt::CaseInsensitive ) == 0 )
4097 parent->
setEvalErrorString( u
"'%1' is not a valid dash pattern size adjustment"_s.arg( adjustString ) );
4101 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4112 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4117 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4119 if ( densified.
isNull() )
4127 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4132 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4134 if ( densified.
isNull() )
4143 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
4145 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
4152 QVector< QgsGeometry > parts;
4153 parts.reserve( list.size() );
4154 for (
const QVariant &value : std::as_const( list ) )
4156 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
4167 if ( values.count() < 2 || values.count() > 4 )
4169 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
4173 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4174 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4175 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
4176 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
4177 switch ( values.count() )
4191 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4192 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4193 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4199 if ( values.empty() )
4204 QVector<QgsPoint> points;
4205 points.reserve( values.count() );
4207 auto addPoint = [&points](
const QgsGeometry & geom )
4222 for (
const QVariant &value : values )
4224 if ( value.userType() == QMetaType::Type::QVariantList )
4226 const QVariantList list = value.toList();
4227 for (
const QVariant &v : list )
4229 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
4234 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
4238 if ( points.count() < 2 )
4246 if ( values.count() < 1 )
4248 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
4252 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4260 auto polygon = std::make_unique< QgsPolygon >();
4274 if ( !exteriorRing )
4277 polygon->setExteriorRing( exteriorRing->
segmentize() );
4280 for (
int i = 1; i < values.count(); ++i )
4282 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
4304 polygon->addInteriorRing( ring->
segmentize() );
4307 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
4312 auto tr = std::make_unique<QgsTriangle>();
4313 auto lineString = std::make_unique<QgsLineString>();
4314 lineString->clear();
4316 for (
const QVariant &value : values )
4318 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
4340 lineString->addVertex( *point );
4343 tr->setExteriorRing( lineString.release() );
4345 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
4350 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4357 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4358 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4380 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4385 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4392 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4393 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4394 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4395 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
4415 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
4416 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
4422 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4429 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4436 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4439 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4446 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4486 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4492 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4507 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4513 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4519 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4528 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4552 return QVariant::fromValue( geom.
vertexAt( idx ) );
4560 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4562 const QVariant v = pointAt( geom, idx, parent );
4565 return QVariant( v.value<
QgsPoint>().
x() );
4571 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4573 return fcnOldXat( values, f, parent, node );
4575 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4577 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4580 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4586 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4588 const QVariant v = pointAt( geom, vertexNumber, parent );
4590 return QVariant( v.value<
QgsPoint>().
x() );
4600 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4602 const QVariant v = pointAt( geom, idx, parent );
4605 return QVariant( v.value<
QgsPoint>().
y() );
4611 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4613 return fcnOldYat( values, f, parent, node );
4615 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4617 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4620 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4626 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4628 const QVariant v = pointAt( geom, vertexNumber, parent );
4630 return QVariant( v.value<
QgsPoint>().
y() );
4637 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4643 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4645 const QVariant v = pointAt( geom, vertexNumber, parent );
4647 return QVariant( v.value<
QgsPoint>().
z() );
4654 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4660 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4662 const QVariant v = pointAt( geom, vertexNumber, parent );
4664 return QVariant( v.value<
QgsPoint>().
m() );
4683 return QVariant::fromValue( geom );
4691 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4693 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4699 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4705 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4710 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4717 ogcContext.
layer = mapLayerPtr.data();
4722 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4737 return QVariant( area );
4741 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4753 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4758 return QVariant( geom.
area() );
4772 return QVariant( len );
4776 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4797 return QVariant( len );
4801 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4807 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4813 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4819 return QVariant( geom.
length() );
4824 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4830 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4839 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4848 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4864 if ( !curvePolygon )
4876 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4883 return QVariant( curvePolygon->
ringCount() );
4885 bool foundPoly =
false;
4894 if ( !curvePolygon )
4905 return QVariant( ringCount );
4910 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4912 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4918 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4924 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4930 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4939 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4945 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4951 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4957 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4963 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4971 double max = std::numeric_limits< double >::lowest();
4975 double z = ( *it ).z();
4981 if ( max == std::numeric_limits< double >::lowest() )
4984 return QVariant( max );
4989 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4997 double min = std::numeric_limits< double >::max();
5001 double z = ( *it ).z();
5007 if ( min == std::numeric_limits< double >::max() )
5010 return QVariant( min );
5015 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5023 double min = std::numeric_limits< double >::max();
5027 double m = ( *it ).m();
5033 if ( min == std::numeric_limits< double >::max() )
5036 return QVariant( min );
5041 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5049 double max = std::numeric_limits< double >::lowest();
5053 double m = ( *it ).m();
5059 if ( max == std::numeric_limits< double >::lowest() )
5062 return QVariant( max );
5067 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5071 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
5080 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5084 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
5093 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5098 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
5109 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5113 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
5115 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
5120 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5139 return QVariant::fromValue( curve->
isClosed() );
5144 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5157 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5158 closedLine->close();
5160 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
5174 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
5175 closedLine->close();
5177 closed->addGeometry( closedLine.release() );
5180 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
5188 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5192 return QVariant::fromValue( fGeom.
isEmpty() );
5198 return QVariant::fromValue(
true );
5200 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5201 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
5206 if ( values.length() < 2 || values.length() > 3 )
5209 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5210 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5217 if ( values.length() == 2 )
5220 QString result = engine->relate( sGeom.
constGet() );
5221 return QVariant::fromValue( result );
5226 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5227 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
5228 return QVariant::fromValue( result );
5234 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5235 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5240 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5241 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5242 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
5246 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5247 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5248 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
5252 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5253 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5254 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
5258 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5259 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5260 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
5264 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5265 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5266 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
5270 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5271 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5272 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
5276 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5277 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5278 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
5283 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5284 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5285 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5286 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
5287 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
5288 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5291 if ( endCapString.compare(
"flat"_L1, Qt::CaseInsensitive ) == 0 )
5293 else if ( endCapString.compare(
"square"_L1, Qt::CaseInsensitive ) == 0 )
5297 if ( joinString.compare(
"miter"_L1, Qt::CaseInsensitive ) == 0 )
5299 else if ( joinString.compare(
"bevel"_L1, Qt::CaseInsensitive ) == 0 )
5303 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5309 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5311 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5316 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5318 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5323 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5325 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
5330 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5345 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
5349 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5350 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5351 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5352 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5355 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5361 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5364 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
5368 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5369 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5370 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
5373 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5379 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5382 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
5386 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
5389 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5395 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5396 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5397 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5398 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5399 if ( joinInt < 1 || joinInt > 3 )
5403 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5406 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5412 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5413 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5414 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5416 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
5417 if ( joinInt < 1 || joinInt > 3 )
5421 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5424 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5430 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5431 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5432 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5435 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5441 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5442 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5443 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5445 return QVariant::fromValue( fGeom );
5450 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5451 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5452 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
5454 const bool perPart = values.value( 3 ).toBool();
5461 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.constGet()->clone() ) );
5462 for ( auto it = collection->parts_begin(); it != collection->parts_end(); ++it )
5464 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5465 QTransform t = QTransform::fromTranslate( partCenter.x(), partCenter.y() );
5466 t.rotate( -rotation );
5467 t.translate( -partCenter.x(), -partCenter.y() );
5468 ( *it )->transform( t );
5470 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5482 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5490 fGeom.
rotate( rotation, pt );
5491 return QVariant::fromValue( fGeom );
5497 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5498 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5499 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5500 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
5507 pt = fGeom.boundingBox().center();
5511 parent->setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5516 pt = center.asPoint();
5519 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5520 t.scale( xScale, yScale );
5521 t.translate( -pt.
x(), -pt.
y() );
5523 return QVariant::fromValue( fGeom );
5528 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5534 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5535 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5537 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5539 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5540 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5542 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5543 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5544 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5545 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5556 QTransform transform;
5557 transform.translate( deltaX, deltaY );
5558 transform.rotate( rotationZ );
5559 transform.scale( scaleX, scaleY );
5560 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5562 return QVariant::fromValue( fGeom );
5568 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5570 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5575 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5577 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5583 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5584 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5586 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5592 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5594 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5598#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5603 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5604 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5605 const bool allowHoles = values.value( 2 ).toBool();
5607 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5620 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5622 if ( values.length() == 2 )
5623 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5631 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5637 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5639 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5645 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5651 double area,
angle, width, height;
5664 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5665 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5667 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5678 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
5689 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5699 reversed->addGeometry( curve->
reversed() );
5706 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5712 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5713 std::reverse(
string.begin(),
string.end() );
5719 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5739 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5745 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5746 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5747 return QVariant( fGeom.
distance( sGeom ) );
5752 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5753 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5756 if ( values.length() == 3 && values.at( 2 ).isValid() )
5758 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5759 densify = std::clamp( densify, 0.0, 1.0 );
5767 return res > -1 ? QVariant( res ) : QVariant();
5772 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5773 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5775 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5780 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5781 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5783 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5788 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5789 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5791 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5797 if ( values.length() < 1 || values.length() > 2 )
5800 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5802 if ( values.length() == 2 )
5803 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5804 QString wkt = fGeom.
asWkt( prec );
5805 return QVariant( wkt );
5810 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5811 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5816 if ( values.length() != 2 )
5818 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5822 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5823 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5851 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5858 if ( pt1->
y() < pt2->
y() )
5860 else if ( pt1->
y() > pt2->
y() )
5868 if ( pt1->
x() < pt2->
x() )
5870 else if ( pt1->
x() > pt2->
x() )
5871 return M_PI + ( M_PI_2 );
5876 if ( pt1->
x() < pt2->
x() )
5878 if ( pt1->
y() < pt2->
y() )
5880 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
5884 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5891 if ( pt1->
y() > pt2->
y() )
5893 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5898 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5899 + ( M_PI + ( M_PI_2 ) );
5906 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5907 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5909 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
5913 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
5921 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
5935 if ( ellipsoid.isEmpty() )
5937 ellipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
5943 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
5951 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
5957 const double bearing = da.
bearing( point1, point2 );
5958 if ( std::isfinite( bearing ) )
5960 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
5973 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5981 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5982 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5983 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5986 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
5993 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5994 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6022 parent->
setEvalErrorString( u
"Function 'inclination' requires two points as arguments."_s );
6032 if ( values.length() != 3 )
6035 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6036 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6037 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6041 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
6047 if ( values.length() < 2 )
6050 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6053 return values.at( 0 );
6055 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6056 QVariant cachedExpression;
6061 if ( cachedExpression.isValid() )
6068 bool asc = values.value( 2 ).toBool();
6086 Q_ASSERT( collection );
6090 QgsExpressionSorter sorter( orderBy );
6092 QList<QgsFeature> partFeatures;
6093 partFeatures.reserve( collection->
partCount() );
6094 for (
int i = 0; i < collection->
partCount(); ++i )
6100 sorter.sortFeatures( partFeatures, unconstedContext );
6104 Q_ASSERT( orderedGeom );
6109 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
6114 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
6117 delete unconstedContext;
6124 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6125 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6129 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6135 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6136 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6140 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6146 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6147 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6151 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
6157 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6158 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6159 const bool use3DDistance = values.at( 2 ).toBool();
6161 double x, y, z, distance;
6184 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6187 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
6207 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6208 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6210 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
6212 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
6217 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6218 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6225 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6226 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6231 vertex = count + vertex;
6239 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6240 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6245 vertex = count + vertex;
6253 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6254 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
6258 return distance >= 0 ? distance : QVariant();
6263 const QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6264 const double m = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6265 const bool use3DDistance = values.at( 2 ).toBool();
6267 double x, y, z, distance;
6276 return found ? distance : QVariant();
6281 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
6283 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6284 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6287 if ( values.length() >= 1 )
6289 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6290 return QVariant( qlonglong( std::round( number ) ) );
6305 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
6306 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6307 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6314 const bool omitGroupSeparator = values.value( 3 ).toBool();
6315 const bool trimTrailingZeros = values.value( 4 ).toBool();
6317 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6318 if ( !omitGroupSeparator )
6319 locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
6321 locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
6323 QString res = locale.toString( value,
'f', places );
6325 if ( trimTrailingZeros )
6327 const QChar decimal = locale.decimalPoint().at( 0 );
6328 const QChar zeroDigit = locale.zeroDigit().at( 0 );
6330 if ( res.contains( decimal ) )
6332 int trimPoint = res.length() - 1;
6334 while ( res.at( trimPoint ) == zeroDigit )
6337 if ( res.at( trimPoint ) == decimal )
6340 res.truncate( trimPoint + 1 );
6349 QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
6350 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6351 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6354 if ( format.indexOf(
"Z" ) > 0 )
6355 datetime = datetime.toUTC();
6357 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
6358 return locale.toString( datetime, format );
6363 const QVariant variant = values.at( 0 );
6365 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6366 if ( !color.isValid() )
6369 const float alpha = color.alphaF();
6370 if ( color.spec() == QColor::Spec::Cmyk )
6372 const float avg = ( color.cyanF() + color.magentaF() + color.yellowF() ) / 3;
6373 color = QColor::fromCmykF( avg, avg, avg, color.blackF(), alpha );
6377 const float avg = ( color.redF() + color.greenF() + color.blueF() ) / 3;
6378 color.setRgbF( avg, avg, avg, alpha );
6381 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6388 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
6393 else if ( ratio < 0 )
6398 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
6399 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
6400 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
6401 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
6403 QColor newColor( red, green, blue, alpha );
6410 const QVariant variant1 = values.at( 0 );
6411 const QVariant variant2 = values.at( 1 );
6413 if ( variant1.userType() != variant2.userType() )
6415 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have the same type (string or color object)" ) );
6420 const QColor color1 = QgsExpressionUtils::getColorValue( variant1, parent, isQColor );
6421 if ( !color1.isValid() )
6424 const QColor color2 = QgsExpressionUtils::getColorValue( variant2, parent, isQColor );
6425 if ( !color2.isValid() )
6428 if ( ( color1.spec() == QColor::Cmyk ) != ( color2.spec() == QColor::Cmyk ) )
6430 parent->
setEvalErrorString( QObject::tr(
"Both color arguments must have compatible color type (CMYK or RGB/HSV/HSL)" ) );
6434 const float ratio =
static_cast<float>( std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0., 1. ) );
6440 const float alpha = color1.alphaF() * ( 1 - ratio ) + color2.alphaF() * ratio;
6441 if ( color1.spec() == QColor::Spec::Cmyk )
6443 float cyan = color1.cyanF() * ( 1 - ratio ) + color2.cyanF() * ratio;
6444 float magenta = color1.magentaF() * ( 1 - ratio ) + color2.magentaF() * ratio;
6445 float yellow = color1.yellowF() * ( 1 - ratio ) + color2.yellowF() * ratio;
6446 float black = color1.blackF() * ( 1 - ratio ) + color2.blackF() * ratio;
6447 newColor = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6451 float red = color1.redF() * ( 1 - ratio ) + color2.redF() * ratio;
6452 float green = color1.greenF() * ( 1 - ratio ) + color2.greenF() * ratio;
6453 float blue = color1.blueF() * ( 1 - ratio ) + color2.blueF() * ratio;
6454 newColor = QColor::fromRgbF( red, green, blue, alpha );
6459 return isQColor ? QVariant( newColor ) : QVariant(
QgsSymbolLayerUtils::encodeColor( newColor ) );
6464 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6465 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6466 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6467 QColor color = QColor( red, green, blue );
6468 if ( ! color.isValid() )
6470 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
6471 color = QColor( 0, 0, 0 );
6474 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6479 const float red = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6480 const float green = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6481 const float blue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6482 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6483 QColor color = QColor::fromRgbF( red, green, blue, alpha );
6484 if ( ! color.isValid() )
6486 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6495 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6496 QVariant value = node->
eval( parent, context );
6500 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6502 value = node->
eval( parent, context );
6510 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6512 QVariant value = node->
eval( parent, context );
6514 if ( value.toBool() )
6516 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6518 value = node->
eval( parent, context );
6523 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6525 value = node->
eval( parent, context );
6533 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
6534 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6535 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6536 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
6537 QColor color = QColor( red, green, blue, alpha );
6538 if ( ! color.isValid() )
6540 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
6541 color = QColor( 0, 0, 0 );
6550 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGradientColorRamp>() )
6552 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
6557 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6561 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
6566 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
6567 QColor color = ramp->
color( value );
6580 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6582 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6584 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6586 QColor color = QColor::fromHslF( hue, saturation, lightness );
6588 if ( ! color.isValid() )
6590 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
6591 color = QColor( 0, 0, 0 );
6594 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6600 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6602 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6604 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6606 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6608 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6609 if ( ! color.isValid() )
6611 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6612 color = QColor( 0, 0, 0 );
6619 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6620 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6621 float lightness = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6622 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6624 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
6625 if ( ! color.isValid() )
6627 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
6637 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6639 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6641 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6643 QColor color = QColor::fromHsvF( hue, saturation, value );
6645 if ( ! color.isValid() )
6647 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
6648 color = QColor( 0, 0, 0 );
6651 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6657 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
6659 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6661 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6663 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
6665 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6666 if ( ! color.isValid() )
6668 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6669 color = QColor( 0, 0, 0 );
6676 float hue = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6677 float saturation = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6678 float value = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6679 float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6680 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
6682 if ( ! color.isValid() )
6684 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
6693 const float cyan = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) ), 0.f, 1.f );
6694 const float magenta = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent ) ), 0.f, 1.f );
6695 const float yellow = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) ), 0.f, 1.f );
6696 const float black = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) ), 0.f, 1.f );
6697 const float alpha = std::clamp(
static_cast<float>( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ) ), 0.f, 1.f );
6699 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6700 if ( ! color.isValid() )
6702 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6712 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6714 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6716 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6718 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6720 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
6722 if ( ! color.isValid() )
6724 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
6725 color = QColor( 0, 0, 0 );
6728 return u
"%1,%2,%3"_s.arg( color.red() ).arg( color.green() ).arg( color.blue() );
6734 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
6736 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
6738 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
6740 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
6742 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
6744 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
6745 if ( ! color.isValid() )
6747 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
6748 color = QColor( 0, 0, 0 );
6755 const QVariant variant = values.at( 0 );
6757 const QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6758 if ( !color.isValid() )
6761 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6762 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6764 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6765 return color.green();
6766 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6767 return color.blue();
6768 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6769 return color.alpha();
6770 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6771 return static_cast< double >( color.hsvHueF() * 360 );
6772 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6773 return static_cast< double >( color.hsvSaturationF() * 100 );
6774 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6775 return static_cast< double >( color.valueF() * 100 );
6776 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6777 return static_cast< double >( color.hslHueF() * 360 );
6778 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6779 return static_cast< double >( color.hslSaturationF() * 100 );
6780 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6781 return static_cast< double >( color.lightnessF() * 100 );
6782 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6783 return static_cast< double >( color.cyanF() * 100 );
6784 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6785 return static_cast< double >( color.magentaF() * 100 );
6786 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6787 return static_cast< double >( color.yellowF() * 100 );
6788 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6789 return static_cast< double >( color.blackF() * 100 );
6791 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6797 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6800 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
6804 QList< QColor > colors;
6806 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6809 if ( !colors.last().isValid() )
6811 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
6815 double step = it.key().toDouble();
6816 if ( it == map.constBegin() )
6821 else if ( it == map.constEnd() )
6831 bool discrete = values.at( 1 ).toBool();
6833 if ( colors.empty() )
6836 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
6841 const QVariant variant = values.at( 0 );
6843 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6844 if ( !color.isValid() )
6847 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6848 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6849 if ( part.compare(
"red"_L1, Qt::CaseInsensitive ) == 0 )
6850 color.setRed( std::clamp( value, 0, 255 ) );
6851 else if ( part.compare(
"green"_L1, Qt::CaseInsensitive ) == 0 )
6852 color.setGreen( std::clamp( value, 0, 255 ) );
6853 else if ( part.compare(
"blue"_L1, Qt::CaseInsensitive ) == 0 )
6854 color.setBlue( std::clamp( value, 0, 255 ) );
6855 else if ( part.compare(
"alpha"_L1, Qt::CaseInsensitive ) == 0 )
6856 color.setAlpha( std::clamp( value, 0, 255 ) );
6857 else if ( part.compare(
"hue"_L1, Qt::CaseInsensitive ) == 0 )
6858 color.setHsv( std::clamp( value, 0, 359 ), color.hsvSaturation(), color.value(), color.alpha() );
6859 else if ( part.compare(
"saturation"_L1, Qt::CaseInsensitive ) == 0 )
6860 color.setHsvF( color.hsvHueF(), std::clamp( value, 0, 100 ) / 100.0, color.valueF(), color.alphaF() );
6861 else if ( part.compare(
"value"_L1, Qt::CaseInsensitive ) == 0 )
6862 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6863 else if ( part.compare(
"hsl_hue"_L1, Qt::CaseInsensitive ) == 0 )
6864 color.setHsl( std::clamp( value, 0, 359 ), color.hslSaturation(), color.lightness(), color.alpha() );
6865 else if ( part.compare(
"hsl_saturation"_L1, Qt::CaseInsensitive ) == 0 )
6866 color.setHslF( color.hslHueF(), std::clamp( value, 0, 100 ) / 100.0, color.lightnessF(), color.alphaF() );
6867 else if ( part.compare(
"lightness"_L1, Qt::CaseInsensitive ) == 0 )
6868 color.setHslF( color.hslHueF(), color.hslSaturationF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6869 else if ( part.compare(
"cyan"_L1, Qt::CaseInsensitive ) == 0 )
6870 color.setCmykF( std::clamp( value, 0, 100 ) / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
6871 else if ( part.compare(
"magenta"_L1, Qt::CaseInsensitive ) == 0 )
6872 color.setCmykF( color.cyanF(), std::clamp( value, 0, 100 ) / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
6873 else if ( part.compare(
"yellow"_L1, Qt::CaseInsensitive ) == 0 )
6874 color.setCmykF( color.cyanF(), color.magentaF(), std::clamp( value, 0, 100 ) / 100.0, color.blackF(), color.alphaF() );
6875 else if ( part.compare(
"black"_L1, Qt::CaseInsensitive ) == 0 )
6876 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), std::clamp( value, 0, 100 ) / 100.0, color.alphaF() );
6879 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
6882 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6887 const QVariant variant = values.at( 0 );
6889 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6890 if ( !color.isValid() )
6893 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6895 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6900 const QVariant variant = values.at( 0 );
6902 QColor color = QgsExpressionUtils::getColorValue( variant, parent, isQColor );
6903 if ( !color.isValid() )
6906 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
6908 return isQColor ? QVariant( color ) : QVariant(
QgsSymbolLayerUtils::encodeColor( color ) );
6913 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
6916 return QVariant::fromValue( geom );
6922 const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
6930 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
6935 return QVariant::fromValue( fGeom );
6938 return QVariant::fromValue( fGeom );
6947 return QVariant::fromValue( fGeom );
6960 bool foundLayer =
false;
6961 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
6964 if ( !featureSource || !foundLayer )
6969 const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
6982 result = QVariant::fromValue( fet );
6990 bool foundLayer =
false;
6991 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
6994 if ( !featureSource || !foundLayer )
6999 QString cacheValueKey;
7000 if ( values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7002 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7004 QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
7005 QString filterString;
7006 for ( ; i != attributeMap.constEnd(); ++i )
7008 if ( !filterString.isEmpty() )
7010 filterString.append(
" AND " );
7014 cacheValueKey = u
"getfeature:%1:%2"_s.arg( featureSource->id(), filterString );
7023 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7024 int attributeId = featureSource->fields().lookupField( attribute );
7025 if ( attributeId == -1 )
7030 const QVariant &attVal = values.at( 2 );
7032 cacheValueKey = u
"getfeature:%1:%2:%3"_s.arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
7055 res = QVariant::fromValue( fet );
7070 if ( !values.isEmpty() )
7073 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
7074 fieldName = col->
name();
7075 else if ( values.size() == 2 )
7076 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7079 QVariant value = values.at( 0 );
7084 if ( fieldIndex == -1 )
7086 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( u
"represent_value"_s, fieldName ) );
7092 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( u
"layer"_s ), context, parent );
7095 const QString cacheValueKey = u
"repvalfcnval:%1:%2:%3"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName, value.toString() );
7104 const QString
cacheKey = u
"repvalfcn:%1:%2"_s.arg( layer ? layer->id() : u
"[None]"_s, fieldName );
7122 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( u
"represent_value"_s, fieldName ) );
7130 const QVariant data = values.at( 0 );
7131 const QMimeDatabase db;
7132 return db.mimeTypeForData( data.toByteArray() ).name();
7137 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7139 bool foundLayer =
false;
7140 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [layerProperty](
QgsMapLayer * layer )-> QVariant
7146 if ( QString::compare( layerProperty, u
"name"_s, Qt::CaseInsensitive ) == 0 )
7147 return layer->name();
7148 else if ( QString::compare( layerProperty, u
"id"_s, Qt::CaseInsensitive ) == 0 )
7150 else if ( QString::compare( layerProperty, u
"title"_s, Qt::CaseInsensitive ) == 0 )
7151 return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->serverProperties()->title();
7152 else if ( QString::compare( layerProperty, u
"abstract"_s, Qt::CaseInsensitive ) == 0 )
7153 return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->serverProperties()->abstract();
7154 else if ( QString::compare( layerProperty, u
"keywords"_s, Qt::CaseInsensitive ) == 0 )
7156 QStringList keywords;
7157 const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
7158 for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
7160 keywords.append( it.value() );
7162 if ( !keywords.isEmpty() )
7164 return layer->serverProperties()->keywordList();
7166 else if ( QString::compare( layerProperty, u
"data_url"_s, Qt::CaseInsensitive ) == 0 )
7168 else if ( QString::compare( layerProperty, u
"attribution"_s, Qt::CaseInsensitive ) == 0 )
7170 return !layer->
metadata().
rights().isEmpty() ? QVariant( layer->
metadata().
rights() ) : QVariant( layer->serverProperties()->attribution() );
7172 else if ( QString::compare( layerProperty, u
"attribution_url"_s, Qt::CaseInsensitive ) == 0 )
7174 else if ( QString::compare( layerProperty, u
"source"_s, Qt::CaseInsensitive ) == 0 )
7176 else if ( QString::compare( layerProperty, u
"min_scale"_s, Qt::CaseInsensitive ) == 0 )
7178 else if ( QString::compare( layerProperty, u
"max_scale"_s, Qt::CaseInsensitive ) == 0 )
7180 else if ( QString::compare( layerProperty, u
"is_editable"_s, Qt::CaseInsensitive ) == 0 )
7182 else if ( QString::compare( layerProperty, u
"crs"_s, Qt::CaseInsensitive ) == 0 )
7184 else if ( QString::compare( layerProperty, u
"crs_definition"_s, Qt::CaseInsensitive ) == 0 )
7186 else if ( QString::compare( layerProperty, u
"crs_description"_s, Qt::CaseInsensitive ) == 0 )
7188 else if ( QString::compare( layerProperty, u
"crs_ellipsoid"_s, Qt::CaseInsensitive ) == 0 )
7190 else if ( QString::compare( layerProperty, u
"extent"_s, Qt::CaseInsensitive ) == 0 )
7193 QVariant result = QVariant::fromValue( extentGeom );
7196 else if ( QString::compare( layerProperty, u
"distance_units"_s, Qt::CaseInsensitive ) == 0 )
7198 else if ( QString::compare( layerProperty, u
"path"_s, Qt::CaseInsensitive ) == 0 )
7201 return decodedUri.value( u
"path"_s );
7203 else if ( QString::compare( layerProperty, u
"type"_s, Qt::CaseInsensitive ) == 0 )
7205 switch ( layer->
type() )
7208 return QCoreApplication::translate(
"expressions",
"Vector" );
7210 return QCoreApplication::translate(
"expressions",
"Raster" );
7212 return QCoreApplication::translate(
"expressions",
"Mesh" );
7214 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
7216 return QCoreApplication::translate(
"expressions",
"Plugin" );
7218 return QCoreApplication::translate(
"expressions",
"Annotation" );
7220 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
7222 return QCoreApplication::translate(
"expressions",
"Group" );
7224 return QCoreApplication::translate(
"expressions",
"Tiled Scene" );
7230 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
7233 if ( QString::compare( layerProperty, u
"storage_type"_s, Qt::CaseInsensitive ) == 0 )
7235 else if ( QString::compare( layerProperty, u
"geometry_type"_s, Qt::CaseInsensitive ) == 0 )
7237 else if ( QString::compare( layerProperty, u
"feature_count"_s, Qt::CaseInsensitive ) == 0 )
7253 const QString uriPart = values.at( 1 ).toString();
7255 bool foundLayer =
false;
7257 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, uriPart](
QgsMapLayer * layer )-> QVariant
7259 if ( !layer->dataProvider() )
7261 parent->setEvalErrorString( QObject::tr(
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
7267 if ( !uriPart.isNull() )
7269 return decodedUri.value( uriPart );
7279 parent->
setEvalErrorString( QObject::tr(
"Function `decode_uri` requires a valid layer." ) );
7290 const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7291 const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7293 bool foundLayer =
false;
7294 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, band, layerProperty](
QgsMapLayer * layer )-> QVariant
7296 QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
7300 if ( band < 1 || band > rl->bandCount() )
7302 parent->setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer" ).arg( band ) );
7308 if ( QString::compare( layerProperty, u
"avg"_s, Qt::CaseInsensitive ) == 0 )
7310 else if ( QString::compare( layerProperty, u
"stdev"_s, Qt::CaseInsensitive ) == 0 )
7312 else if ( QString::compare( layerProperty, u
"min"_s, Qt::CaseInsensitive ) == 0 )
7314 else if ( QString::compare( layerProperty, u
"max"_s, Qt::CaseInsensitive ) == 0 )
7316 else if ( QString::compare( layerProperty, u
"range"_s, Qt::CaseInsensitive ) == 0 )
7318 else if ( QString::compare( layerProperty, u
"sum"_s, Qt::CaseInsensitive ) == 0 )
7322 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
7350 parent->
setEvalErrorString( QObject::tr(
"Function `raster_statistic` requires a valid raster layer." ) );
7367 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7368 bool ascending = values.value( 1 ).toBool();
7369 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
7375 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
7380 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
7385 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
7390 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7391 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7393 for (
const auto &item : listB )
7395 if ( listA.contains( item ) )
7399 return QVariant( match == listB.count() );
7404 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
7409 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7410 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7411 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
7412 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
7413 return list.at( list.length() + pos );
7419 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7420 return list.value( 0 );
7425 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7426 return list.value( list.size() - 1 );
7431 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7432 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7437 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7438 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
7443 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7446 for (
const QVariant &item : list )
7448 switch ( item.userType() )
7450 case QMetaType::Int:
7451 case QMetaType::UInt:
7452 case QMetaType::LongLong:
7453 case QMetaType::ULongLong:
7454 case QMetaType::Float:
7455 case QMetaType::Double:
7456 total += item.toDouble();
7461 return i == 0 ? QVariant() : total / i;
7466 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7467 QVariantList numbers;
7468 for (
const auto &item : list )
7470 switch ( item.userType() )
7472 case QMetaType::Int:
7473 case QMetaType::UInt:
7474 case QMetaType::LongLong:
7475 case QMetaType::ULongLong:
7476 case QMetaType::Float:
7477 case QMetaType::Double:
7478 numbers.append( item );
7482 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
7483 const int count = numbers.count();
7488 else if ( count % 2 )
7490 return numbers.at( count / 2 );
7494 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
7500 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7503 for (
const QVariant &item : list )
7505 switch ( item.userType() )
7507 case QMetaType::Int:
7508 case QMetaType::UInt:
7509 case QMetaType::LongLong:
7510 case QMetaType::ULongLong:
7511 case QMetaType::Float:
7512 case QMetaType::Double:
7513 total += item.toDouble();
7518 return i == 0 ? QVariant() : total;
7521static QVariant convertToSameType(
const QVariant &value, QMetaType::Type type )
7523 QVariant result = value;
7524 ( void )result.convert(
static_cast<int>( type ) );
7530 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7531 QHash< QVariant, int > hash;
7532 for (
const auto &item : list )
7536 const QList< int > occurrences = hash.values();
7537 if ( occurrences.empty() )
7538 return QVariantList();
7540 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7542 const QString option = values.at( 1 ).toString();
7543 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7545 return convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7547 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7549 if ( hash.isEmpty() )
7552 return QVariant( hash.key( maxValue ) );
7554 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7556 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7558 else if ( option.compare(
"real_majority"_L1, Qt::CaseInsensitive ) == 0 )
7560 if ( maxValue * 2 <= list.size() )
7563 return QVariant( hash.key( maxValue ) );
7574 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7575 QHash< QVariant, int > hash;
7576 for (
const auto &item : list )
7580 const QList< int > occurrences = hash.values();
7581 if ( occurrences.empty() )
7582 return QVariantList();
7584 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
7586 const QString option = values.at( 1 ).toString();
7587 if ( option.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
7589 return convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7591 else if ( option.compare(
"any"_L1, Qt::CaseInsensitive ) == 0 )
7593 if ( hash.isEmpty() )
7596 return QVariant( hash.key( minValue ) );
7598 else if ( option.compare(
"median"_L1, Qt::CaseInsensitive ) == 0 )
7600 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) ), context, parent, node );
7602 else if ( option.compare(
"real_minority"_L1, Qt::CaseInsensitive ) == 0 )
7604 if ( hash.isEmpty() )
7608 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
7609 if ( maxValue * 2 > list.size() )
7610 hash.remove( hash.key( maxValue ) );
7612 return convertToSameType( hash.keys(),
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7623 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7624 list.append( values.at( 1 ) );
7625 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7630 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7631 list.prepend( values.at( 1 ) );
7632 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7637 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7638 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
7639 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7644 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7645 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7647 position = position + list.length();
7648 if ( position >= 0 && position < list.length() )
7649 list.removeAt( position );
7650 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7658 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7660 const QVariant toRemove = values.at( 1 );
7663 list.erase( std::remove_if( list.begin(), list.end(), [](
const QVariant & element )
7665 return QgsVariantUtils::isNull( element );
7670 list.removeAll( toRemove );
7672 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7677 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
7679 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
7681 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7682 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
7684 int index = list.indexOf( it.key() );
7685 while ( index >= 0 )
7687 list.replace( index, it.value() );
7688 index = list.indexOf( it.key() );
7692 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7694 else if ( values.count() == 3 )
7696 QVariantList before;
7698 bool isSingleReplacement =
false;
7700 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
7702 before = QVariantList() << values.at( 1 );
7706 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7709 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
7711 after = QVariantList() << values.at( 2 );
7712 isSingleReplacement =
true;
7716 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
7719 if ( !isSingleReplacement && before.length() != after.length() )
7721 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
7725 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7726 for (
int i = 0; i < before.length(); i++ )
7728 int index = list.indexOf( before.at( i ) );
7729 while ( index >= 0 )
7731 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
7732 index = list.indexOf( before.at( i ) );
7736 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7740 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
7747 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7748 QVariantList list_new;
7750 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
7752 while ( list.removeOne( cur ) )
7754 list_new.append( cur );
7758 list_new.append( list );
7760 return convertToSameType( list_new,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7766 for (
const QVariant &cur : values )
7768 list += QgsExpressionUtils::getListValue( cur, parent );
7770 return convertToSameType( list,
static_cast<QMetaType::Type
>( values.at( 0 ).userType() ) );
7775 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7776 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
7777 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
7778 int slice_length = 0;
7780 if ( start_pos < 0 )
7782 start_pos = list.length() + start_pos;
7786 slice_length = end_pos - start_pos + 1;
7790 slice_length = list.length() + end_pos - start_pos + 1;
7793 if ( slice_length < 0 )
7797 list = list.mid( start_pos, slice_length );
7803 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7804 std::reverse( list.begin(), list.end() );
7810 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7811 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
7812 for (
const QVariant &cur : array2 )
7814 if ( array1.contains( cur ) )
7815 return QVariant(
true );
7817 return QVariant(
false );
7822 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7824 QVariantList distinct;
7826 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7828 if ( !distinct.contains( *it ) )
7830 distinct += ( *it );
7839 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
7840 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7841 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7845 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7847 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
7848 if ( it != ( array.constEnd() - 1 ) )
7854 return QVariant( str );
7859 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7860 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7861 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
7863 QStringList list = str.split( delimiter );
7866 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
7868 array += ( !( *it ).isEmpty() ) ? *it : empty;
7876 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7877 QJsonDocument document = QJsonDocument::fromJson( str.toUtf8() );
7878 if ( document.isNull() )
7881 return document.toVariant();
7887 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
7888 return QString( document.toJson( QJsonDocument::Compact ) );
7893 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
7894 if ( str.isEmpty() )
7895 return QVariantMap();
7896 str = str.trimmed();
7903 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7910 for (
int i = 0; i + 1 < values.length(); i += 2 )
7912 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
7919 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7920 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
7921 QVariantMap resultMap;
7923 for (
auto it = map.cbegin(); it != map.cend(); it++ )
7925 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
7933 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
7938 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
7943 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7944 map.remove( values.at( 1 ).toString() );
7950 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
7951 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
7958 for (
const QVariant &cur : values )
7960 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
7961 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
7962 result.insert( it.key(), it.value() );
7969 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
7974 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
7979 const QString envVarName = values.at( 0 ).toString();
7980 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
7983 return QProcessEnvironment::systemEnvironment().value( envVarName );
7988 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
7991 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"base_file_name"_L1 ) );
7994 return QFileInfo( file ).completeBaseName();
7999 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8002 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_suffix"_L1 ) );
8005 return QFileInfo( file ).completeSuffix();
8010 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8013 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_exists"_L1 ) );
8016 return QFileInfo::exists( file );
8021 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8024 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_name"_L1 ) );
8027 return QFileInfo( file ).fileName();
8032 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8035 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_file"_L1 ) );
8038 return QFileInfo( file ).isFile();
8043 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8046 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"is_directory"_L1 ) );
8049 return QFileInfo( file ).isDir();
8054 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8057 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_path"_L1 ) );
8060 return QDir::toNativeSeparators( QFileInfo( file ).path() );
8065 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
8068 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg(
"file_size"_L1 ) );
8071 return QFileInfo( file ).size();
8074static QVariant fcnHash(
const QString &str,
const QCryptographicHash::Algorithm
algorithm )
8076 return QString( QCryptographicHash::hash( str.toUtf8(),
algorithm ).toHex() );
8082 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8083 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
8085 if ( method ==
"md4"_L1 )
8087 hash = fcnHash( str, QCryptographicHash::Md4 );
8089 else if ( method ==
"md5"_L1 )
8091 hash = fcnHash( str, QCryptographicHash::Md5 );
8093 else if ( method ==
"sha1"_L1 )
8095 hash = fcnHash( str, QCryptographicHash::Sha1 );
8097 else if ( method ==
"sha224"_L1 )
8099 hash = fcnHash( str, QCryptographicHash::Sha224 );
8101 else if ( method ==
"sha256"_L1 )
8103 hash = fcnHash( str, QCryptographicHash::Sha256 );
8105 else if ( method ==
"sha384"_L1 )
8107 hash = fcnHash( str, QCryptographicHash::Sha384 );
8109 else if ( method ==
"sha512"_L1 )
8111 hash = fcnHash( str, QCryptographicHash::Sha512 );
8113 else if ( method ==
"sha3_224"_L1 )
8115 hash = fcnHash( str, QCryptographicHash::Sha3_224 );
8117 else if ( method ==
"sha3_256"_L1 )
8119 hash = fcnHash( str, QCryptographicHash::Sha3_256 );
8121 else if ( method ==
"sha3_384"_L1 )
8123 hash = fcnHash( str, QCryptographicHash::Sha3_384 );
8125 else if ( method ==
"sha3_512"_L1 )
8127 hash = fcnHash( str, QCryptographicHash::Sha3_512 );
8129 else if ( method ==
"keccak_224"_L1 )
8131 hash = fcnHash( str, QCryptographicHash::Keccak_224 );
8133 else if ( method ==
"keccak_256"_L1 )
8135 hash = fcnHash( str, QCryptographicHash::Keccak_256 );
8137 else if ( method ==
"keccak_384"_L1 )
8139 hash = fcnHash( str, QCryptographicHash::Keccak_384 );
8141 else if ( method ==
"keccak_512"_L1 )
8143 hash = fcnHash( str, QCryptographicHash::Keccak_512 );
8147 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg( str ) );
8154 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
8159 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
8164 const QByteArray input = values.at( 0 ).toByteArray();
8165 return QVariant( QString( input.toBase64() ) );
8170 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
8172 for (
auto it = map.cbegin(); it != map.cend(); it++ )
8174 query.addQueryItem( it.key(), it.value().toString() );
8176 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
8181 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
8182 const QByteArray base64 = value.toLocal8Bit();
8183 const QByteArray decoded = QByteArray::fromBase64( base64 );
8184 return QVariant( decoded );
8189static 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 )
8194 parent->
setEvalErrorString( u
"This function was called without an expression context."_s );
8198 const QVariant sourceLayerRef = context->
variable( u
"layer"_s );
8201 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
8210 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
8213 const bool layerCanBeCached = node->
isStatic( parent, context );
8214 QVariant targetLayerValue = node->
eval( parent, context );
8218 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
8220 QString subExpString = node->dump();
8222 bool testOnly = ( subExpString ==
"NULL" );
8225 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
8229 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
8234 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
8236 QString filterString = node->dump();
8237 if ( filterString !=
"NULL" )
8239 request.setFilterExpression( filterString );
8243 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
8245 QVariant limitValue = node->eval( parent, context );
8247 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
8250 double max_distance = 0;
8251 if ( isNearestFunc )
8253 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
8255 QVariant distanceValue = node->eval( parent, context );
8257 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
8261 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
8263 QVariant cacheValue = node->eval( parent, context );
8265 bool cacheEnabled = cacheValue.toBool();
8271 double minOverlap { -1 };
8272 double minInscribedCircleRadius { -1 };
8273 bool returnDetails =
false;
8274 bool sortByMeasure =
false;
8275 bool sortAscending =
false;
8276 bool requireMeasures =
false;
8277 bool overlapOrRadiusFilter =
false;
8278 if ( isIntersectsFunc )
8281 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
8283 const QVariant minOverlapValue = node->eval( parent, context );
8285 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
8286 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
8288 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
8290 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
8291 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
8293 returnDetails = !testOnly && node->eval( parent, context ).toBool();
8294 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
8296 const QString sorting { node->eval( parent, context ).toString().toLower() };
8297 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
8298 sortAscending = sorting.startsWith(
"asc" );
8299 requireMeasures = sortByMeasure || returnDetails;
8300 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
8307 if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
8310 request.setDestinationCrs( sourceLayer->crs(), TransformContext );
8313 bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
8316 if ( bboxGrow != 0 )
8318 intDomain.
grow( bboxGrow );
8321 const QString cacheBase { u
"%1:%2:%3"_s.arg( targetLayer->id(), subExpString, filterString ) };
8327 QList<QgsFeature> features;
8328 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
8332 const QString cacheLayer { u
"ovrlaylyr:%1"_s.arg( cacheBase ) };
8333 const QString cacheIndex { u
"ovrlayidx:%1"_s.arg( cacheBase ) };
8337 cachedTarget = targetLayer->
materialize( request );
8338 if ( layerCanBeCached )
8339 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
8349 if ( layerCanBeCached )
8350 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
8357 QList<QgsFeatureId> fidsList;
8358 if ( isNearestFunc )
8360 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
8364 fidsList = spatialIndex.
intersects( intDomain );
8367 QListIterator<QgsFeatureId> i( fidsList );
8368 while ( i.hasNext() )
8371 if ( sameLayers && feat.
id() == fId2 )
8373 features.append( cachedTarget->
getFeature( fId2 ) );
8381 request.setFilterRect( intDomain );
8386 if ( sameLayers && feat.
id() == feat2.
id() )
8388 features.append( feat2 );
8396 const QString expCacheKey { u
"exp:%1"_s.arg( cacheBase ) };
8397 const QString ctxCacheKey { u
"ctx:%1"_s.arg( cacheBase ) };
8403 subExpression.
prepare( &subContext );
8416 auto testLinestring = [minOverlap, requireMeasures](
const QgsGeometry intersection,
double & overlapValue ) ->
bool
8418 bool testResult {
false };
8420 QVector<double> overlapValues;
8421 const QgsGeometry merged { intersection.mergeLines() };
8426 if ( minOverlap != -1 || requireMeasures )
8428 overlapValue = geom->
length();
8429 overlapValues.append( overlapValue );
8430 if ( minOverlap != -1 )
8432 if ( overlapValue >= minOverlap )
8444 if ( ! overlapValues.isEmpty() )
8446 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8453 auto testPolygon = [minOverlap, requireMeasures, minInscribedCircleRadius](
const QgsGeometry intersection,
double & radiusValue,
double & overlapValue ) ->
bool
8456 bool testResult {
false };
8458 QVector<double> overlapValues;
8459 QVector<double> radiusValues;
8460 for (
auto it = intersection.const_parts_begin(); ( ! testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
8464 if ( minOverlap != -1 || requireMeasures )
8466 overlapValue = geom->
area();
8467 overlapValues.append( geom->
area() );
8468 if ( minOverlap != - 1 )
8470 if ( overlapValue >= minOverlap )
8482 if ( minInscribedCircleRadius != -1 || requireMeasures )
8485 const double width = bbox.
width();
8486 const double height = bbox.
height();
8487 const double size = width > height ? width : height;
8488 const double tolerance = size / 100.0;
8490 testResult = radiusValue >= minInscribedCircleRadius;
8491 radiusValues.append( radiusValues );
8496 if ( !radiusValues.isEmpty() )
8498 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
8501 if ( ! overlapValues.isEmpty() )
8503 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
8513 QVariantList results;
8515 QListIterator<QgsFeature> i( features );
8516 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
8522 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
8525 double overlapValue = -1;
8526 double radiusValue = -1;
8528 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
8541 for (
const auto &geom : std::as_const( geometries ) )
8543 switch ( geom.type() )
8547 poly.append( geom.asPolygon() );
8552 line.append( geom.asPolyline() );
8557 point.append( geom.asPoint() );
8568 switch ( geometry.
type() )
8596 switch ( intersection.
type() )
8603 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
8605 if ( ! testResult && overlapOrRadiusFilter )
8618 if ( minInscribedCircleRadius != -1 )
8624 const bool testResult { testLinestring( intersection, overlapValue ) };
8626 if ( ! testResult && overlapOrRadiusFilter )
8639 if ( minInscribedCircleRadius != -1 )
8644 bool testResult {
false };
8645 if ( minOverlap != -1 || requireMeasures )
8665 testResult = testLinestring( feat2.
geometry(), overlapValue );
8670 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
8676 if ( ! testResult && overlapOrRadiusFilter )
8704 const QVariant expResult = subExpression.
evaluate( &subContext );
8706 if ( requireMeasures )
8708 QVariantMap resultRecord;
8709 resultRecord.insert( u
"id"_s, feat2.
id() );
8710 resultRecord.insert( u
"result"_s, expResult );
8712 resultRecord.insert( u
"overlap"_s, overlapValue );
8714 if ( radiusValue != -1 )
8716 resultRecord.insert( u
"radius"_s, radiusValue );
8718 results.append( resultRecord );
8722 results.append( expResult );
8728 results.append( feat2.
id() );
8742 if ( requireMeasures )
8744 if ( sortByMeasure )
8746 std::sort( results.begin(), results.end(), [ sortAscending ](
const QVariant & recordA,
const QVariant & recordB ) ->
bool
8748 return sortAscending ?
8749 recordB.toMap().value( u
"overlap"_s ).toDouble() > recordA.toMap().value( u
"overlap"_s ).toDouble()
8750 : recordA.toMap().value( u
"overlap"_s ).toDouble() > recordB.toMap().value( u
"overlap"_s ).toDouble();
8754 if ( limit > 0 && results.size() > limit )
8756 results.erase( results.begin() + limit );
8759 if ( ! returnDetails )
8761 QVariantList expResults;
8762 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
8764 expResults.append( it->toMap().value( u
"result"_s ) );
8774 QVariantList disjoint_results;
8783 if ( !results.contains( feat2.
id() ) )
8786 disjoint_results.append( subExpression.
evaluate( &subContext ) );
8789 return disjoint_results;
8832 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
8841 QMutexLocker locker( &sFunctionsMutex );
8843 QList<QgsExpressionFunction *> &functions = *sFunctions();
8845 if ( functions.isEmpty() )
8848 << QgsExpressionFunction::Parameter( u
"expression"_s )
8849 << QgsExpressionFunction::Parameter( u
"group_by"_s,
true )
8850 << QgsExpressionFunction::Parameter( u
"filter"_s,
true );
8853 aggParamsConcat << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
8854 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
8857 aggParamsArray << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true );
8863 <<
new QgsStaticExpressionFunction( u
"azimuth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnAzimuth, u
"GeometryGroup"_s )
8864 <<
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 )
8865 <<
new QgsStaticExpressionFunction( u
"inclination"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"point_a"_s ) << QgsExpressionFunction::Parameter( u
"point_b"_s ), fcnInclination, u
"GeometryGroup"_s )
8866 <<
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 )
8874 <<
new QgsStaticExpressionFunction( u
"atan2"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"dx"_s ) << QgsExpressionFunction::Parameter( u
"dy"_s ), fcnAtan2, u
"Math"_s )
8878 <<
new QgsStaticExpressionFunction( u
"log"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"base"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnLog, u
"Math"_s )
8879 <<
new QgsStaticExpressionFunction( u
"round"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value"_s ) << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 ), fcnRound, u
"Math"_s );
8881 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 );
8883 functions << randFunc;
8885 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 );
8887 functions << randfFunc;
8890 <<
new QgsStaticExpressionFunction( u
"max"_s, -1, fcnMax, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8891 <<
new QgsStaticExpressionFunction( u
"min"_s, -1, fcnMin, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8892 <<
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 )
8893 <<
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 )
8894 <<
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 )
8895 <<
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 )
8898 <<
new QgsStaticExpressionFunction( u
"pi"_s, 0, fcnPi, u
"Math"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$pi"_s )
8899 <<
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 )
8900 <<
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 )
8901 <<
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 )
8902 <<
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 )
8903 <<
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 )
8904 <<
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 )
8905 <<
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 )
8906 <<
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 )
8907 <<
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 )
8908 <<
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 )
8909 <<
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 )
8910 <<
new QgsStaticExpressionFunction( u
"extract_degrees"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractDegrees, u
"Conversions"_s )
8911 <<
new QgsStaticExpressionFunction( u
"extract_minutes"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractMinutes, u
"Conversions"_s )
8912 <<
new QgsStaticExpressionFunction( u
"extract_seconds"_s, { QgsExpressionFunction::Parameter{ u
"value"_s } }, fcnExtractSeconds, u
"Conversions"_s )
8913 <<
new QgsStaticExpressionFunction( u
"coalesce"_s, -1, fcnCoalesce, u
"Conditionals"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8914 <<
new QgsStaticExpressionFunction( u
"nullif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"value1"_s ) << QgsExpressionFunction::Parameter( u
"value2"_s ), fcnNullIf, u
"Conditionals"_s )
8915 <<
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 )
8916 <<
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 )
8918 <<
new QgsStaticExpressionFunction( u
"aggregate"_s,
8920 << QgsExpressionFunction::Parameter( u
"layer"_s )
8921 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
8922 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
8923 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
8924 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
8925 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
8936 if ( !node->
args() )
8939 QSet<QString> referencedVars;
8942 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
8948 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
8951 return referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() );
8960 if ( !node->
args() )
8961 return QSet<QString>();
8963 QSet<QString> referencedCols;
8964 QSet<QString> referencedVars;
8968 QgsExpressionNode *subExpressionNode = node->
args()->
at( 2 );
8974 QgsExpressionNode *filterNode = node->
args()->
at( 3 );
8979 if ( referencedVars.contains( u
"parent"_s ) || referencedVars.contains( QString() ) )
8982 return referencedCols;
8988 << QgsExpressionFunction::Parameter( u
"relation"_s )
8989 << QgsExpressionFunction::Parameter( u
"aggregate"_s )
8990 << QgsExpressionFunction::Parameter( u
"expression"_s,
false, QVariant(),
true )
8991 << QgsExpressionFunction::Parameter( u
"concatenator"_s,
true )
8992 << QgsExpressionFunction::Parameter( u
"order_by"_s,
true, QVariant(),
true ),
8995 <<
new QgsStaticExpressionFunction( u
"count"_s, aggParams, fcnAggregateCount, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
8996 <<
new QgsStaticExpressionFunction( u
"count_distinct"_s, aggParams, fcnAggregateCountDistinct, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
8997 <<
new QgsStaticExpressionFunction( u
"count_missing"_s, aggParams, fcnAggregateCountMissing, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
8998 <<
new QgsStaticExpressionFunction( u
"minimum"_s, aggParams, fcnAggregateMin, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
8999 <<
new QgsStaticExpressionFunction( u
"maximum"_s, aggParams, fcnAggregateMax, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9000 <<
new QgsStaticExpressionFunction( u
"sum"_s, aggParams, fcnAggregateSum, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9001 <<
new QgsStaticExpressionFunction( u
"mean"_s, aggParams, fcnAggregateMean, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9002 <<
new QgsStaticExpressionFunction( u
"median"_s, aggParams, fcnAggregateMedian, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9003 <<
new QgsStaticExpressionFunction( u
"stdev"_s, aggParams, fcnAggregateStdev, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9004 <<
new QgsStaticExpressionFunction( u
"range"_s, aggParams, fcnAggregateRange, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9005 <<
new QgsStaticExpressionFunction( u
"minority"_s, aggParams, fcnAggregateMinority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9006 <<
new QgsStaticExpressionFunction( u
"majority"_s, aggParams, fcnAggregateMajority, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9007 <<
new QgsStaticExpressionFunction( u
"q1"_s, aggParams, fcnAggregateQ1, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9008 <<
new QgsStaticExpressionFunction( u
"q3"_s, aggParams, fcnAggregateQ3, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9009 <<
new QgsStaticExpressionFunction( u
"iqr"_s, aggParams, fcnAggregateIQR, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9010 <<
new QgsStaticExpressionFunction( u
"min_length"_s, aggParams, fcnAggregateMinLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9011 <<
new QgsStaticExpressionFunction( u
"max_length"_s, aggParams, fcnAggregateMaxLength, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9012 <<
new QgsStaticExpressionFunction( u
"collect"_s, aggParams, fcnAggregateCollectGeometry, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9013 <<
new QgsStaticExpressionFunction( u
"concatenate"_s, aggParamsConcat, fcnAggregateStringConcat, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9014 <<
new QgsStaticExpressionFunction( u
"concatenate_unique"_s, aggParamsConcat, fcnAggregateStringConcatUnique, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9015 <<
new QgsStaticExpressionFunction( u
"array_agg"_s, aggParamsArray, fcnAggregateArray, u
"Aggregates"_s, QString(),
false, QSet<QString>(),
true )
9017 <<
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 )
9018 <<
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 )
9020 <<
new QgsStaticExpressionFunction( u
"now"_s, 0, fcnNow, u
"Date and Time"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"$now"_s )
9022 << QgsExpressionFunction::Parameter( u
"datetime2"_s ),
9023 fcnAge, u
"Date and Time"_s )
9032 <<
new QgsStaticExpressionFunction( u
"datetime_from_epoch"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"long"_s ), fcnDateTimeFromEpoch, u
"Date and Time"_s )
9033 <<
new QgsStaticExpressionFunction( u
"day_of_week"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"date"_s ), fcnDayOfWeek, u
"Date and Time"_s )
9035 << QgsExpressionFunction::Parameter( u
"month"_s )
9036 << QgsExpressionFunction::Parameter( u
"day"_s ),
9037 fcnMakeDate, u
"Date and Time"_s )
9039 << QgsExpressionFunction::Parameter( u
"minute"_s )
9040 << QgsExpressionFunction::Parameter( u
"second"_s ),
9041 fcnMakeTime, u
"Date and Time"_s )
9043 << QgsExpressionFunction::Parameter( u
"month"_s )
9044 << QgsExpressionFunction::Parameter( u
"day"_s )
9045 << QgsExpressionFunction::Parameter( u
"hour"_s )
9046 << QgsExpressionFunction::Parameter( u
"minute"_s )
9047 << QgsExpressionFunction::Parameter( u
"second"_s ),
9048 fcnMakeDateTime, u
"Date and Time"_s )
9050 << QgsExpressionFunction::Parameter( u
"months"_s,
true, 0 )
9051 << QgsExpressionFunction::Parameter( u
"weeks"_s,
true, 0 )
9052 << QgsExpressionFunction::Parameter( u
"days"_s,
true, 0 )
9053 << QgsExpressionFunction::Parameter( u
"hours"_s,
true, 0 )
9054 << QgsExpressionFunction::Parameter( u
"minutes"_s,
true, 0 )
9055 << QgsExpressionFunction::Parameter( u
"seconds"_s,
true, 0 ),
9056 fcnMakeInterval, u
"Date and Time"_s )
9057 <<
new QgsStaticExpressionFunction( u
"timezone_from_id"_s, { QgsExpressionFunction::Parameter( u
"id"_s ) }, fcnTimeZoneFromId, u
"Date and Time"_s )
9058 <<
new QgsStaticExpressionFunction( u
"timezone_id"_s, { QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnTimeZoneToId, u
"Date and Time"_s )
9059 <<
new QgsStaticExpressionFunction( u
"get_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ) }, fcnGetTimeZone, u
"Date and Time"_s )
9060 <<
new QgsStaticExpressionFunction( u
"set_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnSetTimeZone, u
"Date and Time"_s )
9061 <<
new QgsStaticExpressionFunction( u
"convert_timezone"_s, { QgsExpressionFunction::Parameter( u
"datetime"_s ), QgsExpressionFunction::Parameter( u
"timezone"_s ) }, fcnConvertTimeZone, u
"Date and Time"_s )
9064 << QgsExpressionFunction::Parameter( u
"string"_s )
9065 << QgsExpressionFunction::Parameter( u
"substring"_s )
9066 << QgsExpressionFunction::Parameter( u
"overlapping"_s,
true,
false ),
9072 <<
new QgsStaticExpressionFunction( u
"unaccent"_s, { QgsExpressionFunction::Parameter( u
"string"_s ) }, fcnUnaccent, u
"String"_s )
9074 << QgsExpressionFunction::Parameter( u
"string"_s )
9075 << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnLTrim, u
"String"_s )
9077 << QgsExpressionFunction::Parameter( u
"string"_s )
9078 << QgsExpressionFunction::Parameter( u
"characters"_s,
true, u
" "_s ), fcnRTrim, u
"String"_s )
9079 <<
new QgsStaticExpressionFunction( u
"levenshtein"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLevenshtein, u
"Fuzzy Matching"_s )
9080 <<
new QgsStaticExpressionFunction( u
"longest_common_substring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnLCS, u
"Fuzzy Matching"_s )
9081 <<
new QgsStaticExpressionFunction( u
"hamming_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string1"_s ) << QgsExpressionFunction::Parameter( u
"string2"_s ), fcnHamming, u
"Fuzzy Matching"_s )
9085 <<
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 )
9086 <<
new QgsStaticExpressionFunction( u
"length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"text"_s,
true,
"" ), fcnLength, QStringList() << u
"String"_s << u
"GeometryGroup"_s )
9087 <<
new QgsStaticExpressionFunction( u
"length3D"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLength3D, u
"GeometryGroup"_s )
9088 <<
new QgsStaticExpressionFunction( u
"repeat"_s, { QgsExpressionFunction::Parameter( u
"text"_s ), QgsExpressionFunction::Parameter( u
"number"_s )}, fcnRepeat, u
"String"_s )
9089 <<
new QgsStaticExpressionFunction( u
"replace"_s, -1, fcnReplace, u
"String"_s )
9090 <<
new QgsStaticExpressionFunction( u
"regexp_replace"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s )
9091 << QgsExpressionFunction::Parameter( u
"replacement"_s ), fcnRegexpReplace, u
"String"_s )
9092 <<
new QgsStaticExpressionFunction( u
"regexp_substr"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"input_string"_s ) << QgsExpressionFunction::Parameter( u
"regex"_s ), fcnRegexpSubstr, u
"String"_s )
9093 <<
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(),
9094 false, QSet< QString >(),
false, QStringList(),
true )
9095 <<
new QgsStaticExpressionFunction( u
"concat"_s, -1, fcnConcat, u
"String"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
9096 <<
new QgsStaticExpressionFunction( u
"strpos"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"haystack"_s ) << QgsExpressionFunction::Parameter( u
"needle"_s ), fcnStrpos, u
"String"_s )
9097 <<
new QgsStaticExpressionFunction( u
"left"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnLeft, u
"String"_s )
9098 <<
new QgsStaticExpressionFunction( u
"right"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"length"_s ), fcnRight, u
"String"_s )
9099 <<
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 )
9100 <<
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 )
9101 <<
new QgsStaticExpressionFunction( u
"format"_s, -1, fcnFormatString, u
"String"_s )
9103 << QgsExpressionFunction::Parameter( u
"number"_s )
9104 << QgsExpressionFunction::Parameter( u
"places"_s,
true, 0 )
9105 << QgsExpressionFunction::Parameter( u
"language"_s,
true, QVariant() )
9106 << QgsExpressionFunction::Parameter( u
"omit_group_separators"_s,
true,
false )
9107 << QgsExpressionFunction::Parameter( u
"trim_trailing_zeroes"_s,
true,
false ), fcnFormatNumber, u
"String"_s )
9108 <<
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 )
9109 <<
new QgsStaticExpressionFunction( u
"color_grayscale_average"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"color"_s ), fcnColorGrayscaleAverage, u
"Color"_s )
9111 << QgsExpressionFunction::Parameter( u
"color2"_s )
9112 << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9113 fcnColorMixRgb, u
"Color"_s )
9115 << QgsExpressionFunction::Parameter( u
"color2"_s )
9116 << QgsExpressionFunction::Parameter( u
"ratio"_s ),
9117 fcnColorMix, u
"Color"_s )
9119 << QgsExpressionFunction::Parameter( u
"green"_s )
9120 << QgsExpressionFunction::Parameter( u
"blue"_s ),
9121 fcnColorRgb, u
"Color"_s )
9123 << QgsExpressionFunction::Parameter( u
"green"_s )
9124 << QgsExpressionFunction::Parameter( u
"blue"_s )
9125 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9126 fcnColorRgbF, u
"Color"_s )
9128 << QgsExpressionFunction::Parameter( u
"green"_s )
9129 << QgsExpressionFunction::Parameter( u
"blue"_s )
9130 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9131 fncColorRgba, u
"Color"_s )
9133 << QgsExpressionFunction::Parameter( u
"value"_s ),
9136 << QgsExpressionFunction::Parameter( u
"value"_s ),
9139 << QgsExpressionFunction::Parameter( u
"discrete"_s,
true,
false ),
9140 fcnCreateRamp, u
"Color"_s )
9142 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9143 << QgsExpressionFunction::Parameter( u
"lightness"_s ),
9144 fcnColorHsl, u
"Color"_s )
9146 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9147 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9148 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9149 fncColorHsla, u
"Color"_s )
9151 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9152 << QgsExpressionFunction::Parameter( u
"lightness"_s )
9153 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9154 fcnColorHslF, u
"Color"_s )
9156 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9157 << QgsExpressionFunction::Parameter( u
"value"_s ),
9158 fcnColorHsv, u
"Color"_s )
9160 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9161 << QgsExpressionFunction::Parameter( u
"value"_s )
9162 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9163 fncColorHsva, u
"Color"_s )
9165 << QgsExpressionFunction::Parameter( u
"saturation"_s )
9166 << QgsExpressionFunction::Parameter( u
"value"_s )
9167 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9168 fcnColorHsvF, u
"Color"_s )
9170 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9171 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9172 << QgsExpressionFunction::Parameter( u
"black"_s ),
9173 fcnColorCmyk, u
"Color"_s )
9175 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9176 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9177 << QgsExpressionFunction::Parameter( u
"black"_s )
9178 << QgsExpressionFunction::Parameter( u
"alpha"_s ),
9179 fncColorCmyka, u
"Color"_s )
9181 << QgsExpressionFunction::Parameter( u
"magenta"_s )
9182 << QgsExpressionFunction::Parameter( u
"yellow"_s )
9183 << QgsExpressionFunction::Parameter( u
"black"_s )
9184 << QgsExpressionFunction::Parameter( u
"alpha"_s,
true, 1. ),
9185 fcnColorCmykF, u
"Color"_s )
9187 << QgsExpressionFunction::Parameter( u
"component"_s ),
9188 fncColorPart, u
"Color"_s )
9190 << QgsExpressionFunction::Parameter( u
"factor"_s ),
9191 fncDarker, u
"Color"_s )
9193 << QgsExpressionFunction::Parameter( u
"factor"_s ),
9194 fncLighter, u
"Color"_s )
9195 <<
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 )
9199 fcnBaseFileName, u
"Files and Paths"_s )
9201 fcnFileSuffix, u
"Files and Paths"_s )
9203 fcnFileExists, u
"Files and Paths"_s )
9205 fcnFileName, u
"Files and Paths"_s )
9207 fcnPathIsFile, u
"Files and Paths"_s )
9209 fcnPathIsDir, u
"Files and Paths"_s )
9211 fcnFilePath, u
"Files and Paths"_s )
9213 fcnFileSize, u
"Files and Paths"_s )
9215 <<
new QgsStaticExpressionFunction( u
"exif"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"path"_s ) << QgsExpressionFunction::Parameter( u
"tag"_s,
true ),
9216 fcnExif, u
"Files and Paths"_s )
9218 fcnExifGeoTag, u
"GeometryGroup"_s )
9221 <<
new QgsStaticExpressionFunction( u
"hash"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ) << QgsExpressionFunction::Parameter( u
"method"_s ),
9222 fcnGenericHash, u
"Conversions"_s )
9224 fcnHashMd5, u
"Conversions"_s )
9226 fcnHashSha256, u
"Conversions"_s )
9230 fcnToBase64, u
"Conversions"_s )
9232 fcnFromBase64, u
"Conversions"_s )
9236 << QgsExpressionFunction::Parameter( u
"date"_s )
9237 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9238 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9239 << QgsExpressionFunction::Parameter( u
"height"_s )
9240 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9241 fcnMagneticDeclination, u
"MagneticModels"_s )
9243 << QgsExpressionFunction::Parameter( u
"date"_s )
9244 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9245 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9246 << QgsExpressionFunction::Parameter( u
"height"_s )
9247 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9248 fcnMagneticInclination, u
"MagneticModels"_s )
9250 << QgsExpressionFunction::Parameter( u
"date"_s )
9251 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9252 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9253 << QgsExpressionFunction::Parameter( u
"height"_s )
9254 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9255 fcnMagneticDeclinationRateOfChange, u
"MagneticModels"_s )
9257 << QgsExpressionFunction::Parameter( u
"date"_s )
9258 << QgsExpressionFunction::Parameter( u
"latitude"_s )
9259 << QgsExpressionFunction::Parameter( u
"longitude"_s )
9260 << QgsExpressionFunction::Parameter( u
"height"_s )
9261 << QgsExpressionFunction::Parameter( u
"model_path"_s,
true ),
9262 fcnMagneticInclinationRateOfChange, u
"MagneticModels"_s )
9267 QgsStaticExpressionFunction *geomFunc =
new QgsStaticExpressionFunction( u
"$geometry"_s, 0, fcnGeometry, u
"GeometryGroup"_s, QString(),
true );
9269 functions << geomFunc;
9271 QgsStaticExpressionFunction *areaFunc =
new QgsStaticExpressionFunction( u
"$area"_s, 0, fcnGeomArea, u
"GeometryGroup"_s, QString(),
true );
9273 functions << areaFunc;
9275 functions <<
new QgsStaticExpressionFunction( u
"area"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnArea, u
"GeometryGroup"_s );
9277 QgsStaticExpressionFunction *lengthFunc =
new QgsStaticExpressionFunction( u
"$length"_s, 0, fcnGeomLength, u
"GeometryGroup"_s, QString(),
true );
9279 functions << lengthFunc;
9281 QgsStaticExpressionFunction *perimeterFunc =
new QgsStaticExpressionFunction( u
"$perimeter"_s, 0, fcnGeomPerimeter, u
"GeometryGroup"_s, QString(),
true );
9283 functions << perimeterFunc;
9285 functions <<
new QgsStaticExpressionFunction( u
"perimeter"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPerimeter, u
"GeometryGroup"_s );
9287 functions <<
new QgsStaticExpressionFunction( u
"roundness"_s,
9289 fcnRoundness, u
"GeometryGroup"_s );
9291 QgsStaticExpressionFunction *xFunc =
new QgsStaticExpressionFunction( u
"$x"_s, 0, fcnX, u
"GeometryGroup"_s, QString(),
true );
9295 QgsStaticExpressionFunction *yFunc =
new QgsStaticExpressionFunction( u
"$y"_s, 0, fcnY, u
"GeometryGroup"_s, QString(),
true );
9299 QgsStaticExpressionFunction *zFunc =
new QgsStaticExpressionFunction( u
"$z"_s, 0, fcnZ, u
"GeometryGroup"_s, QString(),
true );
9303 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
9305 { u
"overlay_intersects"_s, fcnGeomOverlayIntersects },
9306 { u
"overlay_contains"_s, fcnGeomOverlayContains },
9307 { u
"overlay_crosses"_s, fcnGeomOverlayCrosses },
9308 { u
"overlay_equals"_s, fcnGeomOverlayEquals },
9309 { u
"overlay_touches"_s, fcnGeomOverlayTouches },
9310 { u
"overlay_disjoint"_s, fcnGeomOverlayDisjoint },
9311 { u
"overlay_within"_s, fcnGeomOverlayWithin },
9313 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
9314 while ( i.hasNext() )
9318 << QgsExpressionFunction::Parameter( u
"layer"_s )
9319 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9320 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9321 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( -1 ),
true )
9322 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false )
9323 << QgsExpressionFunction::Parameter( u
"min_overlap"_s,
true, QVariant( -1 ),
false )
9324 << QgsExpressionFunction::Parameter( u
"min_inscribed_circle_radius"_s,
true, QVariant( -1 ),
false )
9325 << QgsExpressionFunction::Parameter( u
"return_details"_s,
true,
false,
false )
9326 << QgsExpressionFunction::Parameter( u
"sort_by_intersection_size"_s,
true, QString(),
false ),
9331 functions << fcnGeomOverlayFunc;
9335 << QgsExpressionFunction::Parameter( u
"layer"_s )
9336 << QgsExpressionFunction::Parameter( u
"expression"_s,
true, QVariant(),
true )
9337 << QgsExpressionFunction::Parameter( u
"filter"_s,
true, QVariant(),
true )
9338 << QgsExpressionFunction::Parameter( u
"limit"_s,
true, QVariant( 1 ),
true )
9339 << QgsExpressionFunction::Parameter( u
"max_distance"_s,
true, 0 )
9340 << QgsExpressionFunction::Parameter( u
"cache"_s,
true, QVariant(
false ),
false ),
9344 functions << fcnGeomOverlayNearestFunc;
9347 <<
new QgsStaticExpressionFunction( u
"is_valid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomIsValid, u
"GeometryGroup"_s )
9352 <<
new QgsStaticExpressionFunction( u
"point_n"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"index"_s ), fcnPointN, u
"GeometryGroup"_s )
9353 <<
new QgsStaticExpressionFunction( u
"start_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnStartPoint, u
"GeometryGroup"_s )
9354 <<
new QgsStaticExpressionFunction( u
"end_point"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnEndPoint, u
"GeometryGroup"_s )
9356 << QgsExpressionFunction::Parameter( u
"ignore_closing_nodes"_s,
true,
false ),
9357 fcnNodesToPoints, u
"GeometryGroup"_s )
9358 <<
new QgsStaticExpressionFunction( u
"segments_to_lines"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnSegmentsToLines, u
"GeometryGroup"_s )
9359 <<
new QgsStaticExpressionFunction( u
"collect_geometries"_s, -1, fcnCollectGeometries, u
"GeometryGroup"_s )
9360 <<
new QgsStaticExpressionFunction( u
"make_point"_s, -1, fcnMakePoint, u
"GeometryGroup"_s )
9362 << QgsExpressionFunction::Parameter( u
"y"_s )
9363 << QgsExpressionFunction::Parameter( u
"m"_s ),
9364 fcnMakePointM, u
"GeometryGroup"_s )
9365 <<
new QgsStaticExpressionFunction( u
"make_line"_s, -1, fcnMakeLine, u
"GeometryGroup"_s )
9366 <<
new QgsStaticExpressionFunction( u
"make_polygon"_s, -1, fcnMakePolygon, u
"GeometryGroup"_s )
9368 << QgsExpressionFunction::Parameter( u
"point2"_s )
9369 << QgsExpressionFunction::Parameter( u
"point3"_s ),
9370 fcnMakeTriangle, u
"GeometryGroup"_s )
9372 << QgsExpressionFunction::Parameter( u
"center"_s )
9373 << QgsExpressionFunction::Parameter( u
"radius"_s )
9374 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9375 fcnMakeCircle, u
"GeometryGroup"_s )
9377 << QgsExpressionFunction::Parameter( u
"center"_s )
9378 << QgsExpressionFunction::Parameter( u
"semi_major_axis"_s )
9379 << QgsExpressionFunction::Parameter( u
"semi_minor_axis"_s )
9380 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9381 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9382 fcnMakeEllipse, u
"GeometryGroup"_s )
9384 << QgsExpressionFunction::Parameter( u
"center"_s )
9385 << QgsExpressionFunction::Parameter( u
"radius"_s )
9386 << QgsExpressionFunction::Parameter( u
"number_sides"_s )
9387 << QgsExpressionFunction::Parameter( u
"circle"_s,
true, 0 ),
9388 fcnMakeRegularPolygon, u
"GeometryGroup"_s )
9390 << QgsExpressionFunction::Parameter( u
"point1"_s )
9391 << QgsExpressionFunction::Parameter( u
"point2"_s ),
9392 fcnMakeSquare, u
"GeometryGroup"_s )
9394 << QgsExpressionFunction::Parameter( u
"point1"_s )
9395 << QgsExpressionFunction::Parameter( u
"point2"_s )
9396 << QgsExpressionFunction::Parameter( u
"point3"_s )
9397 << QgsExpressionFunction::Parameter( u
"option"_s,
true, 0 ),
9398 fcnMakeRectangleFrom3Points, u
"GeometryGroup"_s )
9401 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9402#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
9403 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"linework"_s ),
9405 QgsExpressionFunction::Parameter( u
"method"_s,
true, u
"structure"_s ),
9407 QgsExpressionFunction::Parameter( u
"keep_collapsed"_s,
true,
false )
9408 }, fcnGeomMakeValid, u
"GeometryGroup"_s );
9410 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 );
9411 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 );
9412 functions <<
new QgsStaticExpressionFunction( u
"z_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnZat, u
"GeometryGroup"_s );
9413 functions <<
new QgsStaticExpressionFunction( u
"m_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"vertex"_s,
true ), fcnMat, u
"GeometryGroup"_s );
9415 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 );
9417 functions << xAtFunc;
9420 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 );
9422 functions << yAtFunc;
9425 <<
new QgsStaticExpressionFunction( u
"geometry_type"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeometryType, u
"GeometryGroup"_s )
9426 <<
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 )
9427 <<
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 )
9428 <<
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 )
9429 <<
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 )
9430 <<
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 )
9431 <<
new QgsStaticExpressionFunction( u
"geom_from_wkb"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"binary"_s ), fcnGeomFromWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
9432 <<
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 )
9433 <<
new QgsStaticExpressionFunction( u
"flip_coordinates"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnFlipCoordinates, u
"GeometryGroup"_s )
9434 <<
new QgsStaticExpressionFunction( u
"relate"_s, -1, fcnRelate, u
"GeometryGroup"_s )
9435 <<
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 )
9437 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9438 fcnDisjoint, u
"GeometryGroup"_s )
9440 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9441 fcnIntersects, u
"GeometryGroup"_s )
9443 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9444 fcnTouches, u
"GeometryGroup"_s )
9446 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9447 fcnCrosses, u
"GeometryGroup"_s )
9449 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9450 fcnContains, u
"GeometryGroup"_s )
9452 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9453 fcnOverlaps, u
"GeometryGroup"_s )
9455 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9456 fcnWithin, u
"GeometryGroup"_s )
9458 << QgsExpressionFunction::Parameter( u
"dx"_s )
9459 << QgsExpressionFunction::Parameter( u
"dy"_s ),
9460 fcnTranslate, u
"GeometryGroup"_s )
9462 << QgsExpressionFunction::Parameter( u
"rotation"_s )
9463 << QgsExpressionFunction::Parameter( u
"center"_s,
true )
9464 << QgsExpressionFunction::Parameter( u
"per_part"_s,
true,
false ),
9465 fcnRotate, u
"GeometryGroup"_s )
9467 << QgsExpressionFunction::Parameter( u
"x_scale"_s )
9468 << QgsExpressionFunction::Parameter( u
"y_scale"_s )
9469 << QgsExpressionFunction::Parameter( u
"center"_s,
true ),
9470 fcnScale, u
"GeometryGroup"_s )
9472 << QgsExpressionFunction::Parameter( u
"delta_x"_s )
9473 << QgsExpressionFunction::Parameter( u
"delta_y"_s )
9474 << QgsExpressionFunction::Parameter( u
"rotation_z"_s )
9475 << QgsExpressionFunction::Parameter( u
"scale_x"_s )
9476 << QgsExpressionFunction::Parameter( u
"scale_y"_s )
9477 << QgsExpressionFunction::Parameter( u
"delta_z"_s,
true, 0 )
9478 << QgsExpressionFunction::Parameter( u
"delta_m"_s,
true, 0 )
9479 << QgsExpressionFunction::Parameter( u
"scale_z"_s,
true, 1 )
9480 << QgsExpressionFunction::Parameter( u
"scale_m"_s,
true, 1 ),
9481 fcnAffineTransform, u
"GeometryGroup"_s )
9483 << QgsExpressionFunction::Parameter( u
"distance"_s )
9484 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8 )
9485 << QgsExpressionFunction::Parameter( u
"cap"_s,
true, u
"round"_s )
9486 << QgsExpressionFunction::Parameter( u
"join"_s,
true, u
"round"_s )
9487 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2 ),
9488 fcnBuffer, u
"GeometryGroup"_s )
9490 fcnForceRHR, u
"GeometryGroup"_s )
9492 fcnForcePolygonCW, u
"GeometryGroup"_s )
9494 fcnForcePolygonCCW, u
"GeometryGroup"_s )
9496 << QgsExpressionFunction::Parameter( u
"azimuth"_s )
9497 << QgsExpressionFunction::Parameter( u
"width"_s )
9498 << QgsExpressionFunction::Parameter( u
"outer_radius"_s )
9499 << QgsExpressionFunction::Parameter( u
"inner_radius"_s,
true, 0.0 ), fcnWedgeBuffer, u
"GeometryGroup"_s )
9501 << QgsExpressionFunction::Parameter( u
"start_width"_s )
9502 << QgsExpressionFunction::Parameter( u
"end_width"_s )
9503 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9504 , fcnTaperedBuffer, u
"GeometryGroup"_s )
9506 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9507 , fcnBufferByM, u
"GeometryGroup"_s )
9509 << QgsExpressionFunction::Parameter( u
"distance"_s )
9510 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9512 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
9513 fcnOffsetCurve, u
"GeometryGroup"_s )
9515 << QgsExpressionFunction::Parameter( u
"distance"_s )
9516 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 8.0 )
9518 << QgsExpressionFunction::Parameter( u
"miter_limit"_s,
true, 2.0 ),
9519 fcnSingleSidedBuffer, u
"GeometryGroup"_s )
9521 << QgsExpressionFunction::Parameter( u
"start_distance"_s )
9522 << QgsExpressionFunction::Parameter( u
"end_distance"_s ),
9523 fcnExtend, u
"GeometryGroup"_s )
9524 <<
new QgsStaticExpressionFunction( u
"centroid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCentroid, u
"GeometryGroup"_s )
9525 <<
new QgsStaticExpressionFunction( u
"point_on_surface"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnPointOnSurface, u
"GeometryGroup"_s )
9527 << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnPoleOfInaccessibility, u
"GeometryGroup"_s )
9528 <<
new QgsStaticExpressionFunction( u
"reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnReverse, { u
"String"_s, u
"GeometryGroup"_s } )
9529 <<
new QgsStaticExpressionFunction( u
"exterior_ring"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnExteriorRing, u
"GeometryGroup"_s )
9531 << QgsExpressionFunction::Parameter( u
"index"_s ),
9532 fcnInteriorRingN, u
"GeometryGroup"_s )
9534 << QgsExpressionFunction::Parameter( u
"index"_s ),
9535 fcnGeometryN, u
"GeometryGroup"_s )
9536 <<
new QgsStaticExpressionFunction( u
"boundary"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundary, u
"GeometryGroup"_s )
9537 <<
new QgsStaticExpressionFunction( u
"line_merge"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnLineMerge, u
"GeometryGroup"_s )
9540 QgsExpressionFunction::Parameter( u
"geometry1"_s ),
9541 QgsExpressionFunction::Parameter( u
"geometry2"_s )
9542 }, fcnSharedPaths, u
"GeometryGroup"_s )
9544 <<
new QgsStaticExpressionFunction( u
"simplify"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplify, u
"GeometryGroup"_s )
9545 <<
new QgsStaticExpressionFunction( u
"simplify_vw"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"tolerance"_s ), fcnSimplifyVW, u
"GeometryGroup"_s )
9546 <<
new QgsStaticExpressionFunction( u
"smooth"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ) << QgsExpressionFunction::Parameter( u
"iterations"_s,
true, 1 )
9547 << QgsExpressionFunction::Parameter( u
"offset"_s,
true, 0.25 )
9548 << QgsExpressionFunction::Parameter( u
"min_length"_s,
true, -1 )
9549 << QgsExpressionFunction::Parameter( u
"max_angle"_s,
true, 180 ), fcnSmooth, u
"GeometryGroup"_s )
9550 <<
new QgsStaticExpressionFunction( u
"triangular_wave"_s,
9552 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9553 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9554 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9555 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9556 }, fcnTriangularWave, u
"GeometryGroup"_s )
9557 <<
new QgsStaticExpressionFunction( u
"triangular_wave_randomized"_s,
9559 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9560 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9561 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9562 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9563 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9564 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9565 }, fcnTriangularWaveRandomized, u
"GeometryGroup"_s )
9566 <<
new QgsStaticExpressionFunction( u
"square_wave"_s,
9568 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9569 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9570 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9571 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9572 }, fcnSquareWave, u
"GeometryGroup"_s )
9573 <<
new QgsStaticExpressionFunction( u
"square_wave_randomized"_s,
9575 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9576 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9577 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9578 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9579 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9580 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9581 }, fcnSquareWaveRandomized, u
"GeometryGroup"_s )
9582 <<
new QgsStaticExpressionFunction( u
"wave"_s,
9584 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9585 QgsExpressionFunction::Parameter( u
"wavelength"_s ),
9586 QgsExpressionFunction::Parameter( u
"amplitude"_s ),
9587 QgsExpressionFunction::Parameter( u
"strict"_s,
true,
false )
9588 }, fcnRoundWave, u
"GeometryGroup"_s )
9589 <<
new QgsStaticExpressionFunction( u
"wave_randomized"_s,
9591 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9592 QgsExpressionFunction::Parameter( u
"min_wavelength"_s ),
9593 QgsExpressionFunction::Parameter( u
"max_wavelength"_s ),
9594 QgsExpressionFunction::Parameter( u
"min_amplitude"_s ),
9595 QgsExpressionFunction::Parameter( u
"max_amplitude"_s ),
9596 QgsExpressionFunction::Parameter( u
"seed"_s,
true, 0 )
9597 }, fcnRoundWaveRandomized, u
"GeometryGroup"_s )
9598 <<
new QgsStaticExpressionFunction( u
"apply_dash_pattern"_s,
9600 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9601 QgsExpressionFunction::Parameter( u
"pattern"_s ),
9602 QgsExpressionFunction::Parameter( u
"start_rule"_s,
true, u
"no_rule"_s ),
9603 QgsExpressionFunction::Parameter( u
"end_rule"_s,
true, u
"no_rule"_s ),
9604 QgsExpressionFunction::Parameter( u
"adjustment"_s,
true, u
"both"_s ),
9605 QgsExpressionFunction::Parameter( u
"pattern_offset"_s,
true, 0 ),
9606 }, fcnApplyDashPattern, u
"GeometryGroup"_s )
9607 <<
new QgsStaticExpressionFunction( u
"densify_by_count"_s,
9609 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9610 QgsExpressionFunction::Parameter( u
"vertices"_s )
9611 }, fcnDensifyByCount, u
"GeometryGroup"_s )
9612 <<
new QgsStaticExpressionFunction( u
"densify_by_distance"_s,
9614 QgsExpressionFunction::Parameter( u
"geometry"_s ),
9615 QgsExpressionFunction::Parameter( u
"distance"_s )
9616 }, fcnDensifyByDistance, u
"GeometryGroup"_s )
9617 <<
new QgsStaticExpressionFunction( u
"num_points"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumPoints, u
"GeometryGroup"_s )
9618 <<
new QgsStaticExpressionFunction( u
"num_interior_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumInteriorRings, u
"GeometryGroup"_s )
9619 <<
new QgsStaticExpressionFunction( u
"num_rings"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumRings, u
"GeometryGroup"_s )
9620 <<
new QgsStaticExpressionFunction( u
"num_geometries"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnGeomNumGeometries, u
"GeometryGroup"_s )
9621 <<
new QgsStaticExpressionFunction( u
"bounds_width"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsWidth, u
"GeometryGroup"_s )
9622 <<
new QgsStaticExpressionFunction( u
"bounds_height"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnBoundsHeight, u
"GeometryGroup"_s )
9623 <<
new QgsStaticExpressionFunction( u
"is_closed"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsClosed, u
"GeometryGroup"_s )
9624 <<
new QgsStaticExpressionFunction( u
"close_line"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnCloseLine, u
"GeometryGroup"_s )
9625 <<
new QgsStaticExpressionFunction( u
"is_empty"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s ), fcnIsEmpty, u
"GeometryGroup"_s )
9626 <<
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 )
9627 <<
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 )
9628#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
9630 << QgsExpressionFunction::Parameter( u
"target_percent"_s )
9631 << QgsExpressionFunction::Parameter( u
"allow_holes"_s,
true,
false ), fcnConcaveHull, u
"GeometryGroup"_s )
9634 << QgsExpressionFunction::Parameter( u
"geometry"_s ),
9635 fcnOrientedBBox, u
"GeometryGroup"_s )
9637 << QgsExpressionFunction::Parameter( u
"geometry"_s ),
9638 fcnMainAngle, u
"GeometryGroup"_s )
9640 << QgsExpressionFunction::Parameter( u
"geometry"_s )
9641 << QgsExpressionFunction::Parameter( u
"segments"_s,
true, 36 ),
9642 fcnMinimalCircle, u
"GeometryGroup"_s )
9644 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9645 fcnDifference, u
"GeometryGroup"_s )
9647 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9648 fcnDistance, u
"GeometryGroup"_s )
9649 <<
new QgsStaticExpressionFunction( u
"hausdorff_distance"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry1"_s ) << QgsExpressionFunction::Parameter( u
"geometry2"_s )
9650 << QgsExpressionFunction::Parameter( u
"densify_fraction"_s,
true ),
9651 fcnHausdorffDistance, u
"GeometryGroup"_s )
9653 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9654 fcnIntersection, u
"GeometryGroup"_s )
9656 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9657 fcnSymDifference, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"symDifference"_s )
9659 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9660 fcnCombine, u
"GeometryGroup"_s )
9662 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9663 fcnCombine, u
"GeometryGroup"_s )
9665 << QgsExpressionFunction::Parameter( u
"precision"_s,
true, 8.0 ),
9666 fcnGeomToWKT, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"geomToWKT"_s )
9668 fcnGeomToWKB, u
"GeometryGroup"_s, QString(),
false, QSet<QString>(),
false )
9669 <<
new QgsStaticExpressionFunction( u
"geometry"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetGeometry, u
"GeometryGroup"_s, QString(),
true )
9671 << QgsExpressionFunction::Parameter( u
"source_auth_id"_s )
9672 << QgsExpressionFunction::Parameter( u
"dest_auth_id"_s ),
9673 fcnTransformGeometry, u
"GeometryGroup"_s )
9675 << QgsExpressionFunction::Parameter( u
"x"_s )
9676 << QgsExpressionFunction::Parameter( u
"y"_s ),
9677 fcnExtrude, u
"GeometryGroup"_s, QString() )
9679 fcnGeomIsMultipart, u
"GeometryGroup"_s )
9681 fcnZMax, u
"GeometryGroup"_s )
9683 fcnZMin, u
"GeometryGroup"_s )
9685 fcnMMax, u
"GeometryGroup"_s )
9687 fcnMMin, u
"GeometryGroup"_s )
9689 fcnSinuosity, u
"GeometryGroup"_s )
9691 fcnStraightDistance2d, u
"GeometryGroup"_s );
9694 QgsStaticExpressionFunction *orderPartsFunc =
new QgsStaticExpressionFunction( u
"order_parts"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometry"_s )
9695 << QgsExpressionFunction::Parameter( u
"orderby"_s )
9696 << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ),
9697 fcnOrderParts, u
"GeometryGroup"_s, QString() );
9702 const QList< QgsExpressionNode *> argList = node->
args()->
list();
9703 for ( QgsExpressionNode *argNode : argList )
9705 if ( !argNode->isStatic( parent, context ) )
9711 QgsExpressionNode *argNode = node->
args()->
at( 1 );
9713 QString expString = argNode->
eval( parent, context ).toString();
9717 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
9728 QgsExpressionNode *argNode = node->
args()->
at( 1 );
9729 QString
expression = argNode->
eval( parent, context ).toString();
9731 e.prepare( context );
9737 functions << orderPartsFunc;
9741 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9742 fcnClosestPoint, u
"GeometryGroup"_s )
9744 << QgsExpressionFunction::Parameter( u
"geometry2"_s ),
9745 fcnShortestLine, u
"GeometryGroup"_s )
9747 << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolatePoint, u
"GeometryGroup"_s )
9749 << QgsExpressionFunction::Parameter( u
"m"_s ) << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
9750 fcnLineInterpolatePointByM, u
"GeometryGroup"_s )
9752 << QgsExpressionFunction::Parameter( u
"distance"_s ), fcnLineInterpolateAngle, u
"GeometryGroup"_s )
9754 << QgsExpressionFunction::Parameter( u
"point"_s ), fcnLineLocatePoint, u
"GeometryGroup"_s )
9756 << QgsExpressionFunction::Parameter( u
"m"_s ) << QgsExpressionFunction::Parameter( u
"use_3d_distance"_s,
true,
false ),
9757 fcnLineLocateM, u
"GeometryGroup"_s )
9759 << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnAngleAtVertex, u
"GeometryGroup"_s )
9761 << QgsExpressionFunction::Parameter( u
"vertex"_s ), fcnDistanceToVertex, u
"GeometryGroup"_s )
9763 << QgsExpressionFunction::Parameter( u
"start_distance"_s ) << QgsExpressionFunction::Parameter( u
"end_distance"_s ), fcnLineSubset, u
"GeometryGroup"_s );
9768 QgsStaticExpressionFunction *idFunc =
new QgsStaticExpressionFunction( u
"$id"_s, 0, fcnFeatureId, u
"Record and Attributes"_s );
9770 functions << idFunc;
9772 QgsStaticExpressionFunction *currentFeatureFunc =
new QgsStaticExpressionFunction( u
"$currentfeature"_s, 0, fcnFeature, u
"Record and Attributes"_s );
9774 functions << currentFeatureFunc;
9776 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 );
9778 functions << uuidFunc;
9781 <<
new QgsStaticExpressionFunction( u
"feature_id"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s ), fcnGetFeatureId, u
"Record and Attributes"_s, QString(),
true )
9783 << QgsExpressionFunction::Parameter( u
"attribute"_s )
9784 << QgsExpressionFunction::Parameter( u
"value"_s,
true ),
9785 fcnGetFeature, u
"Record and Attributes"_s, QString(),
false, QSet<QString>(),
false, QStringList() << u
"QgsExpressionUtils::getFeature"_s )
9787 << QgsExpressionFunction::Parameter( u
"feature_id"_s ),
9788 fcnGetFeatureById, u
"Record and Attributes"_s, QString(),
false, QSet<QString>(),
false );
9790 QgsStaticExpressionFunction *attributesFunc =
new QgsStaticExpressionFunction( u
"attributes"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"feature"_s,
true ),
9793 functions << attributesFunc;
9794 QgsStaticExpressionFunction *representAttributesFunc =
new QgsStaticExpressionFunction( u
"represent_attributes"_s, -1,
9797 functions << representAttributesFunc;
9799 QgsStaticExpressionFunction *validateFeature =
new QgsStaticExpressionFunction( u
"is_feature_valid"_s,
9801 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
9802 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
9805 functions << validateFeature;
9807 QgsStaticExpressionFunction *validateAttribute =
new QgsStaticExpressionFunction( u
"is_attribute_valid"_s,
9810 << QgsExpressionFunction::Parameter( u
"feature"_s,
true )
9811 << QgsExpressionFunction::Parameter( u
"strength"_s,
true ),
9814 functions << validateAttribute;
9816 QgsStaticExpressionFunction *maptipFunc =
new QgsStaticExpressionFunction(
9820 u
"Record and Attributes"_s,
9826 functions << maptipFunc;
9828 QgsStaticExpressionFunction *displayFunc =
new QgsStaticExpressionFunction(
9829 u
"display_expression"_s,
9831 fcnFeatureDisplayExpression,
9832 u
"Record and Attributes"_s,
9838 functions << displayFunc;
9840 QgsStaticExpressionFunction *isSelectedFunc =
new QgsStaticExpressionFunction(
9844 u
"Record and Attributes"_s,
9850 functions << isSelectedFunc;
9853 <<
new QgsStaticExpressionFunction(
9857 u
"Record and Attributes"_s,
9864 <<
new QgsStaticExpressionFunction(
9865 u
"sqlite_fetch_and_increment"_s,
9867 << QgsExpressionFunction::Parameter( u
"database"_s )
9868 << QgsExpressionFunction::Parameter( u
"table"_s )
9869 << QgsExpressionFunction::Parameter( u
"id_field"_s )
9870 << QgsExpressionFunction::Parameter( u
"filter_attribute"_s )
9871 << QgsExpressionFunction::Parameter( u
"filter_value"_s )
9872 << QgsExpressionFunction::Parameter( u
"default_values"_s,
true ),
9873 fcnSqliteFetchAndIncrement,
9874 u
"Record and Attributes"_s
9879 <<
new QgsStaticExpressionFunction( u
"crs_to_authid"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"crs"_s ), fcnCrsToAuthid, u
"CRS"_s, QString(),
true )
9880 <<
new QgsStaticExpressionFunction( u
"crs_from_text"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"definition"_s ), fcnCrsFromText, u
"CRS"_s );
9884 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 );
9891 QgsExpressionNodeColumnRef *colRef =
dynamic_cast<QgsExpressionNodeColumnRef *
>( node->
args()->at( 0 ) );
9898 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
9908 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
9914 functions << representValueFunc;
9919 << QgsExpressionFunction::Parameter( u
"property"_s ),
9920 fcnGetLayerProperty, u
"Map Layers"_s )
9921 <<
new QgsStaticExpressionFunction( u
"decode_uri"_s,
9923 << QgsExpressionFunction::Parameter( u
"layer"_s )
9924 << QgsExpressionFunction::Parameter( u
"part"_s,
true ),
9925 fcnDecodeUri, u
"Map Layers"_s )
9926 <<
new QgsStaticExpressionFunction( u
"mime_type"_s,
9928 << QgsExpressionFunction::Parameter( u
"binary_data"_s ),
9929 fcnMimeType, u
"General"_s )
9931 << QgsExpressionFunction::Parameter( u
"band"_s )
9932 << QgsExpressionFunction::Parameter( u
"statistic"_s ), fcnGetRasterBandStat, u
"Rasters"_s );
9935 QgsStaticExpressionFunction *varFunction =
new QgsStaticExpressionFunction( u
"var"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"name"_s ), fcnGetVariable, u
"General"_s );
9946 QgsExpressionNode *argNode = node->
args()->
at( 0 );
9948 if ( !argNode->
isStatic( parent, context ) )
9951 const QString varName = argNode->
eval( parent, context ).toString();
9952 if ( varName ==
"feature"_L1 || varName ==
"id"_L1 || varName ==
"geometry"_L1 )
9956 return scope ? scope->
isStatic( varName ) :
false;
9964 if ( node && node->
args()->
count() > 0 )
9966 QgsExpressionNode *argNode = node->
args()->
at( 0 );
9967 if ( QgsExpressionNodeLiteral *literal =
dynamic_cast<QgsExpressionNodeLiteral *
>( argNode ) )
9969 if ( literal->value() ==
"geometry"_L1 || literal->value() ==
"feature"_L1 )
9986 QgsExpressionNode *argNode = node->
args()->
at( 0 );
9988 if ( argNode->
isStatic( parent, context ) )
9990 QString expString = argNode->
eval( parent, context ).toString();
9994 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10001 functions << evalTemplateFunction;
10009 QgsExpressionNode *argNode = node->
args()->
at( 0 );
10011 if ( argNode->
isStatic( parent, context ) )
10013 QString expString = argNode->
eval( parent, context ).toString();
10017 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
10025 functions << evalFunc;
10027 QgsStaticExpressionFunction *attributeFunc =
new QgsStaticExpressionFunction( u
"attribute"_s, -1, fcnAttribute, u
"Record and Attributes"_s, QString(),
false, QSet<QString>() <<
QgsFeatureRequest::ALL_ATTRIBUTES );
10031 const QList< QgsExpressionNode *> argList = node->
args()->
list();
10032 for ( QgsExpressionNode *argNode : argList )
10034 if ( !argNode->
isStatic( parent, context ) )
10046 functions << attributeFunc;
10050 <<
new QgsWithVariableExpressionFunction()
10051 <<
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 )
10052 <<
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 )
10055 <<
new QgsArrayForeachExpressionFunction()
10056 <<
new QgsArrayFilterExpressionFunction()
10057 <<
new QgsStaticExpressionFunction( u
"array"_s, -1, fcnArray, u
"Arrays"_s, QString(),
false, QSet<QString>(),
false, QStringList(),
true )
10058 <<
new QgsStaticExpressionFunction( u
"array_sort"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"ascending"_s,
true,
true ), fcnArraySort, u
"Arrays"_s )
10059 <<
new QgsStaticExpressionFunction( u
"array_length"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayLength, u
"Arrays"_s )
10060 <<
new QgsStaticExpressionFunction( u
"array_contains"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayContains, u
"Arrays"_s )
10061 <<
new QgsStaticExpressionFunction( u
"array_count"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayCount, u
"Arrays"_s )
10062 <<
new QgsStaticExpressionFunction( u
"array_all"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array_a"_s ) << QgsExpressionFunction::Parameter( u
"array_b"_s ), fcnArrayAll, u
"Arrays"_s )
10063 <<
new QgsStaticExpressionFunction( u
"array_find"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayFind, u
"Arrays"_s )
10064 <<
new QgsStaticExpressionFunction( u
"array_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayGet, u
"Arrays"_s )
10070 <<
new QgsStaticExpressionFunction( u
"array_median"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayMedian, u
"Arrays"_s )
10071 <<
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 )
10072 <<
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 )
10074 <<
new QgsStaticExpressionFunction( u
"array_append"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayAppend, u
"Arrays"_s )
10075 <<
new QgsStaticExpressionFunction( u
"array_prepend"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"value"_s ), fcnArrayPrepend, u
"Arrays"_s )
10076 <<
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 )
10077 <<
new QgsStaticExpressionFunction( u
"array_remove_at"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"pos"_s ), fcnArrayRemoveAt, u
"Arrays"_s )
10078 <<
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 )
10079 <<
new QgsStaticExpressionFunction( u
"array_replace"_s, -1, fcnArrayReplace, u
"Arrays"_s )
10080 <<
new QgsStaticExpressionFunction( u
"array_prioritize"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ) << QgsExpressionFunction::Parameter( u
"array_prioritize"_s ), fcnArrayPrioritize, u
"Arrays"_s )
10081 <<
new QgsStaticExpressionFunction( u
"array_cat"_s, -1, fcnArrayCat, u
"Arrays"_s )
10082 <<
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 )
10083 <<
new QgsStaticExpressionFunction( u
"array_reverse"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayReverse, u
"Arrays"_s )
10084 <<
new QgsStaticExpressionFunction( u
"array_intersect"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array1"_s ) << QgsExpressionFunction::Parameter( u
"array2"_s ), fcnArrayIntersect, u
"Arrays"_s )
10085 <<
new QgsStaticExpressionFunction( u
"array_distinct"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"array"_s ), fcnArrayDistinct, u
"Arrays"_s )
10086 <<
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 )
10087 <<
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 )
10088 <<
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 )
10089 <<
new QgsStaticExpressionFunction( u
"geometries_to_array"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"geometries"_s ), fcnGeometryCollectionAsArray, u
"Arrays"_s )
10092 <<
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 )
10093 <<
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 )
10094 <<
new QgsStaticExpressionFunction( u
"hstore_to_map"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"string"_s ), fcnHstoreToMap, u
"Maps"_s )
10096 <<
new QgsStaticExpressionFunction( u
"map"_s, -1, fcnMap, u
"Maps"_s )
10097 <<
new QgsStaticExpressionFunction( u
"map_get"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapGet, u
"Maps"_s )
10098 <<
new QgsStaticExpressionFunction( u
"map_exist"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapExist, u
"Maps"_s )
10099 <<
new QgsStaticExpressionFunction( u
"map_delete"_s,
QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( u
"map"_s ) << QgsExpressionFunction::Parameter( u
"key"_s ), fcnMapDelete, u
"Maps"_s )
10100 <<
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 )
10101 <<
new QgsStaticExpressionFunction( u
"map_concat"_s, -1, fcnMapConcat, u
"Maps"_s )
10105 << QgsExpressionFunction::Parameter( u
"prefix"_s ),
10106 fcnMapPrefixKeys, u
"Maps"_s )
10108 fcnMapToHtmlTable, u
"Maps"_s )
10110 fcnMapToHtmlDefinitionList, u
"Maps"_s )
10112 fcnToFormUrlEncode, u
"Maps"_s )
10121 *sOwnedFunctions() << func;
10122 *sBuiltinFunctions() << func->name();
10123 sBuiltinFunctions()->append( func->aliases() );
10137 QMutexLocker locker( &sFunctionsMutex );
10138 sFunctions()->append( function );
10139 if ( transferOwnership )
10140 sOwnedFunctions()->append( function );
10155 QMutexLocker locker( &sFunctionsMutex );
10156 sFunctions()->removeAt( fnIdx );
10157 sFunctionIndexMap.clear();
10165 const QList<QgsExpressionFunction *> &ownedFunctions = *sOwnedFunctions();
10166 for ( QgsExpressionFunction *func : std::as_const( ownedFunctions ) )
10168 sBuiltinFunctions()->removeAll( func->name() );
10169 for (
const QString &alias : func->aliases() )
10171 sBuiltinFunctions()->removeAll( alias );
10174 sFunctions()->removeAll( func );
10177 qDeleteAll( *sOwnedFunctions() );
10178 sOwnedFunctions()->clear();
10183 if ( sBuiltinFunctions()->isEmpty() )
10187 return *sBuiltinFunctions();
10203 QgsExpressionNode::NodeList *args = node->
args();
10205 if ( args->
count() < 2 )
10208 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10218 QVariantList result;
10220 if ( args->
count() < 2 )
10224 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10226 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10227 std::unique_ptr< QgsExpressionContext > tempContext;
10230 tempContext = std::make_unique< QgsExpressionContext >();
10231 subContext = tempContext.get();
10234 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10238 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it, ++i )
10242 result << args->
at( 1 )->
eval( parent, subContext );
10255 Q_UNUSED( context )
10267 if ( args->
count() < 2 )
10271 args->
at( 0 )->
prepare( parent, context );
10275 subContext = *context;
10282 args->
at( 1 )->
prepare( parent, &subContext );
10303 if ( args->
count() < 2 )
10306 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10316 QVariantList result;
10318 if ( args->
count() < 2 )
10322 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
10324 QgsExpressionContext *subContext =
const_cast<QgsExpressionContext *
>( context );
10325 std::unique_ptr< QgsExpressionContext > tempContext;
10328 tempContext = std::make_unique< QgsExpressionContext >();
10329 subContext = tempContext.get();
10332 QgsExpressionContextScope *subScope =
new QgsExpressionContextScope();
10336 if ( args->
count() >= 3 )
10338 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
10340 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
10342 limit = limitVar.toInt();
10350 for (
const QVariant &value : array )
10352 subScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"element"_s, value,
true ) );
10353 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
10357 if ( limit > 0 && limit == result.size() )
10372 Q_UNUSED( context )
10384 if ( args->
count() < 2 )
10388 args->
at( 0 )->
prepare( parent, context );
10392 subContext = *context;
10398 args->
at( 1 )->
prepare( parent, &subContext );
10416 QgsExpressionNode::NodeList *args = node->
args();
10418 if ( args->
count() < 3 )
10422 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
10424 QVariant
name = args->
at( 0 )->
eval( parent, context );
10425 QVariant value = args->
at( 1 )->
eval( parent, context );
10428 appendTemporaryVariable( context,
name.toString(), value );
10429 if ( args->
at( 2 )->
isStatic( parent, context ) )
10431 popTemporaryVariable( context );
10442 if ( args->
count() < 3 )
10446 QVariant
name = args->
at( 0 )->
eval( parent, context );
10447 QVariant value = args->
at( 1 )->
eval( parent, context );
10449 const QgsExpressionContext *updatedContext = context;
10450 std::unique_ptr< QgsExpressionContext > tempContext;
10451 if ( !updatedContext )
10453 tempContext = std::make_unique< QgsExpressionContext >();
10454 updatedContext = tempContext.get();
10457 appendTemporaryVariable( updatedContext,
name.toString(), value );
10458 result = args->
at( 2 )->
eval( parent, updatedContext );
10461 popTemporaryVariable( updatedContext );
10470 Q_UNUSED( context )
10482 if ( args->
count() < 3 )
10487 QVariant value = args->
at( 1 )->
prepare( parent, context );
10490 std::unique_ptr< QgsExpressionContext > tempContext;
10491 if ( !updatedContext )
10493 tempContext = std::make_unique< QgsExpressionContext >();
10494 updatedContext = tempContext.get();
10497 appendTemporaryVariable( updatedContext,
name.toString(), value );
10498 args->
at( 2 )->
prepare( parent, updatedContext );
10501 popTemporaryVariable( updatedContext );
10506void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
10508 QgsExpressionContext *updatedContext =
const_cast<QgsExpressionContext *
>( context );
10509 delete updatedContext->
popScope();
10512void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
10514 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
10515 scope->
addVariable( QgsExpressionContextScope::StaticVariable(
name, value,
true ) );
10517 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.