68#include <QMimeDatabase>
69#include <QProcessEnvironment>
70#include <QCryptographicHash>
71#include <QRegularExpression>
94 QVariantList argValues;
98 const QList< QgsExpressionNode * > argList = args->
list();
105 v = QVariant::fromValue( n );
109 v = n->eval( parent, context );
111 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
112 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
115 argValues.append( v );
120 return func( argValues, context, parent, node );
131 return QStringList();
158 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
163 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
175 const QString &group,
176 const QString &helpText,
180 const QStringList &aliases,
184 , mAliases( aliases )
185 , mUsesGeometry( false )
186 , mUsesGeometryFunc( usesGeometry )
187 , mReferencedColumnsFunc( referencedColumns )
199 if ( mUsesGeometryFunc )
200 return mUsesGeometryFunc( node );
202 return mUsesGeometry;
212 if ( mReferencedColumnsFunc )
213 return mReferencedColumnsFunc( node );
215 return mReferencedColumns;
221 return mIsStaticFunc( node, parent, context );
229 return mPrepareFunc( node, parent, context );
241 mIsStaticFunc =
nullptr;
247 mPrepareFunc = prepareFunc;
252 if ( node && node->
args() )
254 const QList< QgsExpressionNode * > argList = node->
args()->
list();
257 if ( !argNode->isStatic( parent, context ) )
267 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
268 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
269 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
271 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
278 double current = start + step;
279 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
294 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
296 if ( name == QLatin1String(
"feature" ) )
298 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
300 else if ( name == QLatin1String(
"id" ) )
302 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
304 else if ( name == QLatin1String(
"geometry" ) )
320 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
329 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
331 return expression.evaluate( context );
336 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
337 return QVariant( std::sqrt( x ) );
342 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::fabs( val ) );
348 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return ( deg * M_PI ) / 180;
353 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
354 return ( 180 * rad ) / M_PI;
358 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
359 return QVariant( std::sin( x ) );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
364 return QVariant( std::cos( x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::tan( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
374 return QVariant( std::asin( x ) );
378 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
379 return QVariant( std::acos( x ) );
383 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
384 return QVariant( std::atan( x ) );
388 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
389 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
390 return QVariant( std::atan2( y, x ) );
394 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
395 return QVariant( std::exp( x ) );
399 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::log( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
409 return QVariant( log10( x ) );
413 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
414 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
415 if ( x <= 0 || b <= 0 )
417 return QVariant( std::log( x ) / std::log( b ) );
421 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
422 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
426 std::random_device rd;
427 std::mt19937_64 generator( rd() );
429 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
432 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
435 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
440 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
441 std::hash<std::string> hasher;
442 seed = hasher( seedStr.toStdString() );
444 generator.seed( seed );
448 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
449 return QVariant( min + f * ( max - min ) );
453 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
454 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
458 std::random_device rd;
459 std::mt19937_64 generator( rd() );
461 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
464 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
467 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
472 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
473 std::hash<std::string> hasher;
474 seed = hasher( seedStr.toStdString() );
476 generator.seed( seed );
479 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
480 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
481 return QVariant( randomInteger );
484 return QVariant(
int( randomInteger ) );
489 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
490 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
491 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
492 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
493 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
495 if ( domainMin >= domainMax )
497 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
502 if ( val >= domainMax )
506 else if ( val <= domainMin )
512 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
513 double c = rangeMin - ( domainMin * m );
516 return QVariant( m * val +
c );
521 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
522 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
523 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
524 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
525 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
526 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
528 if ( domainMin >= domainMax )
530 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
540 if ( val >= domainMax )
544 else if ( val <= domainMin )
550 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
555 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
556 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
557 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
558 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
559 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
560 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
562 if ( domainMin >= domainMax )
564 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
574 if ( val >= domainMax )
578 else if ( val <= domainMin )
584 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
585 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
591 double maxVal = std::numeric_limits<double>::quiet_NaN();
592 for (
const QVariant &val : values )
595 if ( std::isnan( maxVal ) )
599 else if ( !std::isnan( testVal ) )
601 maxVal = std::max( maxVal, testVal );
605 if ( !std::isnan( maxVal ) )
607 result = QVariant( maxVal );
615 double minVal = std::numeric_limits<double>::quiet_NaN();
616 for (
const QVariant &val : values )
619 if ( std::isnan( minVal ) )
623 else if ( !std::isnan( testVal ) )
625 minVal = std::min( minVal, testVal );
629 if ( !std::isnan( minVal ) )
631 result = QVariant( minVal );
643 QVariant value = node->
eval( parent, context );
648 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
652 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
657 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
659 value = node->
eval( parent, context );
665 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
670 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
672 QString subExpression = node->
dump();
676 if ( values.count() > 3 )
678 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
681 if ( !nl || nl->value().isValid() )
686 if ( values.count() > 4 )
688 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
690 value = node->
eval( parent, context );
697 if ( values.count() > 5 )
699 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
702 if ( !nl || nl->value().isValid() )
704 orderBy = node->
dump();
709 QString aggregateError;
717 const QSet< QString > filterVars = filterExp.referencedVariables();
718 const QSet< QString > subExpVars = subExp.referencedVariables();
719 QSet<QString> allVars = filterVars + subExpVars;
721 bool isStatic =
true;
722 if ( filterVars.contains( QStringLiteral(
"parent" ) )
723 || filterVars.contains( QString() )
724 || subExpVars.contains( QStringLiteral(
"parent" ) )
725 || subExpVars.contains( QString() ) )
731 for (
const QString &varName : allVars )
734 if ( scope && !scope->
isStatic( varName ) )
742 if ( isStatic && ! parameters.
orderBy.isEmpty() )
744 for (
const auto &orderByClause : std::as_const( parameters.orderBy ) )
747 if ( orderByExpression.referencedVariables().contains( QStringLiteral(
"parent" ) ) || orderByExpression.referencedVariables().contains( QString() ) )
758 const QString contextHash = context->
uniqueHash( ok, allVars );
761 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5:%6" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
762 orderBy, contextHash );
767 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
778 subContext.appendScope( subScope );
779 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
781 if ( ok && !cacheKey.isEmpty() )
791 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
795 if ( !aggregateError.isEmpty() )
796 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
798 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
809 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
817 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
821 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
830 QVariant value = node->
eval( parent, context );
832 QString relationId = value.toString();
839 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
841 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
846 relation = relations.at( 0 );
853 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
855 value = node->
eval( parent, context );
861 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
866 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
868 QString subExpression = node->
dump();
872 if ( values.count() > 3 )
874 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
876 value = node->
eval( parent, context );
883 if ( values.count() > 4 )
885 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
888 if ( !nl || nl->value().isValid() )
890 orderBy = node->
dump();
901 const QString cacheKey = QStringLiteral(
"relagg:%1%:%2:%3:%4:%5:%6" ).arg( relationId, vl->id(),
902 QString::number(
static_cast< int >( aggregate ) ),
915 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
919 if ( !error.isEmpty() )
920 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
922 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
936 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
944 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
948 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
957 QString subExpression = node->
dump();
961 if ( values.count() > 1 )
963 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
966 if ( !nl || nl->value().isValid() )
967 groupBy = node->
dump();
971 if ( values.count() > 2 )
973 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
976 if ( !nl || nl->value().isValid() )
982 if ( orderByPos >= 0 && values.count() > orderByPos )
984 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
987 if ( !nl || nl->value().isValid() )
989 orderBy = node->
dump();
997 if ( !groupBy.isEmpty() )
1000 QVariant groupByValue = groupByExp.evaluate( context );
1001 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
1004 if ( !parameters.
filter.isEmpty() )
1005 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
1007 parameters.
filter = groupByClause;
1013 bool isStatic =
true;
1014 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1015 for (
const QString &varName : refVars )
1018 if ( scope && !scope->
isStatic( varName ) )
1029 const QString contextHash = context->
uniqueHash( ok, refVars );
1032 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5:%6" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
1033 orderBy, contextHash );
1038 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1050 subContext.appendScope( subScope );
1052 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1056 if ( !error.isEmpty() )
1057 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1059 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1164 if ( values.count() > 3 )
1166 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1168 QVariant value = node->
eval( parent, context );
1170 parameters.
delimiter = value.toString();
1181 if ( values.count() > 3 )
1183 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1185 QVariant value = node->
eval( parent, context );
1187 parameters.
delimiter = value.toString();
1203 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1208 const double v = scale.toDouble( &ok );
1216 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1217 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1218 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1221 if ( testValue <= minValue )
1223 return QVariant( minValue );
1225 else if ( testValue >= maxValue )
1227 return QVariant( maxValue );
1231 return QVariant( testValue );
1237 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1238 return QVariant( std::floor( x ) );
1243 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1244 return QVariant( std::ceil( x ) );
1249 const QVariant value = values.at( 0 );
1250 if ( QgsExpressionUtils::isNull( value.isValid() ) )
1252 return QVariant(
false );
1254 else if ( value.userType() == QMetaType::QString )
1257 return QVariant( !value.toString().isEmpty() );
1259 else if ( QgsExpressionUtils::isList( value ) )
1261 return !value.toList().isEmpty();
1263 return QVariant( value.toBool() );
1267 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1271 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1275 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1280 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1281 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1282 if ( format.isEmpty() && !language.isEmpty() )
1284 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1285 return QVariant( QDateTime() );
1288 if ( format.isEmpty() && language.isEmpty() )
1289 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1291 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1292 QLocale locale = QLocale();
1293 if ( !language.isEmpty() )
1295 locale = QLocale( language );
1298 QDateTime datetime = locale.toDateTime( datetimestring, format );
1299 if ( !datetime.isValid() )
1301 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1302 datetime = QDateTime();
1304 return QVariant( datetime );
1309 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1310 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1311 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1313 const QDate date( year, month, day );
1314 if ( !date.isValid() )
1316 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1319 return QVariant( date );
1324 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1325 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1326 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1328 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1329 if ( !time.isValid() )
1331 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1334 return QVariant( time );
1339 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1340 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1341 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1342 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1343 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1344 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1346 const QDate date( year, month, day );
1347 if ( !date.isValid() )
1349 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1352 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1353 if ( !time.isValid() )
1355 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1358 return QVariant( QDateTime( date, time ) );
1363 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1364 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1365 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1366 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1367 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1368 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1369 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1371 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1376 for (
const QVariant &value : values )
1387 const QVariant val1 = values.at( 0 );
1388 const QVariant val2 = values.at( 1 );
1398 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1399 return QVariant( str.toLower() );
1403 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1404 return QVariant( str.toUpper() );
1408 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1409 QStringList elems = str.split(
' ' );
1410 for (
int i = 0; i < elems.size(); i++ )
1412 if ( elems[i].size() > 1 )
1413 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1415 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1420 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1421 return QVariant( str.trimmed() );
1426 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1428 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1430 const QRegularExpression re( QStringLiteral(
"^([%1]*)" ).arg( QRegularExpression::escape( characters ) ) );
1431 str.replace( re, QString() );
1432 return QVariant( str );
1437 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1439 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1441 const QRegularExpression re( QStringLiteral(
"([%1]*)$" ).arg( QRegularExpression::escape( characters ) ) );
1442 str.replace( re, QString() );
1443 return QVariant( str );
1448 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1449 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1455 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1456 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1462 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1463 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1465 return ( dist < 0 ? QVariant() : QVariant(
QgsStringUtils::hammingDistance( string1, string2, true ) ) );
1470 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1476 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1477 return QVariant( QString( character ) );
1482 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1484 if ( value.isEmpty() )
1489 int res = value.at( 0 ).unicode();
1490 return QVariant( res );
1495 if ( values.length() == 2 || values.length() == 3 )
1497 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1498 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1500 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1513 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent,
true );
1517 return QVariant( geom.
length() );
1523 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1524 return QVariant( str.length() );
1529 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1534 double totalLength = 0;
1537 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1539 totalLength += line->length3D();
1543 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1544 totalLength += segmentized->length3D();
1553 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1555 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1556 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1557 QVector< QPair< QString, QString > > mapItems;
1559 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1561 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1565 std::sort( mapItems.begin(),
1567 [](
const QPair< QString, QString > &pair1,
1568 const QPair< QString, QString > &pair2 )
1570 return ( pair1.first.length() > pair2.first.length() );
1573 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1575 str = str.replace( it->first, it->second );
1578 return QVariant( str );
1580 else if ( values.count() == 3 )
1582 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1583 QVariantList before;
1585 bool isSingleReplacement =
false;
1587 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1589 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1593 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1596 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1598 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1599 isSingleReplacement =
true;
1603 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1606 if ( !isSingleReplacement && before.length() != after.length() )
1608 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1612 for (
int i = 0; i < before.length(); i++ )
1614 str = str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1617 return QVariant( str );
1621 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1628 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1629 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1630 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1632 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1633 if ( !re.isValid() )
1635 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1638 return QVariant( str.replace( re, after ) );
1643 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1644 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1646 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1647 if ( !re.isValid() )
1649 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1652 return QVariant( ( str.indexOf( re ) + 1 ) );
1657 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1658 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1659 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1661 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1662 if ( !re.isValid() )
1664 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1668 QRegularExpressionMatch matches = re.match( str );
1669 if ( matches.hasMatch() )
1672 QStringList list = matches.capturedTexts();
1675 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1677 array += ( !( *it ).isEmpty() ) ? *it : empty;
1680 return QVariant( array );
1690 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1691 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1693 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1694 if ( !re.isValid() )
1696 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1701 QRegularExpressionMatch match = re.match( str );
1702 if ( match.hasMatch() )
1705 if ( match.lastCapturedIndex() > 0 )
1708 return QVariant( match.captured( 1 ) );
1713 return QVariant( match.captured( 0 ) );
1718 return QVariant(
"" );
1724 QString uuid = QUuid::createUuid().toString();
1725 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1726 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1727 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1728 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1734 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1737 QString str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1738 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1741 if ( values.at( 2 ).isValid() )
1742 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1748 from = str.size() + from;
1754 else if ( from > 0 )
1762 len = str.size() + len - from;
1769 return QVariant( str.mid( from, len ) );
1775 return QVariant(
static_cast< int >( f.
id() ) );
1780 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1781 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1782 bool foundLayer =
false;
1783 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1785 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1786 if ( !layer || !layer->dataProvider() )
1788 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1792 if ( bandNb < 1 || bandNb > layer->bandCount() )
1794 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1800 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1808 if ( multiPoint.count() == 1 )
1810 point = multiPoint[0];
1819 double value = layer->dataProvider()->sample( point, bandNb );
1820 return std::isnan( value ) ? QVariant() : value;
1826 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1837 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1838 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1840 bool foundLayer =
false;
1841 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1843 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1844 if ( !layer || !layer->dataProvider() )
1846 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1850 if ( bandNb < 1 || bandNb > layer->bandCount() )
1852 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1856 if ( std::isnan( value ) )
1858 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1862 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1867 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1868 if ( data.isEmpty() )
1874 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1875 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1878 if ( field.isColor() || field.isRamp() )
1882 result.insert( fields.at( idx ).name, data.at( idx ) );
1890 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1911 if ( values.size() == 1 )
1913 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1916 else if ( values.size() == 2 )
1918 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1919 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1923 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1932 QString table { R
"html(
1935 <tr><th>%1</th></tr>
1938 <tr><td>%2</td></tr>
1942 if ( values.size() == 1 )
1944 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1948 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
1952 if ( dict.isEmpty() )
1957 QStringList headers;
1960 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1962 headers.push_back( it.key().toHtmlEscaped() );
1963 cells.push_back( it.value().toString( ).toHtmlEscaped() );
1966 return table.arg( headers.join( QLatin1String(
"</th><th>" ) ), cells.join( QLatin1String(
"</td><td>" ) ) );
1971 QString table { R
"html(
1976 if ( values.size() == 1 )
1978 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1982 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
1986 if ( dict.isEmpty() )
1993 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1995 rows.append( QStringLiteral(
"<dt>%1</dt><dd>%2</dd>" ).arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
1998 return table.arg( rows );
2006 layer = context->
variable( QStringLiteral(
"layer" ) );
2011 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
2013 layer = node->
eval( parent, context );
2024 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2028 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
2029 if ( strength == QLatin1String(
"hard" ) )
2033 else if ( strength == QLatin1String(
"soft" ) )
2038 bool foundLayer =
false;
2039 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2041 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2044 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2050 for (
int i = 0; i < fields.
size(); i++ )
2065 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2077 layer = context->
variable( QStringLiteral(
"layer" ) );
2082 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2084 layer = node->
eval( parent, context );
2095 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2099 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2100 if ( strength == QLatin1String(
"hard" ) )
2104 else if ( strength == QLatin1String(
"soft" ) )
2109 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2111 bool foundLayer =
false;
2112 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2114 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2121 if ( fieldIndex == -1 )
2123 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2134 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2150 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2155 for (
int i = 0; i < fields.
count(); ++i )
2169 if ( values.isEmpty() )
2172 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2174 else if ( values.size() == 1 )
2176 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2177 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2179 else if ( values.size() == 2 )
2181 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2182 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2186 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2193 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2199 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2205 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2207 const QString fieldName { fields.
at( fieldIndex ).
name() };
2208 const QVariant attributeVal = feature.
attribute( fieldIndex );
2209 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
2212 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2221 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
2233 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2235 result.insert( fields.
at( fieldIndex ).
name(), value );
2251 bool evaluate =
true;
2255 if ( values.isEmpty() )
2258 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2260 else if ( values.size() == 1 )
2262 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2263 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2265 else if ( values.size() == 2 )
2267 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2268 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2270 else if ( values.size() == 3 )
2272 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2273 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2274 evaluate = values.value( 2 ).toBool();
2280 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2284 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2316 subContext.setFeature( feature );
2325 exp.prepare( &subContext );
2326 return exp.evaluate( &subContext ).toString();
2332 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2337 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2344 if ( values.isEmpty() )
2347 layer = context->
variable( QStringLiteral(
"layer" ) );
2349 else if ( values.size() == 1 )
2351 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2352 layer = context->
variable( QStringLiteral(
"layer" ) );
2354 else if ( values.size() == 2 )
2356 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2357 layer = values.at( 0 );
2361 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2365 bool foundLayer =
false;
2366 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2368 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2369 if ( !layer || !feature.
isValid() )
2386 if ( values.isEmpty() )
2387 layer = context->
variable( QStringLiteral(
"layer" ) );
2388 else if ( values.count() == 1 )
2389 layer = values.at( 0 );
2392 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2396 bool foundLayer =
false;
2397 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2399 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2415 static QMap<QString, qlonglong> counterCache;
2416 QVariant functionResult;
2418 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2422 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2427 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
2428 if ( database.isEmpty() )
2430 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2435 database = databaseArgument;
2438 const QString table = values.at( 1 ).toString();
2439 const QString idColumn = values.at( 2 ).toString();
2440 const QString filterAttribute = values.at( 3 ).toString();
2441 const QVariant filterValue = values.at( 4 ).toString();
2442 const QVariantMap defaultValues = values.at( 5 ).toMap();
2448 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2451 functionResult = QVariant();
2455 QString errorMessage;
2456 QString currentValSql;
2458 qlonglong nextId = 0;
2459 bool cachedMode =
false;
2460 bool valueRetrieved =
false;
2462 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2469 auto cachedCounter = counterCache.find( cacheString );
2471 if ( cachedCounter != counterCache.end() )
2473 qlonglong &cachedValue = cachedCounter.value();
2474 nextId = cachedValue;
2476 cachedValue = nextId;
2477 valueRetrieved =
true;
2482 if ( !cachedMode || !valueRetrieved )
2484 int result = SQLITE_ERROR;
2487 if ( !filterAttribute.isNull() )
2492 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2494 if ( result == SQLITE_OK )
2497 if ( sqliteStatement.
step() == SQLITE_ROW )
2503 if ( cachedMode && result == SQLITE_OK )
2505 counterCache.insert( cacheString, nextId );
2509 counterCache.remove( cacheString );
2512 valueRetrieved =
true;
2516 if ( valueRetrieved )
2525 if ( !filterAttribute.isNull() )
2531 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2534 vals << iter.value().toString();
2537 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2538 upsertSql += QLatin1String(
" VALUES " );
2539 upsertSql +=
'(' + vals.join(
',' ) +
')';
2541 int result = SQLITE_ERROR;
2545 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2552 result = sqliteDb.
exec( upsertSql, errorMessage );
2554 if ( result == SQLITE_OK )
2556 functionResult = QVariant( nextId );
2561 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2562 functionResult = QVariant();
2567 functionResult = QVariant();
2570 bool foundLayer =
false;
2571 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2573 fetchAndIncrementFunc( layer, QString() );
2577 const QString databasePath = values.at( 0 ).toString();
2580 fetchAndIncrementFunc(
nullptr, databasePath );
2584 return functionResult;
2590 for (
const QVariant &value : values )
2593 concat += QgsExpressionUtils::getStringValue( value, parent );
2600 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2601 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2606 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2607 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2608 return string.right( pos );
2613 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2614 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2615 return string.left( pos );
2620 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2621 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2622 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2623 return string.leftJustified( length, fill.at( 0 ),
true );
2628 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2629 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2630 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2631 return string.rightJustified( length, fill.at( 0 ),
true );
2636 if ( values.size() < 1 )
2638 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2642 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2643 for (
int n = 1; n < values.length(); n++ )
2645 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2653 return QVariant( QDateTime::currentDateTime() );
2658 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2659 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2660 if ( format.isEmpty() && !language.isEmpty() )
2662 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2663 return QVariant( QDate() );
2666 if ( format.isEmpty() && language.isEmpty() )
2667 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2669 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2670 QLocale locale = QLocale();
2671 if ( !language.isEmpty() )
2673 locale = QLocale( language );
2676 QDate date = locale.toDate( datestring, format );
2677 if ( !date.isValid() )
2679 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2682 return QVariant( date );
2687 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2688 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2689 if ( format.isEmpty() && !language.isEmpty() )
2691 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2692 return QVariant( QTime() );
2695 if ( format.isEmpty() && language.isEmpty() )
2696 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2698 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2699 QLocale locale = QLocale();
2700 if ( !language.isEmpty() )
2702 locale = QLocale( language );
2705 QTime time = locale.toTime( timestring, format );
2706 if ( !time.isValid() )
2708 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2711 return QVariant( time );
2716 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2725 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2726 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2727 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2729 QString formatString;
2730 if ( values.count() > 3 )
2731 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2734 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2738 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2742 else if ( ! formatString.isEmpty() )
2744 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2748 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2752 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2758 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2766 return floatToDegreeFormat( format, values, context, parent, node );
2773 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2775 return ok ? QVariant( value ) : QVariant();
2781 return floatToDegreeFormat( format, values, context, parent, node );
2786 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2787 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2788 qint64 seconds = d2.secsTo( d1 );
2789 return QVariant::fromValue(
QgsInterval( seconds ) );
2794 if ( !values.at( 0 ).canConvert<QDate>() )
2797 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2798 if ( !date.isValid() )
2803 return date.dayOfWeek() % 7;
2808 QVariant value = values.at( 0 );
2809 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2812 return QVariant( inter.
days() );
2816 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2817 return QVariant( d1.date().day() );
2823 QVariant value = values.at( 0 );
2824 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2827 return QVariant( inter.
years() );
2831 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2832 return QVariant( d1.date().year() );
2838 QVariant value = values.at( 0 );
2839 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2842 return QVariant( inter.
months() );
2846 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2847 return QVariant( d1.date().month() );
2853 QVariant value = values.at( 0 );
2854 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2857 return QVariant( inter.
weeks() );
2861 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2862 return QVariant( d1.date().weekNumber() );
2868 QVariant value = values.at( 0 );
2869 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2872 return QVariant( inter.
hours() );
2876 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2877 return QVariant( t1.hour() );
2883 QVariant value = values.at( 0 );
2884 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2887 return QVariant( inter.
minutes() );
2891 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2892 return QVariant( t1.minute() );
2898 QVariant value = values.at( 0 );
2899 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2902 return QVariant( inter.
seconds() );
2906 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2907 return QVariant( t1.second() );
2913 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2916 return QVariant( dt.toMSecsSinceEpoch() );
2926 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2928 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2933 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2936 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2939 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2945 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2948 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2955#define ENSURE_GEOM_TYPE(f, g, geomtype) \
2956 if ( !(f).hasGeometry() ) \
2957 return QVariant(); \
2958 QgsGeometry g = (f).geometry(); \
2959 if ( (g).type() != (geomtype) ) \
2966 if ( g.isMultipart() )
2968 return g.asMultiPoint().at( 0 ).x();
2972 return g.asPoint().x();
2980 if ( g.isMultipart() )
2982 return g.asMultiPoint().at( 0 ).y();
2986 return g.asPoint().y();
3000 if ( g.isEmpty() || !abGeom->
is3D() )
3005 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
3011 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
3013 if ( collection->numGeometries() > 0 )
3015 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3026 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3032 return QVariant( isValid );
3037 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3041 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3042#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
3047 if ( methodString.compare( QLatin1String(
"linework" ), Qt::CaseInsensitive ) == 0 )
3049 else if ( methodString.compare( QLatin1String(
"structure" ), Qt::CaseInsensitive ) == 0 )
3052 const bool keepCollapsed = values.value( 2 ).toBool();
3057 valid = geom.
makeValid( method, keepCollapsed );
3061 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3065 return QVariant::fromValue( valid );
3070 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3076 for (
int i = 0; i < multiGeom.size(); ++i )
3078 array += QVariant::fromValue( multiGeom.at( i ) );
3086 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3098 QVariant result( centroid.asPoint().
x() );
3104 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3116 QVariant result( centroid.asPoint().
y() );
3122 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3132 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3140 if ( collection->numGeometries() == 1 )
3142 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3153 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3163 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3171 if ( collection->numGeometries() == 1 )
3173 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3184 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3189 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3216 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3233 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3250 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3255 bool ignoreClosing =
false;
3256 if ( values.length() > 1 )
3258 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3268 bool skipLast =
false;
3269 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3274 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3286 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3297 for (
int i = 0; i < line->numPoints() - 1; ++i )
3301 << line->pointN( i )
3302 << line->pointN( i + 1 ) );
3313 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3323 if ( collection->numGeometries() == 1 )
3325 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
3330 if ( !curvePolygon )
3334 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3340 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3346 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3356 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3362 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3368 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3377 return QVariant::fromValue(
QgsGeometry( boundary ) );
3382 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3391 return QVariant::fromValue( merged );
3396 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3400 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3405 if ( sharedPaths.
isNull() )
3408 return QVariant::fromValue( sharedPaths );
3414 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3419 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3422 if ( simplified.
isNull() )
3430 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3435 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3440 if ( simplified.
isNull() )
3448 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3453 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3454 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3455 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3456 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3458 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3467 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3472 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3473 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3474 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3485 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3490 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3491 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3492 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3493 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3494 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3497 minAmplitude, maxAmplitude, seed );
3506 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3511 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3512 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3513 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3524 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3529 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3530 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3531 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3532 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3533 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3536 minAmplitude, maxAmplitude, seed );
3545 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3550 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3551 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3552 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3563 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3568 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3569 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3570 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3571 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3572 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3575 minAmplitude, maxAmplitude, seed );
3584 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3589 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3590 QVector< double > dashPattern;
3591 dashPattern.reserve( pattern.size() );
3592 for (
const QVariant &value : std::as_const( pattern ) )
3595 double v = value.toDouble( &ok );
3602 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3607 if ( dashPattern.size() % 2 != 0 )
3609 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3613 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3615 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3617 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3619 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3621 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3623 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3627 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3631 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3633 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3635 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3637 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3639 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3641 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3645 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3649 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3651 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3653 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3655 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3659 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3663 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3674 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3679 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3681 if ( densified.
isNull() )
3689 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3694 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3696 if ( densified.
isNull() )
3705 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3707 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3714 QVector< QgsGeometry > parts;
3715 parts.reserve( list.size() );
3716 for (
const QVariant &value : std::as_const( list ) )
3718 QgsGeometry part = QgsExpressionUtils::getGeometry( value, parent );
3729 if ( values.count() < 2 || values.count() > 4 )
3731 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3735 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3736 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3737 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3738 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3739 switch ( values.count() )
3753 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3754 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3755 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3761 if ( values.empty() )
3766 QVector<QgsPoint> points;
3767 points.reserve( values.count() );
3769 auto addPoint = [&points](
const QgsGeometry & geom )
3777 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3784 for (
const QVariant &value : values )
3786 if ( value.userType() == QMetaType::Type::QVariantList )
3788 const QVariantList list = value.toList();
3789 for (
const QVariant &v : list )
3791 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3796 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3800 if ( points.count() < 2 )
3808 if ( values.count() < 1 )
3810 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3814 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3822 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3824 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3831 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3836 if ( !exteriorRing )
3839 polygon->setExteriorRing( exteriorRing->
segmentize() );
3842 for (
int i = 1; i < values.count(); ++i )
3844 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3851 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3858 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3866 polygon->addInteriorRing( ring->
segmentize() );
3869 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3874 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3875 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3876 lineString->clear();
3878 for (
const QVariant &value : values )
3880 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3887 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3894 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3902 lineString->addVertex( *point );
3905 tr->setExteriorRing( lineString.release() );
3907 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3912 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3919 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3920 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3927 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3934 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3942 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3947 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3954 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3955 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3956 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3957 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3963 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3970 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3977 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3978 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3984 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3991 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3998 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
4001 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
4008 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
4012 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
4019 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4026 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
4033 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4048 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4054 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4060 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4061 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4069 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4075 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4081 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4090 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4093 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4094 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4095 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
4114 return QVariant::fromValue( geom.
vertexAt( idx ) );
4122 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4124 const QVariant v = pointAt( geom, idx, parent );
4127 return QVariant( v.value<
QgsPoint>().
x() );
4133 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4135 return fcnOldXat( values, f, parent, node );
4137 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4139 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4142 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4148 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4150 const QVariant v = pointAt( geom, vertexNumber, parent );
4152 return QVariant( v.value<
QgsPoint>().
x() );
4162 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4164 const QVariant v = pointAt( geom, idx, parent );
4167 return QVariant( v.value<
QgsPoint>().
y() );
4173 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4175 return fcnOldYat( values, f, parent, node );
4177 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4179 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4182 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4188 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4190 const QVariant v = pointAt( geom, vertexNumber, parent );
4192 return QVariant( v.value<
QgsPoint>().
y() );
4199 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4205 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4207 const QVariant v = pointAt( geom, vertexNumber, parent );
4209 return QVariant( v.value<
QgsPoint>().
z() );
4216 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4222 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4224 const QVariant v = pointAt( geom, vertexNumber, parent );
4226 return QVariant( v.value<
QgsPoint>().
m() );
4245 return QVariant::fromValue( geom );
4253 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4255 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4261 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4267 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4272 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4279 ogcContext.
layer = mapLayerPtr.data();
4280 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
4284 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4299 return QVariant( area );
4303 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating area" ) );
4315 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4320 return QVariant( geom.
area() );
4334 return QVariant( len );
4338 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating length" ) );
4359 return QVariant( len );
4363 parent->
setEvalErrorString( QObject::tr(
"An error occurred while calculating perimeter" ) );
4369 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4375 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4381 return QVariant( geom.
length() );
4386 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4387 return QVariant( geom.
isNull() ? 0 : geom.constGet()->nCoordinates() );
4392 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4401 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4410 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4425 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
4426 if ( !curvePolygon )
4429 return QVariant( curvePolygon->
isEmpty() ? 0 : curvePolygon->numInteriorRings() );
4438 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4445 return QVariant( curvePolygon->
ringCount() );
4447 bool foundPoly =
false;
4455 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
4456 if ( !curvePolygon )
4467 return QVariant( ringCount );
4472 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4474 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4480 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4486 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4492 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4501 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4507 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4513 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4519 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4525 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4533 double max = std::numeric_limits< double >::lowest();
4537 double z = ( *it ).z();
4543 if ( max == std::numeric_limits< double >::lowest() )
4546 return QVariant( max );
4551 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4559 double min = std::numeric_limits< double >::max();
4563 double z = ( *it ).z();
4569 if ( min == std::numeric_limits< double >::max() )
4572 return QVariant( min );
4577 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4585 double min = std::numeric_limits< double >::max();
4589 double m = ( *it ).m();
4595 if ( min == std::numeric_limits< double >::max() )
4598 return QVariant( min );
4603 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4611 double max = std::numeric_limits< double >::lowest();
4615 double m = ( *it ).m();
4621 if ( max == std::numeric_limits< double >::lowest() )
4624 return QVariant( max );
4629 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4630 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
4633 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
4642 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4646 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4655 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4660 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4671 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4675 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4677 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4682 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4686 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4693 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4701 return QVariant::fromValue( curve->
isClosed() );
4706 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4719 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4720 closedLine->close();
4722 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4732 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4734 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4735 closedLine->close();
4737 closed->addGeometry( closedLine.release() );
4740 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4748 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4752 return QVariant::fromValue( fGeom.
isEmpty() );
4758 return QVariant::fromValue(
true );
4760 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4761 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4766 if ( values.length() < 2 || values.length() > 3 )
4769 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4770 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4777 if ( values.length() == 2 )
4780 QString result = engine->relate( sGeom.
constGet() );
4781 return QVariant::fromValue( result );
4786 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4787 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4788 return QVariant::fromValue( result );
4794 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4795 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4800 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4801 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4802 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4806 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4807 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4808 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4812 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4813 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4814 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4818 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4819 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4820 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4824 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4825 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4826 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4830 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4831 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4832 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4836 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4837 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4838 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4843 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4844 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4845 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4846 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4847 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4848 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4851 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4853 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4857 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4859 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4863 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4869 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4871 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4876 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4878 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4883 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4885 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4890 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4891 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4898 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4905 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4909 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4910 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4911 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4912 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4915 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4921 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4924 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4928 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4929 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4930 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4933 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4939 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4942 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4946 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4949 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4955 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4956 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4957 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4958 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4959 if ( joinInt < 1 || joinInt > 3 )
4963 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4966 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4972 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4973 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4974 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4976 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4977 if ( joinInt < 1 || joinInt > 3 )
4981 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4984 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4990 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4991 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4992 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4995 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5001 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5002 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5003 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5005 return QVariant::fromValue( fGeom );
5010 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5011 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5012 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
5014 const bool perPart = values.value( 3 ).toBool();
5021 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
5024 const QgsPointXY partCenter = ( *it )->boundingBox().center();
5025 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
5026 t.rotate( -rotation );
5027 t.translate( -partCenter.
x(), -partCenter.
y() );
5028 ( *it )->transform( t );
5030 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
5042 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5050 fGeom.
rotate( rotation, pt );
5051 return QVariant::fromValue( fGeom );
5057 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5058 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5059 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5060 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
5071 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5079 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5080 t.scale( xScale, yScale );
5081 t.translate( -pt.
x(), -pt.
y() );
5083 return QVariant::fromValue( fGeom );
5088 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5094 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5095 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5097 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5099 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5100 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5102 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5103 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5104 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5105 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5116 QTransform transform;
5117 transform.translate( deltaX, deltaY );
5118 transform.rotate( rotationZ );
5119 transform.scale( scaleX, scaleY );
5120 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5122 return QVariant::fromValue( fGeom );
5128 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5130 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5135 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5137 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5143 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5144 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5146 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5152 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5154 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5158#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5163 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5164 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5165 const bool allowHoles = values.value( 2 ).toBool();
5167 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5180 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5182 if ( values.length() == 2 )
5183 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5191 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5197 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5199 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5205 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5211 double area,
angle, width, height;
5224 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5225 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5227 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5233 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5240 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
5245 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5253 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
5255 reversed->addGeometry( curve->
reversed() );
5262 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5269 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5280 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
5289 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5295 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5296 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5297 return QVariant( fGeom.
distance( sGeom ) );
5302 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5303 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5306 if ( values.length() == 3 && values.at( 2 ).isValid() )
5308 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5309 densify = std::clamp( densify, 0.0, 1.0 );
5317 return res > -1 ? QVariant( res ) : QVariant();
5322 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5323 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5325 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5330 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5331 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5333 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5338 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5339 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5341 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5347 if ( values.length() < 1 || values.length() > 2 )
5350 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5352 if ( values.length() == 2 )
5353 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5354 QString wkt = fGeom.
asWkt( prec );
5355 return QVariant( wkt );
5360 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5361 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5366 if ( values.length() != 2 )
5368 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5372 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5373 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5375 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5382 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5387 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5394 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5401 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5408 if ( pt1->
y() < pt2->
y() )
5410 else if ( pt1->
y() > pt2->
y() )
5418 if ( pt1->
x() < pt2->
x() )
5420 else if ( pt1->
x() > pt2->
x() )
5421 return M_PI + ( M_PI_2 );
5426 if ( pt1->
x() < pt2->
x() )
5428 if ( pt1->
y() < pt2->
y() )
5430 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
5434 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5441 if ( pt1->
y() > pt2->
y() )
5443 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5448 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5449 + ( M_PI + ( M_PI_2 ) );
5456 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5457 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5458 QString sourceCrs = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5459 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
5463 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
5471 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
5480 if ( sourceCrs.isEmpty() )
5482 sourceCrs = context->
variable( QStringLiteral(
"layer_crs" ) ).toString();
5485 if ( ellipsoid.isEmpty() )
5487 ellipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
5494 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
5502 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
5508 const double bearing = da.
bearing( point1, point2 );
5509 if ( std::isfinite( bearing ) )
5511 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
5524 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5528 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
5532 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5533 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5534 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5537 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
5544 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5545 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5547 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5554 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5558 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5565 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5573 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
5583 if ( values.length() != 3 )
5586 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5587 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5588 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5592 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVa