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;
207 if ( mReferencedColumnsFunc )
208 return mReferencedColumnsFunc( node );
210 return mReferencedColumns;
216 return mIsStaticFunc( node, parent, context );
224 return mPrepareFunc( node, parent, context );
236 mIsStaticFunc =
nullptr;
242 mPrepareFunc = prepareFunc;
247 if ( node && node->
args() )
249 const QList< QgsExpressionNode * > argList = node->
args()->
list();
252 if ( !argNode->isStatic( parent, context ) )
262 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
263 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
264 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
266 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
273 double current = start + step;
274 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
289 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
291 if ( name == QLatin1String(
"feature" ) )
293 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
295 else if ( name == QLatin1String(
"id" ) )
297 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
299 else if ( name == QLatin1String(
"geometry" ) )
315 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
324 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
326 return expression.evaluate( context );
331 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
332 return QVariant( std::sqrt( x ) );
337 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
338 return QVariant( std::fabs( val ) );
343 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
344 return ( deg * M_PI ) / 180;
348 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return ( 180 * rad ) / M_PI;
353 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
354 return QVariant( std::sin( x ) );
358 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
359 return QVariant( std::cos( x ) );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
364 return QVariant( std::tan( x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::asin( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
374 return QVariant( std::acos( x ) );
378 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
379 return QVariant( std::atan( x ) );
383 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
384 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
385 return QVariant( std::atan2( y, x ) );
389 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
390 return QVariant( std::exp( x ) );
394 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
397 return QVariant( std::log( x ) );
401 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
404 return QVariant( log10( x ) );
408 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
409 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
410 if ( x <= 0 || b <= 0 )
412 return QVariant( std::log( x ) / std::log( b ) );
416 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
417 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
421 std::random_device rd;
422 std::mt19937_64 generator( rd() );
424 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
427 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
430 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
435 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
436 std::hash<std::string> hasher;
437 seed = hasher( seedStr.toStdString() );
439 generator.seed( seed );
443 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
444 return QVariant( min + f * ( max - min ) );
448 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
449 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
453 std::random_device rd;
454 std::mt19937_64 generator( rd() );
456 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
459 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
462 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
467 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
468 std::hash<std::string> hasher;
469 seed = hasher( seedStr.toStdString() );
471 generator.seed( seed );
474 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
475 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
476 return QVariant( randomInteger );
479 return QVariant(
int( randomInteger ) );
484 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
485 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
486 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
487 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
488 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
490 if ( domainMin >= domainMax )
492 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
497 if ( val >= domainMax )
501 else if ( val <= domainMin )
507 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
508 double c = rangeMin - ( domainMin * m );
511 return QVariant( m * val +
c );
516 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
517 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
518 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
519 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
520 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
521 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
523 if ( domainMin >= domainMax )
525 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
535 if ( val >= domainMax )
539 else if ( val <= domainMin )
545 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
550 QVariant result( QVariant::Double );
551 double maxVal = std::numeric_limits<double>::quiet_NaN();
552 for (
const QVariant &val : values )
555 if ( std::isnan( maxVal ) )
559 else if ( !std::isnan( testVal ) )
561 maxVal = std::max( maxVal, testVal );
565 if ( !std::isnan( maxVal ) )
567 result = QVariant( maxVal );
574 QVariant result( QVariant::Double );
575 double minVal = std::numeric_limits<double>::quiet_NaN();
576 for (
const QVariant &val : values )
579 if ( std::isnan( minVal ) )
583 else if ( !std::isnan( testVal ) )
585 minVal = std::min( minVal, testVal );
589 if ( !std::isnan( minVal ) )
591 result = QVariant( minVal );
603 QVariant value = node->
eval( parent, context );
608 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
612 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
617 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
619 value = node->
eval( parent, context );
625 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
630 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
632 QString subExpression = node->
dump();
636 if ( values.count() > 3 )
638 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
641 if ( !nl || nl->value().isValid() )
646 if ( values.count() > 4 )
648 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
650 value = node->
eval( parent, context );
657 if ( values.count() > 5 )
659 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
662 if ( !nl || nl->value().isValid() )
664 orderBy = node->
dump();
669 QString aggregateError;
677 bool isStatic =
true;
678 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
679 || filterExp.referencedVariables().contains( QString() )
680 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
681 || subExp.referencedVariables().contains( QString() ) )
687 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
688 for (
const QString &varName : refVars )
691 if ( scope && !scope->
isStatic( varName ) )
701 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
702 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
706 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
717 subContext.appendScope( subScope );
718 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
730 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
734 if ( !aggregateError.isEmpty() )
735 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
737 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
748 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
756 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
760 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
769 QVariant value = node->
eval( parent, context );
771 QString relationId = value.toString();
778 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
780 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
785 relation = relations.at( 0 );
792 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
794 value = node->
eval( parent, context );
800 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
805 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
807 QString subExpression = node->
dump();
811 if ( values.count() > 3 )
813 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
815 value = node->
eval( parent, context );
822 if ( values.count() > 4 )
824 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
827 if ( !nl || nl->value().isValid() )
829 orderBy = node->
dump();
840 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->id(),
841 QString::number(
static_cast< int >( aggregate ) ),
854 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
858 if ( !error.isEmpty() )
859 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
861 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
875 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
883 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
887 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
896 QString subExpression = node->
dump();
900 if ( values.count() > 1 )
902 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
905 if ( !nl || nl->value().isValid() )
906 groupBy = node->
dump();
910 if ( values.count() > 2 )
912 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
915 if ( !nl || nl->value().isValid() )
921 if ( orderByPos >= 0 && values.count() > orderByPos )
923 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
926 if ( !nl || nl->value().isValid() )
928 orderBy = node->
dump();
936 if ( !groupBy.isEmpty() )
939 QVariant groupByValue = groupByExp.evaluate( context );
940 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
943 if ( !parameters.
filter.isEmpty() )
944 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
946 parameters.
filter = groupByClause;
952 bool isStatic =
true;
953 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
954 for (
const QString &varName : refVars )
957 if ( scope && !scope->
isStatic( varName ) )
967 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
968 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
972 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
984 subContext.appendScope( subScope );
986 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
990 if ( !error.isEmpty() )
991 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
993 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1098 if ( values.count() > 3 )
1100 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1102 QVariant value = node->
eval( parent, context );
1104 parameters.
delimiter = value.toString();
1115 if ( values.count() > 3 )
1117 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1119 QVariant value = node->
eval( parent, context );
1121 parameters.
delimiter = value.toString();
1137 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1142 const double v = scale.toDouble( &ok );
1150 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1151 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1152 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1155 if ( testValue <= minValue )
1157 return QVariant( minValue );
1159 else if ( testValue >= maxValue )
1161 return QVariant( maxValue );
1165 return QVariant( testValue );
1171 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1172 return QVariant( std::floor( x ) );
1177 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1178 return QVariant( std::ceil( x ) );
1183 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1187 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1191 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1196 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1197 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1198 if ( format.isEmpty() && !language.isEmpty() )
1200 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1201 return QVariant( QDateTime() );
1204 if ( format.isEmpty() && language.isEmpty() )
1205 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1207 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1208 QLocale locale = QLocale();
1209 if ( !language.isEmpty() )
1211 locale = QLocale( language );
1214 QDateTime datetime = locale.toDateTime( datetimestring, format );
1215 if ( !datetime.isValid() )
1217 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1218 datetime = QDateTime();
1220 return QVariant( datetime );
1225 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1226 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1227 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1229 const QDate date( year, month, day );
1230 if ( !date.isValid() )
1232 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1235 return QVariant( date );
1240 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1241 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1242 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1244 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1245 if ( !time.isValid() )
1247 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1250 return QVariant( time );
1255 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1256 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1257 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1258 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1259 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1260 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1262 const QDate date( year, month, day );
1263 if ( !date.isValid() )
1265 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1268 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1269 if ( !time.isValid() )
1271 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1274 return QVariant( QDateTime( date, time ) );
1279 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1280 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1281 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1282 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1283 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1284 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1285 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1287 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1292 for (
const QVariant &value : values )
1303 const QVariant val1 = values.at( 0 );
1304 const QVariant val2 = values.at( 1 );
1314 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1315 return QVariant(
str.toLower() );
1319 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1320 return QVariant(
str.toUpper() );
1324 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1325 QStringList elems =
str.split(
' ' );
1326 for (
int i = 0; i < elems.size(); i++ )
1328 if ( elems[i].size() > 1 )
1329 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1331 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1336 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1337 return QVariant(
str.trimmed() );
1342 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1343 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1349 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1350 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1356 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1357 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1364 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1370 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1371 return QVariant( QString( character ) );
1376 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1378 if ( value.isEmpty() )
1383 int res = value.at( 0 ).unicode();
1384 return QVariant( res );
1389 if ( values.length() == 2 || values.length() == 3 )
1391 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1392 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1394 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1405 if ( values.at( 0 ).userType() == QMetaType::type(
"QgsGeometry" ) )
1408 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1412 return QVariant( geom.
length() );
1416 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1417 return QVariant(
str.length() );
1422 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1427 double totalLength = 0;
1430 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1432 totalLength += line->length3D();
1436 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1437 totalLength += segmentized->length3D();
1446 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1448 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1449 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1450 QVector< QPair< QString, QString > > mapItems;
1452 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1454 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1458 std::sort( mapItems.begin(),
1460 [](
const QPair< QString, QString > &pair1,
1461 const QPair< QString, QString > &pair2 )
1463 return ( pair1.first.length() > pair2.first.length() );
1466 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1468 str =
str.replace( it->first, it->second );
1471 return QVariant(
str );
1473 else if ( values.count() == 3 )
1475 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1476 QVariantList before;
1478 bool isSingleReplacement =
false;
1480 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
1482 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1486 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1489 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1491 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1492 isSingleReplacement =
true;
1496 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1499 if ( !isSingleReplacement && before.length() != after.length() )
1501 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1505 for (
int i = 0; i < before.length(); i++ )
1507 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1510 return QVariant(
str );
1514 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1521 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1522 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1523 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1525 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1526 if ( !re.isValid() )
1528 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1531 return QVariant(
str.replace( re, after ) );
1536 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1537 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1539 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1540 if ( !re.isValid() )
1542 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1545 return QVariant( (
str.indexOf( re ) + 1 ) );
1550 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1551 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1552 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1554 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1555 if ( !re.isValid() )
1557 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1561 QRegularExpressionMatch matches = re.match(
str );
1562 if ( matches.hasMatch() )
1565 QStringList list = matches.capturedTexts();
1568 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1570 array += ( !( *it ).isEmpty() ) ? *it : empty;
1573 return QVariant( array );
1583 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1584 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1586 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1587 if ( !re.isValid() )
1589 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1594 QRegularExpressionMatch match = re.match(
str );
1595 if ( match.hasMatch() )
1598 if ( match.lastCapturedIndex() > 0 )
1601 return QVariant( match.captured( 1 ) );
1606 return QVariant( match.captured( 0 ) );
1611 return QVariant(
"" );
1617 QString uuid = QUuid::createUuid().toString();
1618 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1619 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1620 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1621 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1627 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1630 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1631 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1634 if ( values.at( 2 ).isValid() )
1635 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1641 from =
str.size() + from;
1647 else if ( from > 0 )
1655 len =
str.size() + len - from;
1662 return QVariant(
str.mid( from, len ) );
1668 return QVariant(
static_cast< int >( f.
id() ) );
1673 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1674 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1675 bool foundLayer =
false;
1676 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1678 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1679 if ( !layer || !layer->dataProvider() )
1681 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1685 if ( bandNb < 1 || bandNb > layer->bandCount() )
1687 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1693 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1700 QgsMultiPointXY multiPoint = geom.asMultiPoint();
1701 if ( multiPoint.count() == 1 )
1703 point = multiPoint[0];
1712 double value = layer->dataProvider()->sample( point, bandNb );
1713 return std::isnan( value ) ? QVariant() : value;
1719 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1730 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1731 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1733 bool foundLayer =
false;
1734 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1736 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1737 if ( !layer || !layer->dataProvider() )
1739 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1743 if ( bandNb < 1 || bandNb > layer->bandCount() )
1745 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1749 if ( std::isnan( value ) )
1751 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1755 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1760 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1761 if ( data.isEmpty() )
1767 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1768 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1775 result.insert( fields.at( idx ).name, data.at( idx ) );
1783 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1804 if ( values.size() == 1 )
1806 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1809 else if ( values.size() == 2 )
1811 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1812 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1816 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1825 QString table { R
"html(
1831 <tr><td>%2</td></tr>
1835 if ( values.size() == 1 )
1837 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1841 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
1845 if ( dict.isEmpty() )
1850 QStringList headers;
1853 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1855 headers.push_back( it.key().toHtmlEscaped() );
1856 cells.push_back( it.value().toString( ).toHtmlEscaped() );
1859 return table.arg( headers.join( QLatin1String(
"</th><th>" ) ), cells.join( QLatin1String(
"</td><td>" ) ) );
1864 QString table { R
"html(
1869 if ( values.size() == 1 )
1871 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1875 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
1879 if ( dict.isEmpty() )
1886 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1888 rows.append( QStringLiteral(
"<dt>%1</dt><dd>%2</dd>" ).arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
1891 return table.arg( rows );
1899 layer = context->
variable( QStringLiteral(
"layer" ) );
1904 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1906 layer = node->
eval( parent, context );
1917 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1921 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
1922 if ( strength == QLatin1String(
"hard" ) )
1926 else if ( strength == QLatin1String(
"soft" ) )
1931 bool foundLayer =
false;
1932 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
1934 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
1937 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
1943 for (
int i = 0; i < fields.
size(); i++ )
1958 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
1970 layer = context->
variable( QStringLiteral(
"layer" ) );
1975 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
1977 layer = node->
eval( parent, context );
1988 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
1992 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
1993 if ( strength == QLatin1String(
"hard" ) )
1997 else if ( strength == QLatin1String(
"soft" ) )
2002 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2004 bool foundLayer =
false;
2005 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2007 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2014 if ( fieldIndex == -1 )
2016 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2027 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2043 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2048 for (
int i = 0; i < fields.
count(); ++i )
2062 if ( values.isEmpty() )
2065 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2067 else if ( values.size() == 1 )
2069 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2070 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2072 else if ( values.size() == 2 )
2074 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2075 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2079 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2086 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2092 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2098 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2100 const QString fieldName { fields.
at( fieldIndex ).
name() };
2101 const QVariant attributeVal = feature.
attribute( fieldIndex );
2102 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
2105 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2114 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
2126 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2128 result.insert( fields.
at( fieldIndex ).
name(), value );
2144 bool evaluate =
true;
2148 if ( values.isEmpty() )
2151 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2153 else if ( values.size() == 1 )
2155 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2156 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2158 else if ( values.size() == 2 )
2160 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2161 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2163 else if ( values.size() == 3 )
2165 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2166 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2167 evaluate = values.value( 2 ).toBool();
2173 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2177 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2209 subContext.setFeature( feature );
2218 exp.prepare( &subContext );
2219 return exp.evaluate( &subContext ).toString();
2225 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2230 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2237 if ( values.isEmpty() )
2240 layer = context->
variable( QStringLiteral(
"layer" ) );
2242 else if ( values.size() == 1 )
2244 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2245 layer = context->
variable( QStringLiteral(
"layer" ) );
2247 else if ( values.size() == 2 )
2249 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2250 layer = values.at( 0 );
2254 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2258 bool foundLayer =
false;
2259 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2261 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2262 if ( !layer || !feature.
isValid() )
2264 return QVariant( QVariant::Bool );
2270 return QVariant( QVariant::Bool );
2279 if ( values.isEmpty() )
2280 layer = context->
variable( QStringLiteral(
"layer" ) );
2281 else if ( values.count() == 1 )
2282 layer = values.at( 0 );
2285 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2289 bool foundLayer =
false;
2290 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2292 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2295 return QVariant( QVariant::LongLong );
2301 return QVariant( QVariant::LongLong );
2308 static QMap<QString, qlonglong> counterCache;
2309 QVariant functionResult;
2311 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2315 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2320 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
2321 if ( database.isEmpty() )
2323 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2328 database = databaseArgument;
2331 const QString table = values.at( 1 ).toString();
2332 const QString idColumn = values.at( 2 ).toString();
2333 const QString filterAttribute = values.at( 3 ).toString();
2334 const QVariant filterValue = values.at( 4 ).toString();
2335 const QVariantMap defaultValues = values.at( 5 ).toMap();
2341 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2344 functionResult = QVariant();
2348 QString errorMessage;
2349 QString currentValSql;
2351 qlonglong nextId = 0;
2352 bool cachedMode =
false;
2353 bool valueRetrieved =
false;
2355 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2362 auto cachedCounter = counterCache.find( cacheString );
2364 if ( cachedCounter != counterCache.end() )
2366 qlonglong &cachedValue = cachedCounter.value();
2367 nextId = cachedValue;
2369 cachedValue = nextId;
2370 valueRetrieved =
true;
2375 if ( !cachedMode || !valueRetrieved )
2377 int result = SQLITE_ERROR;
2380 if ( !filterAttribute.isNull() )
2385 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2387 if ( result == SQLITE_OK )
2390 if ( sqliteStatement.
step() == SQLITE_ROW )
2396 if ( cachedMode && result == SQLITE_OK )
2398 counterCache.insert( cacheString, nextId );
2402 counterCache.remove( cacheString );
2405 valueRetrieved =
true;
2409 if ( valueRetrieved )
2418 if ( !filterAttribute.isNull() )
2424 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2427 vals << iter.value().toString();
2430 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2431 upsertSql += QLatin1String(
" VALUES " );
2432 upsertSql +=
'(' + vals.join(
',' ) +
')';
2434 int result = SQLITE_ERROR;
2438 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2445 result = sqliteDb.
exec( upsertSql, errorMessage );
2447 if ( result == SQLITE_OK )
2449 functionResult = QVariant( nextId );
2454 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2455 functionResult = QVariant();
2460 functionResult = QVariant();
2463 bool foundLayer =
false;
2464 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2466 fetchAndIncrementFunc( layer, QString() );
2470 const QString databasePath = values.at( 0 ).toString();
2473 fetchAndIncrementFunc(
nullptr, databasePath );
2477 return functionResult;
2483 for (
const QVariant &value : values )
2486 concat += QgsExpressionUtils::getStringValue( value, parent );
2493 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2494 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2499 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2500 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2501 return string.right( pos );
2506 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2507 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2508 return string.left( pos );
2513 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2514 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2515 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2516 return string.leftJustified( length, fill.at( 0 ),
true );
2521 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2522 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2523 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2524 return string.rightJustified( length, fill.at( 0 ),
true );
2529 if ( values.size() < 1 )
2531 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2535 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2536 for (
int n = 1; n < values.length(); n++ )
2538 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2546 return QVariant( QDateTime::currentDateTime() );
2551 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2552 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2553 if ( format.isEmpty() && !language.isEmpty() )
2555 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2556 return QVariant( QDate() );
2559 if ( format.isEmpty() && language.isEmpty() )
2560 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2562 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2563 QLocale locale = QLocale();
2564 if ( !language.isEmpty() )
2566 locale = QLocale( language );
2569 QDate date = locale.toDate( datestring, format );
2570 if ( !date.isValid() )
2572 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2575 return QVariant( date );
2580 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2581 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2582 if ( format.isEmpty() && !language.isEmpty() )
2584 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2585 return QVariant( QTime() );
2588 if ( format.isEmpty() && language.isEmpty() )
2589 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2591 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2592 QLocale locale = QLocale();
2593 if ( !language.isEmpty() )
2595 locale = QLocale( language );
2598 QTime time = locale.toTime( timestring, format );
2599 if ( !time.isValid() )
2601 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2604 return QVariant( time );
2609 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2618 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2619 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2620 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2622 QString formatString;
2623 if ( values.count() > 3 )
2624 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2626 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2627 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2631 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2635 else if ( ! formatString.isEmpty() )
2637 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2641 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2645 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2651 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2659 return floatToDegreeFormat( format, values, context, parent, node );
2666 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2668 return ok ? QVariant( value ) : QVariant();
2674 return floatToDegreeFormat( format, values, context, parent, node );
2679 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2680 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2681 qint64 seconds = d2.secsTo( d1 );
2682 return QVariant::fromValue(
QgsInterval( seconds ) );
2687 if ( !values.at( 0 ).canConvert<QDate>() )
2690 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2691 if ( !date.isValid() )
2696 return date.dayOfWeek() % 7;
2701 QVariant value = values.at( 0 );
2702 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2705 return QVariant( inter.
days() );
2709 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2710 return QVariant( d1.date().day() );
2716 QVariant value = values.at( 0 );
2717 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2720 return QVariant( inter.
years() );
2724 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2725 return QVariant( d1.date().year() );
2731 QVariant value = values.at( 0 );
2732 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2735 return QVariant( inter.
months() );
2739 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2740 return QVariant( d1.date().month() );
2746 QVariant value = values.at( 0 );
2747 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2750 return QVariant( inter.
weeks() );
2754 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2755 return QVariant( d1.date().weekNumber() );
2761 QVariant value = values.at( 0 );
2762 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2765 return QVariant( inter.
hours() );
2769 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2770 return QVariant( t1.hour() );
2776 QVariant value = values.at( 0 );
2777 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2780 return QVariant( inter.
minutes() );
2784 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2785 return QVariant( t1.minute() );
2791 QVariant value = values.at( 0 );
2792 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2795 return QVariant( inter.
seconds() );
2799 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2800 return QVariant( t1.second() );
2806 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2809 return QVariant( dt.toMSecsSinceEpoch() );
2819 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2821 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2826 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2829 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2832 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2838 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2841 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2848#define ENSURE_GEOM_TYPE(f, g, geomtype) \
2849 if ( !(f).hasGeometry() ) \
2850 return QVariant(); \
2851 QgsGeometry g = (f).geometry(); \
2852 if ( (g).type() != (geomtype) ) \
2859 if ( g.isMultipart() )
2861 return g.asMultiPoint().at( 0 ).x();
2865 return g.asPoint().x();
2873 if ( g.isMultipart() )
2875 return g.asMultiPoint().at( 0 ).y();
2879 return g.asPoint().y();
2893 if ( g.isEmpty() || !abGeom->
is3D() )
2898 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2904 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2906 if ( collection->numGeometries() > 0 )
2908 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2919 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2925 return QVariant( isValid );
2930 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2934 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
2935#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
2940 if ( methodString.compare( QLatin1String(
"linework" ), Qt::CaseInsensitive ) == 0 )
2942 else if ( methodString.compare( QLatin1String(
"structure" ), Qt::CaseInsensitive ) == 0 )
2945 const bool keepCollapsed = values.value( 2 ).toBool();
2950 valid = geom.
makeValid( method, keepCollapsed );
2954 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
2958 return QVariant::fromValue( valid );
2963 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2969 for (
int i = 0; i < multiGeom.size(); ++i )
2971 array += QVariant::fromValue( multiGeom.at( i ) );
2979 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2991 QVariant result(
centroid.asPoint().
x() );
2997 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3009 QVariant result(
centroid.asPoint().
y() );
3015 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3025 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3033 if ( collection->numGeometries() == 1 )
3035 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3046 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3056 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3064 if ( collection->numGeometries() == 1 )
3066 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3077 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3082 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3109 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3126 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3143 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3148 bool ignoreClosing =
false;
3149 if ( values.length() > 1 )
3151 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3161 bool skipLast =
false;
3162 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3167 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3179 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3190 for (
int i = 0; i < line->numPoints() - 1; ++i )
3194 << line->pointN( i )
3195 << line->pointN( i + 1 ) );
3206 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3216 if ( collection->numGeometries() == 1 )
3218 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
3223 if ( !curvePolygon )
3227 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3233 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3239 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3249 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3255 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3261 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3270 return QVariant::fromValue(
QgsGeometry( boundary ) );
3275 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3284 return QVariant::fromValue( merged );
3289 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3293 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3298 if ( sharedPaths.
isNull() )
3301 return QVariant::fromValue( sharedPaths );
3307 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3312 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3315 if ( simplified.
isNull() )
3323 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3328 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3333 if ( simplified.
isNull() )
3341 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3346 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3347 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3348 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3349 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3351 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3360 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3365 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3366 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3367 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3378 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3383 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3384 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3385 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3386 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3387 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3390 minAmplitude, maxAmplitude, seed );
3399 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3404 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3405 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3406 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3417 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3422 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3423 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3424 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3425 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3426 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3429 minAmplitude, maxAmplitude, seed );
3438 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3443 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3444 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3445 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3456 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3461 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3462 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3463 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3464 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3465 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3468 minAmplitude, maxAmplitude, seed );
3477 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3482 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3483 QVector< double > dashPattern;
3484 dashPattern.reserve( pattern.size() );
3485 for (
const QVariant &value : std::as_const( pattern ) )
3488 double v = value.toDouble( &ok );
3495 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3500 if ( dashPattern.size() % 2 != 0 )
3502 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3506 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3508 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3510 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3512 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3514 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3516 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3520 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3524 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3526 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3528 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3530 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3532 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3534 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3538 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3542 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3544 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3546 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3548 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3552 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3556 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3567 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3572 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3574 if ( densified.
isNull() )
3582 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3587 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3589 if ( densified.
isNull() )
3598 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3600 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3607 QVector< QgsGeometry > parts;
3608 parts.reserve( list.size() );
3609 for (
const QVariant &value : std::as_const( list ) )
3611 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3627 if ( values.count() < 2 || values.count() > 4 )
3629 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3633 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3634 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3635 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3636 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3637 switch ( values.count() )
3651 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3652 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3653 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3659 if ( values.empty() )
3664 QVector<QgsPoint> points;
3665 points.reserve( values.count() );
3667 auto addPoint = [&points](
const QgsGeometry & geom )
3675 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3682 for (
const QVariant &value : values )
3684 if ( value.type() == QVariant::List )
3686 const QVariantList list = value.toList();
3687 for (
const QVariant &v : list )
3689 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3694 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3698 if ( points.count() < 2 )
3706 if ( values.count() < 1 )
3708 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3712 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3720 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3722 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3729 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3734 if ( !exteriorRing )
3737 polygon->setExteriorRing( exteriorRing->
segmentize() );
3740 for (
int i = 1; i < values.count(); ++i )
3742 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3749 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3756 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3764 polygon->addInteriorRing( ring->
segmentize() );
3767 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3772 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3773 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3774 lineString->clear();
3776 for (
const QVariant &value : values )
3778 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3785 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3792 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3800 lineString->addVertex( *point );
3803 tr->setExteriorRing( lineString.release() );
3805 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3810 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3817 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3818 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3825 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3832 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3840 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3845 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3852 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3853 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3854 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3855 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3861 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3868 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3875 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3876 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3882 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3889 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3896 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3899 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3906 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3910 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3917 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3924 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3931 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3946 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3952 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3958 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3959 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3967 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3973 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3979 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3988 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3991 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3992 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3993 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
4012 return QVariant::fromValue( geom.
vertexAt( idx ) );
4020 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4022 const QVariant v = pointAt( geom, idx, parent );
4025 return QVariant( v.value<
QgsPoint>().
x() );
4031 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4033 return fcnOldXat( values, f, parent, node );
4035 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4037 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4040 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4046 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4048 const QVariant v = pointAt( geom, vertexNumber, parent );
4050 return QVariant( v.value<
QgsPoint>().
x() );
4060 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4062 const QVariant v = pointAt( geom, idx, parent );
4065 return QVariant( v.value<
QgsPoint>().
y() );
4071 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4073 return fcnOldYat( values, f, parent, node );
4075 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4077 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4080 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4086 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4088 const QVariant v = pointAt( geom, vertexNumber, parent );
4090 return QVariant( v.value<
QgsPoint>().
y() );
4097 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4103 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4105 const QVariant v = pointAt( geom, vertexNumber, parent );
4107 return QVariant( v.value<
QgsPoint>().
z() );
4114 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4120 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4122 const QVariant v = pointAt( geom, vertexNumber, parent );
4124 return QVariant( v.value<
QgsPoint>().
m() );
4143 return QVariant::fromValue( geom );
4151 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4153 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4159 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4165 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4170 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4177 ogcContext.
layer = mapLayerPtr.data();
4178 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
4182 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4195 return QVariant( area );
4205 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4210 return QVariant( geom.
area() );
4222 return QVariant( len );
4239 return QVariant( len );
4243 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4249 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4255 return QVariant( geom.
length() );
4260 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4266 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4275 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4284 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4299 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
4300 if ( !curvePolygon )
4312 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4319 return QVariant( curvePolygon->
ringCount() );
4321 bool foundPoly =
false;
4329 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
4330 if ( !curvePolygon )
4341 return QVariant( ringCount );
4346 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4348 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4354 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4360 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4366 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4375 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4381 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4387 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4393 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4399 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4407 double max = std::numeric_limits< double >::lowest();
4411 double z = ( *it ).z();
4417 if ( max == std::numeric_limits< double >::lowest() )
4418 return QVariant( QVariant::Double );
4420 return QVariant( max );
4425 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4433 double min = std::numeric_limits< double >::max();
4437 double z = ( *it ).z();
4443 if ( min == std::numeric_limits< double >::max() )
4444 return QVariant( QVariant::Double );
4446 return QVariant( min );
4451 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4459 double min = std::numeric_limits< double >::max();
4463 double m = ( *it ).m();
4469 if ( min == std::numeric_limits< double >::max() )
4470 return QVariant( QVariant::Double );
4472 return QVariant( min );
4477 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4485 double max = std::numeric_limits< double >::lowest();
4489 double m = ( *it ).m();
4495 if ( max == std::numeric_limits< double >::lowest() )
4496 return QVariant( QVariant::Double );
4498 return QVariant( max );
4503 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4504 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
4507 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
4516 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4520 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4529 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4534 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4545 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4549 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4551 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4556 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4560 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4567 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4575 return QVariant::fromValue( curve->
isClosed() );
4580 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4593 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4594 closedLine->close();
4596 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4606 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4608 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4609 closedLine->close();
4611 closed->addGeometry( closedLine.release() );
4614 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4622 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4626 return QVariant::fromValue( fGeom.
isEmpty() );
4632 return QVariant::fromValue(
true );
4634 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4635 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4640 if ( values.length() < 2 || values.length() > 3 )
4643 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4644 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4651 if ( values.length() == 2 )
4654 QString result = engine->relate( sGeom.
constGet() );
4655 return QVariant::fromValue( result );
4660 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4661 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4662 return QVariant::fromValue( result );
4668 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4669 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4674 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4675 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4676 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4680 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4681 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4682 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4686 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4687 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4688 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4692 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4693 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4694 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4698 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4699 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4700 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4704 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4705 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4706 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4710 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4711 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4712 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4717 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4718 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4719 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4720 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4721 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4722 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4725 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4726 capStyle = Qgis::EndCapStyle::Flat;
4727 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4728 capStyle = Qgis::EndCapStyle::Square;
4731 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4732 joinStyle = Qgis::JoinStyle::Miter;
4733 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4734 joinStyle = Qgis::JoinStyle::Bevel;
4737 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4743 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4745 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4750 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4752 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4757 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4759 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4764 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4765 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4772 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4779 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4783 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4784 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4785 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4786 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4789 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4795 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4798 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4802 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4803 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4804 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4807 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4813 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4816 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4820 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4823 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4829 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4830 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4831 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4832 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4833 if ( joinInt < 1 || joinInt > 3 )
4837 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4840 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4846 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4847 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4848 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4850 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4851 if ( joinInt < 1 || joinInt > 3 )
4855 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4858 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4864 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4865 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4866 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4869 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4875 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4876 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4877 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4879 return QVariant::fromValue( fGeom );
4884 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4885 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4886 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4888 const bool perPart = values.value( 3 ).toBool();
4895 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4898 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4899 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4900 t.rotate( -rotation );
4901 t.translate( -partCenter.
x(), -partCenter.
y() );
4902 ( *it )->transform( t );
4904 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4916 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4924 fGeom.
rotate( rotation, pt );
4925 return QVariant::fromValue( fGeom );
4931 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4932 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4933 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4934 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
4945 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
4953 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
4954 t.scale( xScale, yScale );
4955 t.translate( -pt.
x(), -pt.
y() );
4957 return QVariant::fromValue( fGeom );
4962 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4968 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4969 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4971 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4973 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4974 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4976 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
4977 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
4978 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
4979 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
4990 QTransform transform;
4991 transform.translate( deltaX, deltaY );
4992 transform.rotate( rotationZ );
4993 transform.scale( scaleX, scaleY );
4994 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
4996 return QVariant::fromValue( fGeom );
5002 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5004 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5009 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5011 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5017 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5018 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5020 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5026 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5028 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5032#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5037 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5038 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5039 const bool allowHoles = values.value( 2 ).toBool();
5041 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5054 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5056 if ( values.length() == 2 )
5057 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5065 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5071 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5073 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5079 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5085 double area,
angle, width, height;
5098 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5099 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5101 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5107 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5114 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
5119 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5127 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
5129 reversed->addGeometry( curve->
reversed() );
5136 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5143 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5154 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
5163 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5169 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5170 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5171 return QVariant( fGeom.
distance( sGeom ) );
5176 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5177 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5180 if ( values.length() == 3 && values.at( 2 ).isValid() )
5182 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5183 densify = std::clamp( densify, 0.0, 1.0 );
5191 return res > -1 ? QVariant( res ) : QVariant();
5196 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5197 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5199 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5204 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5205 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5207 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5212 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5213 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5215 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5221 if ( values.length() < 1 || values.length() > 2 )
5224 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5226 if ( values.length() == 2 )
5227 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5228 QString wkt = fGeom.
asWkt( prec );
5229 return QVariant( wkt );
5234 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5235 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5240 if ( values.length() != 2 )
5242 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5246 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5247 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5249 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5256 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5261 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5268 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5275 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5282 if ( pt1->
y() < pt2->
y() )
5284 else if ( pt1->
y() > pt2->
y() )
5292 if ( pt1->
x() < pt2->
x() )
5294 else if ( pt1->
x() > pt2->
x() )
5295 return M_PI + ( M_PI_2 );
5300 if ( pt1->
x() < pt2->
x() )
5302 if ( pt1->
y() < pt2->
y() )
5304 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
5308 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5315 if ( pt1->
y() > pt2->
y() )
5317 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5322 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5323 + ( M_PI + ( M_PI_2 ) );
5330 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5334 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
5338 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5339 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5340 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5343 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
5350 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5351 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5353 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5360 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5364 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5371 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5379 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
5389 if ( values.length() != 3 )
5392 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5393 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5394 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5398 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
5404 if ( values.length() < 2 )
5407 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5410 return values.at( 0 );
5412 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5413 QVariant cachedExpression;
5418 if ( cachedExpression.isValid() )
5425 bool asc = values.value( 2 ).toBool();
5443 Q_ASSERT( collection );
5447 QgsExpressionSorter sorter( orderBy );
5449 QList<QgsFeature> partFeatures;
5450 partFeatures.reserve( collection->
partCount() );
5451 for (
int i = 0; i < collection->
partCount(); ++i )
5457 sorter.sortFeatures( partFeatures, unconstedContext );
5461 Q_ASSERT( orderedGeom );
5466 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
5471 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
5474 delete unconstedContext;
5481 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5482 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5486 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5492 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5493 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5497 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5503 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5504 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5508 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5514 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5517 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
5523 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
5530 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
5537 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5538 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5540 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
5542 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
5547 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5548 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5555 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5556 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5561 vertex = count + vertex;
5569 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5570 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5575 vertex = count + vertex;