68#include <QMimeDatabase>
69#include <QProcessEnvironment>
70#include <QCryptographicHash>
71#include <QRegularExpression>
94 QVariantList argValues;
98 const QList< QgsExpressionNode * > argList = args->
list();
105 v = QVariant::fromValue( n );
109 v = n->eval( parent, context );
111 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
112 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
115 argValues.append( v );
120 return func( argValues, context, parent, node );
131 return QStringList();
158 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
163 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
175 const QString &group,
176 const QString &helpText,
180 const QStringList &aliases,
184 , mAliases( aliases )
185 , mUsesGeometry( false )
186 , mUsesGeometryFunc( usesGeometry )
187 , mReferencedColumnsFunc( referencedColumns )
199 if ( mUsesGeometryFunc )
200 return mUsesGeometryFunc( node );
202 return mUsesGeometry;
212 if ( mReferencedColumnsFunc )
213 return mReferencedColumnsFunc( node );
215 return mReferencedColumns;
221 return mIsStaticFunc( node, parent, context );
229 return mPrepareFunc( node, parent, context );
241 mIsStaticFunc =
nullptr;
247 mPrepareFunc = prepareFunc;
252 if ( node && node->
args() )
254 const QList< QgsExpressionNode * > argList = node->
args()->
list();
257 if ( !argNode->isStatic( parent, context ) )
267 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
268 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
269 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
271 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
278 double current = start + step;
279 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
294 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
296 if ( name == QLatin1String(
"feature" ) )
298 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
300 else if ( name == QLatin1String(
"id" ) )
302 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
304 else if ( name == QLatin1String(
"geometry" ) )
320 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
329 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
331 return expression.evaluate( context );
336 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
337 return QVariant( std::sqrt( x ) );
342 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::fabs( val ) );
348 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return ( deg * M_PI ) / 180;
353 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
354 return ( 180 * rad ) / M_PI;
358 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
359 return QVariant( std::sin( x ) );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
364 return QVariant( std::cos( x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::tan( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
374 return QVariant( std::asin( x ) );
378 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
379 return QVariant( std::acos( x ) );
383 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
384 return QVariant( std::atan( x ) );
388 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
389 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
390 return QVariant( std::atan2( y, x ) );
394 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
395 return QVariant( std::exp( x ) );
399 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::log( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
409 return QVariant( log10( x ) );
413 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
414 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
415 if ( x <= 0 || b <= 0 )
417 return QVariant( std::log( x ) / std::log( b ) );
421 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
422 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
426 std::random_device rd;
427 std::mt19937_64 generator( rd() );
429 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
432 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
435 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
440 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
441 std::hash<std::string> hasher;
442 seed = hasher( seedStr.toStdString() );
444 generator.seed( seed );
448 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
449 return QVariant( min + f * ( max - min ) );
453 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
454 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
458 std::random_device rd;
459 std::mt19937_64 generator( rd() );
461 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
464 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
467 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
472 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
473 std::hash<std::string> hasher;
474 seed = hasher( seedStr.toStdString() );
476 generator.seed( seed );
479 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
480 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
481 return QVariant( randomInteger );
484 return QVariant(
int( randomInteger ) );
489 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
490 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
491 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
492 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
493 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
495 if ( domainMin >= domainMax )
497 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
502 if ( val >= domainMax )
506 else if ( val <= domainMin )
512 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
513 double c = rangeMin - ( domainMin * m );
516 return QVariant( m * val +
c );
521 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
522 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
523 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
524 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
525 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
526 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
528 if ( domainMin >= domainMax )
530 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
540 if ( val >= domainMax )
544 else if ( val <= domainMin )
550 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
555 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
556 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
557 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
558 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
559 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
560 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
562 if ( domainMin >= domainMax )
564 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
574 if ( val >= domainMax )
578 else if ( val <= domainMin )
584 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
585 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
590 QVariant result( QVariant::Double );
591 double maxVal = std::numeric_limits<double>::quiet_NaN();
592 for (
const QVariant &val : values )
595 if ( std::isnan( maxVal ) )
599 else if ( !std::isnan( testVal ) )
601 maxVal = std::max( maxVal, testVal );
605 if ( !std::isnan( maxVal ) )
607 result = QVariant( maxVal );
614 QVariant result( QVariant::Double );
615 double minVal = std::numeric_limits<double>::quiet_NaN();
616 for (
const QVariant &val : values )
619 if ( std::isnan( minVal ) )
623 else if ( !std::isnan( testVal ) )
625 minVal = std::min( minVal, testVal );
629 if ( !std::isnan( minVal ) )
631 result = QVariant( minVal );
643 QVariant value = node->
eval( parent, context );
648 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
652 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
657 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
659 value = node->
eval( parent, context );
665 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
670 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
672 QString subExpression = node->
dump();
676 if ( values.count() > 3 )
678 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
681 if ( !nl || nl->value().isValid() )
686 if ( values.count() > 4 )
688 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
690 value = node->
eval( parent, context );
697 if ( values.count() > 5 )
699 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
702 if ( !nl || nl->value().isValid() )
704 orderBy = node->
dump();
709 QString aggregateError;
717 bool isStatic =
true;
718 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
719 || filterExp.referencedVariables().contains( QString() )
720 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
721 || subExp.referencedVariables().contains( QString() ) )
727 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
728 for (
const QString &varName : refVars )
731 if ( scope && !scope->
isStatic( varName ) )
741 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
742 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
746 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
757 subContext.appendScope( subScope );
758 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
770 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
774 if ( !aggregateError.isEmpty() )
775 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
777 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
788 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
796 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
800 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
809 QVariant value = node->
eval( parent, context );
811 QString relationId = value.toString();
818 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
820 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
825 relation = relations.at( 0 );
832 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
834 value = node->
eval( parent, context );
840 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
845 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
847 QString subExpression = node->
dump();
851 if ( values.count() > 3 )
853 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
855 value = node->
eval( parent, context );
862 if ( values.count() > 4 )
864 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
867 if ( !nl || nl->value().isValid() )
869 orderBy = node->
dump();
880 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->id(),
881 QString::number(
static_cast< int >( aggregate ) ),
894 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
898 if ( !error.isEmpty() )
899 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
901 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
915 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
923 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
927 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
936 QString subExpression = node->
dump();
940 if ( values.count() > 1 )
942 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
945 if ( !nl || nl->value().isValid() )
946 groupBy = node->
dump();
950 if ( values.count() > 2 )
952 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
955 if ( !nl || nl->value().isValid() )
961 if ( orderByPos >= 0 && values.count() > orderByPos )
963 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
966 if ( !nl || nl->value().isValid() )
968 orderBy = node->
dump();
976 if ( !groupBy.isEmpty() )
979 QVariant groupByValue = groupByExp.evaluate( context );
980 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
983 if ( !parameters.
filter.isEmpty() )
984 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
986 parameters.
filter = groupByClause;
992 bool isStatic =
true;
993 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
994 for (
const QString &varName : refVars )
997 if ( scope && !scope->
isStatic( varName ) )
1007 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
1008 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
1012 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
1024 subContext.appendScope( subScope );
1026 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1030 if ( !error.isEmpty() )
1031 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1033 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1138 if ( values.count() > 3 )
1140 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1142 QVariant value = node->
eval( parent, context );
1144 parameters.
delimiter = value.toString();
1155 if ( values.count() > 3 )
1157 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1159 QVariant value = node->
eval( parent, context );
1161 parameters.
delimiter = value.toString();
1177 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1182 const double v = scale.toDouble( &ok );
1190 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1191 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1192 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1195 if ( testValue <= minValue )
1197 return QVariant( minValue );
1199 else if ( testValue >= maxValue )
1201 return QVariant( maxValue );
1205 return QVariant( testValue );
1211 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1212 return QVariant( std::floor( x ) );
1217 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1218 return QVariant( std::ceil( x ) );
1223 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1227 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1231 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1236 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1237 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1238 if ( format.isEmpty() && !language.isEmpty() )
1240 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1241 return QVariant( QDateTime() );
1244 if ( format.isEmpty() && language.isEmpty() )
1245 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1247 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1248 QLocale locale = QLocale();
1249 if ( !language.isEmpty() )
1251 locale = QLocale( language );
1254 QDateTime datetime = locale.toDateTime( datetimestring, format );
1255 if ( !datetime.isValid() )
1257 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1258 datetime = QDateTime();
1260 return QVariant( datetime );
1265 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1266 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1267 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1269 const QDate date( year, month, day );
1270 if ( !date.isValid() )
1272 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1275 return QVariant( date );
1280 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1281 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1282 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1284 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1285 if ( !time.isValid() )
1287 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1290 return QVariant( time );
1295 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1296 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1297 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1298 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1299 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1300 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1302 const QDate date( year, month, day );
1303 if ( !date.isValid() )
1305 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1308 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1309 if ( !time.isValid() )
1311 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1314 return QVariant( QDateTime( date, time ) );
1319 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1320 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1321 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1322 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1323 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1324 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1325 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1327 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1332 for (
const QVariant &value : values )
1343 const QVariant val1 = values.at( 0 );
1344 const QVariant val2 = values.at( 1 );
1354 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1355 return QVariant(
str.toLower() );
1359 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1360 return QVariant(
str.toUpper() );
1364 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1365 QStringList elems =
str.split(
' ' );
1366 for (
int i = 0; i < elems.size(); i++ )
1368 if ( elems[i].size() > 1 )
1369 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1371 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1376 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1377 return QVariant(
str.trimmed() );
1382 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1384 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1386 const QRegularExpression re( QStringLiteral(
"^([%1]*)" ).arg( QRegularExpression::escape( characters ) ) );
1387 str.replace( re, QString() );
1388 return QVariant(
str );
1393 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1395 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1397 const QRegularExpression re( QStringLiteral(
"([%1]*)$" ).arg( QRegularExpression::escape( characters ) ) );
1398 str.replace( re, QString() );
1399 return QVariant(
str );
1404 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1405 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1411 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1412 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1418 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1419 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1421 return ( dist < 0 ? QVariant() : QVariant(
QgsStringUtils::hammingDistance( string1, string2, true ) ) );
1426 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1432 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1433 return QVariant( QString( character ) );
1438 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1440 if ( value.isEmpty() )
1445 int res = value.at( 0 ).unicode();
1446 return QVariant( res );
1451 if ( values.length() == 2 || values.length() == 3 )
1453 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1454 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1456 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1467 if ( values.at( 0 ).userType() == QMetaType::type(
"QgsGeometry" ) )
1470 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1474 return QVariant( geom.
length() );
1478 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1479 return QVariant(
str.length() );
1484 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1489 double totalLength = 0;
1492 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1494 totalLength += line->length3D();
1498 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1499 totalLength += segmentized->length3D();
1508 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1510 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1511 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1512 QVector< QPair< QString, QString > > mapItems;
1514 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1516 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1520 std::sort( mapItems.begin(),
1522 [](
const QPair< QString, QString > &pair1,
1523 const QPair< QString, QString > &pair2 )
1525 return ( pair1.first.length() > pair2.first.length() );
1528 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1530 str =
str.replace( it->first, it->second );
1533 return QVariant(
str );
1535 else if ( values.count() == 3 )
1537 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1538 QVariantList before;
1540 bool isSingleReplacement =
false;
1542 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
1544 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1548 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1551 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1553 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1554 isSingleReplacement =
true;
1558 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1561 if ( !isSingleReplacement && before.length() != after.length() )
1563 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1567 for (
int i = 0; i < before.length(); i++ )
1569 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1572 return QVariant(
str );
1576 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1583 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1584 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1585 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1587 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1588 if ( !re.isValid() )
1590 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1593 return QVariant(
str.replace( re, after ) );
1598 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1599 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1601 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1602 if ( !re.isValid() )
1604 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1607 return QVariant( (
str.indexOf( re ) + 1 ) );
1612 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1613 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1614 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1616 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1617 if ( !re.isValid() )
1619 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1623 QRegularExpressionMatch matches = re.match(
str );
1624 if ( matches.hasMatch() )
1627 QStringList list = matches.capturedTexts();
1630 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1632 array += ( !( *it ).isEmpty() ) ? *it : empty;
1635 return QVariant( array );
1645 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1646 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1648 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1649 if ( !re.isValid() )
1651 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1656 QRegularExpressionMatch match = re.match(
str );
1657 if ( match.hasMatch() )
1660 if ( match.lastCapturedIndex() > 0 )
1663 return QVariant( match.captured( 1 ) );
1668 return QVariant( match.captured( 0 ) );
1673 return QVariant(
"" );
1679 QString uuid = QUuid::createUuid().toString();
1680 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1681 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1682 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1683 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1689 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1692 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1693 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1696 if ( values.at( 2 ).isValid() )
1697 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1703 from =
str.size() + from;
1709 else if ( from > 0 )
1717 len =
str.size() + len - from;
1724 return QVariant(
str.mid( from, len ) );
1730 return QVariant(
static_cast< int >( f.
id() ) );
1735 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1736 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1737 bool foundLayer =
false;
1738 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1740 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1741 if ( !layer || !layer->dataProvider() )
1743 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1747 if ( bandNb < 1 || bandNb > layer->bandCount() )
1749 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1755 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1763 if ( multiPoint.count() == 1 )
1765 point = multiPoint[0];
1774 double value = layer->dataProvider()->sample( point, bandNb );
1775 return std::isnan( value ) ? QVariant() : value;
1781 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1792 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1793 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1795 bool foundLayer =
false;
1796 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1798 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1799 if ( !layer || !layer->dataProvider() )
1801 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1805 if ( bandNb < 1 || bandNb > layer->bandCount() )
1807 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1811 if ( std::isnan( value ) )
1813 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1817 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1822 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1823 if ( data.isEmpty() )
1829 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1830 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1833 if ( field.isColor() || field.isRamp() )
1837 result.insert( fields.at( idx ).name, data.at( idx ) );
1845 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1866 if ( values.size() == 1 )
1868 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1871 else if ( values.size() == 2 )
1873 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1874 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1878 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1887 QString table { R
"html(
1893 <tr><td>%2</td></tr>
1897 if ( values.size() == 1 )
1899 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1903 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
1907 if ( dict.isEmpty() )
1912 QStringList headers;
1915 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1917 headers.push_back( it.key().toHtmlEscaped() );
1918 cells.push_back( it.value().toString( ).toHtmlEscaped() );
1921 return table.arg( headers.join( QLatin1String(
"</th><th>" ) ), cells.join( QLatin1String(
"</td><td>" ) ) );
1926 QString table { R
"html(
1931 if ( values.size() == 1 )
1933 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1937 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
1941 if ( dict.isEmpty() )
1948 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1950 rows.append( QStringLiteral(
"<dt>%1</dt><dd>%2</dd>" ).arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
1953 return table.arg( rows );
1961 layer = context->
variable( QStringLiteral(
"layer" ) );
1966 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1968 layer = node->
eval( parent, context );
1979 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1983 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
1984 if ( strength == QLatin1String(
"hard" ) )
1988 else if ( strength == QLatin1String(
"soft" ) )
1993 bool foundLayer =
false;
1994 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
1996 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
1999 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2005 for (
int i = 0; i < fields.
size(); i++ )
2020 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2032 layer = context->
variable( QStringLiteral(
"layer" ) );
2037 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2039 layer = node->
eval( parent, context );
2050 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2054 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2055 if ( strength == QLatin1String(
"hard" ) )
2059 else if ( strength == QLatin1String(
"soft" ) )
2064 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2066 bool foundLayer =
false;
2067 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2069 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2076 if ( fieldIndex == -1 )
2078 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2089 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2105 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2110 for (
int i = 0; i < fields.
count(); ++i )
2124 if ( values.isEmpty() )
2127 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2129 else if ( values.size() == 1 )
2131 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2132 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2134 else if ( values.size() == 2 )
2136 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2137 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2141 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2148 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2154 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2160 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2162 const QString fieldName { fields.
at( fieldIndex ).
name() };
2163 const QVariant attributeVal = feature.
attribute( fieldIndex );
2164 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
2167 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2176 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
2188 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2190 result.insert( fields.
at( fieldIndex ).
name(), value );
2206 bool evaluate =
true;
2210 if ( values.isEmpty() )
2213 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2215 else if ( values.size() == 1 )
2217 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2218 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2220 else if ( values.size() == 2 )
2222 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2223 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2225 else if ( values.size() == 3 )
2227 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2228 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2229 evaluate = values.value( 2 ).toBool();
2235 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2239 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2271 subContext.setFeature( feature );
2280 exp.prepare( &subContext );
2281 return exp.evaluate( &subContext ).toString();
2287 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2292 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2299 if ( values.isEmpty() )
2302 layer = context->
variable( QStringLiteral(
"layer" ) );
2304 else if ( values.size() == 1 )
2306 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2307 layer = context->
variable( QStringLiteral(
"layer" ) );
2309 else if ( values.size() == 2 )
2311 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2312 layer = values.at( 0 );
2316 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2320 bool foundLayer =
false;
2321 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2323 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2324 if ( !layer || !feature.
isValid() )
2326 return QVariant( QVariant::Bool );
2332 return QVariant( QVariant::Bool );
2341 if ( values.isEmpty() )
2342 layer = context->
variable( QStringLiteral(
"layer" ) );
2343 else if ( values.count() == 1 )
2344 layer = values.at( 0 );
2347 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2351 bool foundLayer =
false;
2352 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2354 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2357 return QVariant( QVariant::LongLong );
2363 return QVariant( QVariant::LongLong );
2370 static QMap<QString, qlonglong> counterCache;
2371 QVariant functionResult;
2373 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2377 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2382 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
2383 if ( database.isEmpty() )
2385 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2390 database = databaseArgument;
2393 const QString table = values.at( 1 ).toString();
2394 const QString idColumn = values.at( 2 ).toString();
2395 const QString filterAttribute = values.at( 3 ).toString();
2396 const QVariant filterValue = values.at( 4 ).toString();
2397 const QVariantMap defaultValues = values.at( 5 ).toMap();
2403 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2406 functionResult = QVariant();
2410 QString errorMessage;
2411 QString currentValSql;
2413 qlonglong nextId = 0;
2414 bool cachedMode =
false;
2415 bool valueRetrieved =
false;
2417 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2424 auto cachedCounter = counterCache.find( cacheString );
2426 if ( cachedCounter != counterCache.end() )
2428 qlonglong &cachedValue = cachedCounter.value();
2429 nextId = cachedValue;
2431 cachedValue = nextId;
2432 valueRetrieved =
true;
2437 if ( !cachedMode || !valueRetrieved )
2439 int result = SQLITE_ERROR;
2442 if ( !filterAttribute.isNull() )
2447 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2449 if ( result == SQLITE_OK )
2452 if ( sqliteStatement.
step() == SQLITE_ROW )
2458 if ( cachedMode && result == SQLITE_OK )
2460 counterCache.insert( cacheString, nextId );
2464 counterCache.remove( cacheString );
2467 valueRetrieved =
true;
2471 if ( valueRetrieved )
2480 if ( !filterAttribute.isNull() )
2486 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2489 vals << iter.value().toString();
2492 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2493 upsertSql += QLatin1String(
" VALUES " );
2494 upsertSql +=
'(' + vals.join(
',' ) +
')';
2496 int result = SQLITE_ERROR;
2500 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2507 result = sqliteDb.
exec( upsertSql, errorMessage );
2509 if ( result == SQLITE_OK )
2511 functionResult = QVariant( nextId );
2516 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2517 functionResult = QVariant();
2522 functionResult = QVariant();
2525 bool foundLayer =
false;
2526 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2528 fetchAndIncrementFunc( layer, QString() );
2532 const QString databasePath = values.at( 0 ).toString();
2535 fetchAndIncrementFunc(
nullptr, databasePath );
2539 return functionResult;
2545 for (
const QVariant &value : values )
2548 concat += QgsExpressionUtils::getStringValue( value, parent );
2555 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2556 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2561 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2562 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2563 return string.right( pos );
2568 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2569 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2570 return string.left( pos );
2575 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2576 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2577 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2578 return string.leftJustified( length, fill.at( 0 ),
true );
2583 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2584 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2585 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2586 return string.rightJustified( length, fill.at( 0 ),
true );
2591 if ( values.size() < 1 )
2593 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2597 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2598 for (
int n = 1; n < values.length(); n++ )
2600 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2608 return QVariant( QDateTime::currentDateTime() );
2613 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2614 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2615 if ( format.isEmpty() && !language.isEmpty() )
2617 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2618 return QVariant( QDate() );
2621 if ( format.isEmpty() && language.isEmpty() )
2622 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2624 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2625 QLocale locale = QLocale();
2626 if ( !language.isEmpty() )
2628 locale = QLocale( language );
2631 QDate date = locale.toDate( datestring, format );
2632 if ( !date.isValid() )
2634 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2637 return QVariant( date );
2642 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2643 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2644 if ( format.isEmpty() && !language.isEmpty() )
2646 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2647 return QVariant( QTime() );
2650 if ( format.isEmpty() && language.isEmpty() )
2651 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2653 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2654 QLocale locale = QLocale();
2655 if ( !language.isEmpty() )
2657 locale = QLocale( language );
2660 QTime time = locale.toTime( timestring, format );
2661 if ( !time.isValid() )
2663 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2666 return QVariant( time );
2671 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2680 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2681 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2682 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2684 QString formatString;
2685 if ( values.count() > 3 )
2686 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2688 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2689 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2693 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2697 else if ( ! formatString.isEmpty() )
2699 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2703 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2707 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2713 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2721 return floatToDegreeFormat( format, values, context, parent, node );
2728 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2730 return ok ? QVariant( value ) : QVariant();
2736 return floatToDegreeFormat( format, values, context, parent, node );
2741 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2742 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2743 qint64 seconds = d2.secsTo( d1 );
2744 return QVariant::fromValue(
QgsInterval( seconds ) );
2749 if ( !values.at( 0 ).canConvert<QDate>() )
2752 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2753 if ( !date.isValid() )
2758 return date.dayOfWeek() % 7;
2763 QVariant value = values.at( 0 );
2764 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2767 return QVariant( inter.
days() );
2771 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2772 return QVariant( d1.date().day() );
2778 QVariant value = values.at( 0 );
2779 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2782 return QVariant( inter.
years() );
2786 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2787 return QVariant( d1.date().year() );
2793 QVariant value = values.at( 0 );
2794 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2797 return QVariant( inter.
months() );
2801 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2802 return QVariant( d1.date().month() );
2808 QVariant value = values.at( 0 );
2809 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2812 return QVariant( inter.
weeks() );
2816 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2817 return QVariant( d1.date().weekNumber() );
2823 QVariant value = values.at( 0 );
2824 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2827 return QVariant( inter.
hours() );
2831 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2832 return QVariant( t1.hour() );
2838 QVariant value = values.at( 0 );
2839 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2842 return QVariant( inter.
minutes() );
2846 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2847 return QVariant( t1.minute() );
2853 QVariant value = values.at( 0 );
2854 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2857 return QVariant( inter.
seconds() );
2861 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2862 return QVariant( t1.second() );
2868 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2871 return QVariant( dt.toMSecsSinceEpoch() );
2881 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2883 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2888 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2891 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2894 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2900 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2903 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2910#define ENSURE_GEOM_TYPE(f, g, geomtype) \
2911 if ( !(f).hasGeometry() ) \
2912 return QVariant(); \
2913 QgsGeometry g = (f).geometry(); \
2914 if ( (g).type() != (geomtype) ) \
2921 if ( g.isMultipart() )
2923 return g.asMultiPoint().at( 0 ).x();
2927 return g.asPoint().x();
2935 if ( g.isMultipart() )
2937 return g.asMultiPoint().at( 0 ).y();
2941 return g.asPoint().y();
2955 if ( g.isEmpty() || !abGeom->
is3D() )
2960 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2966 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2968 if ( collection->numGeometries() > 0 )
2970 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2981 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2987 return QVariant( isValid );
2992 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2996 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
2997#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
3002 if ( methodString.compare( QLatin1String(
"linework" ), Qt::CaseInsensitive ) == 0 )
3004 else if ( methodString.compare( QLatin1String(
"structure" ), Qt::CaseInsensitive ) == 0 )
3007 const bool keepCollapsed = values.value( 2 ).toBool();
3012 valid = geom.
makeValid( method, keepCollapsed );
3016 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3020 return QVariant::fromValue( valid );
3025 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3031 for (
int i = 0; i < multiGeom.size(); ++i )
3033 array += QVariant::fromValue( multiGeom.at( i ) );
3041 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3053 QVariant result( centroid.asPoint().
x() );
3059 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3071 QVariant result( centroid.asPoint().
y() );
3077 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3087 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3095 if ( collection->numGeometries() == 1 )
3097 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3108 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3118 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3126 if ( collection->numGeometries() == 1 )
3128 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3139 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3144 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3171 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3188 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3205 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3210 bool ignoreClosing =
false;
3211 if ( values.length() > 1 )
3213 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3223 bool skipLast =
false;
3224 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3229 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3241 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3252 for (
int i = 0; i < line->numPoints() - 1; ++i )
3256 << line->pointN( i )
3257 << line->pointN( i + 1 ) );
3268 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3278 if ( collection->numGeometries() == 1 )
3280 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
3285 if ( !curvePolygon )
3289 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3295 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3301 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3311 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3317 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3323 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3332 return QVariant::fromValue(
QgsGeometry( boundary ) );
3337 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3346 return QVariant::fromValue( merged );
3351 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3355 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3360 if ( sharedPaths.
isNull() )
3363 return QVariant::fromValue( sharedPaths );
3369 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3374 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3377 if ( simplified.
isNull() )
3385 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3390 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3395 if ( simplified.
isNull() )
3403 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3408 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3409 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3410 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3411 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3413 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3422 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3427 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3428 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3429 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3440 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3445 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3446 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3447 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3448 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3449 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3452 minAmplitude, maxAmplitude, seed );
3461 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3466 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3467 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3468 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3479 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3484 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3485 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3486 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3487 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3488 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3491 minAmplitude, maxAmplitude, seed );
3500 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3505 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3506 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3507 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3518 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3523 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3524 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3525 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3526 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3527 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3530 minAmplitude, maxAmplitude, seed );
3539 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3544 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3545 QVector< double > dashPattern;
3546 dashPattern.reserve( pattern.size() );
3547 for (
const QVariant &value : std::as_const( pattern ) )
3550 double v = value.toDouble( &ok );
3557 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3562 if ( dashPattern.size() % 2 != 0 )
3564 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3568 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3570 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3572 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3574 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3576 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3578 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3582 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3586 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3588 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3590 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3592 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3594 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3596 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3600 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3604 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3606 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3608 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3610 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3614 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3618 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3629 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3634 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3636 if ( densified.
isNull() )
3644 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3649 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3651 if ( densified.
isNull() )
3660 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3662 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3669 QVector< QgsGeometry > parts;
3670 parts.reserve( list.size() );
3671 for (
const QVariant &value : std::as_const( list ) )
3673 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3689 if ( values.count() < 2 || values.count() > 4 )
3691 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3695 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3696 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3697 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3698 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3699 switch ( values.count() )
3713 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3714 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3715 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3721 if ( values.empty() )
3726 QVector<QgsPoint> points;
3727 points.reserve( values.count() );
3729 auto addPoint = [&points](
const QgsGeometry & geom )
3737 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3744 for (
const QVariant &value : values )
3746 if ( value.type() == QVariant::List )
3748 const QVariantList list = value.toList();
3749 for (
const QVariant &v : list )
3751 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3756 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3760 if ( points.count() < 2 )
3768 if ( values.count() < 1 )
3770 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3774 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3782 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3784 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3791 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3796 if ( !exteriorRing )
3799 polygon->setExteriorRing( exteriorRing->
segmentize() );
3802 for (
int i = 1; i < values.count(); ++i )
3804 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3811 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3818 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3826 polygon->addInteriorRing( ring->
segmentize() );
3829 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3834 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3835 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3836 lineString->clear();
3838 for (
const QVariant &value : values )
3840 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3847 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3854 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3862 lineString->addVertex( *point );
3865 tr->setExteriorRing( lineString.release() );
3867 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3872 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3879 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3880 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3887 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3894 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3902 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3907 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3914 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3915 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3916 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3917 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3923 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3930 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3937 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3938 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3944 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3951 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3958 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3961 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3968 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3972 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3979 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3986 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3993 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4008 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4014 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4020 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4021 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4029 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4035 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4041 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4050 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4053 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4054 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4055 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
4074 return QVariant::fromValue( geom.
vertexAt( idx ) );
4082 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4084 const QVariant v = pointAt( geom, idx, parent );
4087 return QVariant( v.value<
QgsPoint>().
x() );
4093 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4095 return fcnOldXat( values, f, parent, node );
4097 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4099 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4102 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4108 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4110 const QVariant v = pointAt( geom, vertexNumber, parent );
4112 return QVariant( v.value<
QgsPoint>().
x() );
4122 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4124 const QVariant v = pointAt( geom, idx, parent );
4127 return QVariant( v.value<
QgsPoint>().
y() );
4133 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4135 return fcnOldYat( values, f, parent, node );
4137 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4139 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4142 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4148 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4150 const QVariant v = pointAt( geom, vertexNumber, parent );
4152 return QVariant( v.value<
QgsPoint>().
y() );
4159 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4165 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4167 const QVariant v = pointAt( geom, vertexNumber, parent );
4169 return QVariant( v.value<
QgsPoint>().
z() );
4176 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4182 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4184 const QVariant v = pointAt( geom, vertexNumber, parent );
4186 return QVariant( v.value<
QgsPoint>().
m() );
4205 return QVariant::fromValue( geom );
4213 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4215 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4221 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4227 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4232 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4239 ogcContext.
layer = mapLayerPtr.data();
4240 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
4244 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4257 return QVariant( area );
4267 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4272 return QVariant( geom.
area() );
4284 return QVariant( len );
4301 return QVariant( len );
4305 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4311 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4317 return QVariant( geom.
length() );
4322 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4323 return QVariant( geom.
isNull() ? 0 : geom.constGet()->nCoordinates() );
4328 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4337 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4346 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4361 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
4362 if ( !curvePolygon )
4365 return QVariant( curvePolygon->
isEmpty() ? 0 : curvePolygon->numInteriorRings() );
4374 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4381 return QVariant( curvePolygon->
ringCount() );
4383 bool foundPoly =
false;
4391 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
4392 if ( !curvePolygon )
4403 return QVariant( ringCount );
4408 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4410 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4416 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4422 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4428 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4437 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4443 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4449 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4455 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4461 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4469 double max = std::numeric_limits< double >::lowest();
4473 double z = ( *it ).z();
4479 if ( max == std::numeric_limits< double >::lowest() )
4480 return QVariant( QVariant::Double );
4482 return QVariant( max );
4487 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4495 double min = std::numeric_limits< double >::max();
4499 double z = ( *it ).z();
4505 if ( min == std::numeric_limits< double >::max() )
4506 return QVariant( QVariant::Double );
4508 return QVariant( min );
4513 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4521 double min = std::numeric_limits< double >::max();
4525 double m = ( *it ).m();
4531 if ( min == std::numeric_limits< double >::max() )
4532 return QVariant( QVariant::Double );
4534 return QVariant( min );
4539 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4547 double max = std::numeric_limits< double >::lowest();
4551 double m = ( *it ).m();
4557 if ( max == std::numeric_limits< double >::lowest() )
4558 return QVariant( QVariant::Double );
4560 return QVariant( max );
4565 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4566 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
4569 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
4578 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4582 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4591 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4596 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4607 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4611 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4613 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4618 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4622 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4629 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4637 return QVariant::fromValue( curve->
isClosed() );
4642 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4655 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4656 closedLine->close();
4658 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4668 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4670 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4671 closedLine->close();
4673 closed->addGeometry( closedLine.release() );
4676 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4684 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4688 return QVariant::fromValue( fGeom.
isEmpty() );
4694 return QVariant::fromValue(
true );
4696 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4697 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4702 if ( values.length() < 2 || values.length() > 3 )
4705 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4706 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4713 if ( values.length() == 2 )
4716 QString result = engine->relate( sGeom.
constGet() );
4717 return QVariant::fromValue( result );
4722 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4723 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4724 return QVariant::fromValue( result );
4730 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4731 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4736 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4737 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4738 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4742 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4743 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4744 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4748 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4749 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4750 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4754 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4755 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4756 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4760 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4761 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4762 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4766 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4767 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4768 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4772 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4773 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4774 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4779 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4780 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4781 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4782 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4783 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4784 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4787 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4789 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4793 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4795 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4799 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4805 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4807 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4812 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4814 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4819 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4821 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4826 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4827 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4834 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4841 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4845 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4846 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4847 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4848 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4851 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4857 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4860 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4864 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4865 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4866 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4869 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4875 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4878 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4882 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4885 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4891 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4892 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4893 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4894 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4895 if ( joinInt < 1 || joinInt > 3 )
4899 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4902 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4908 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4909 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4910 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4912 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4913 if ( joinInt < 1 || joinInt > 3 )
4917 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4920 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4926 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4927 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4928 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4931 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4937 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4938 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4939 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4941 return QVariant::fromValue( fGeom );
4946 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4947 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4948 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4950 const bool perPart = values.value( 3 ).toBool();
4957 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4960 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4961 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4962 t.rotate( -rotation );
4963 t.translate( -partCenter.
x(), -partCenter.
y() );
4964 ( *it )->transform( t );
4966 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4978 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4986 fGeom.
rotate( rotation, pt );
4987 return QVariant::fromValue( fGeom );
4993 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4994 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4995 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4996 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
5007 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5015 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5016 t.scale( xScale, yScale );
5017 t.translate( -pt.
x(), -pt.
y() );
5019 return QVariant::fromValue( fGeom );
5024 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5030 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5031 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5033 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5035 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5036 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5038 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5039 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5040 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5041 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5052 QTransform transform;
5053 transform.translate( deltaX, deltaY );
5054 transform.rotate( rotationZ );
5055 transform.scale( scaleX, scaleY );
5056 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5058 return QVariant::fromValue( fGeom );
5064 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5066 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 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5080 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5082 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5088 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5090 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5094#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5099 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5100 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5101 const bool allowHoles = values.value( 2 ).toBool();
5103 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5116 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5118 if ( values.length() == 2 )
5119 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5127 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5133 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5135 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5141 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5147 double area,
angle, width, height;
5160 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5161 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5163 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5169 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5176 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
5181 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5189 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
5191 reversed->addGeometry( curve->
reversed() );
5198 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5205 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5216 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
5225 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5231 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5232 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5233 return QVariant( fGeom.
distance( sGeom ) );
5238 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5239 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5242 if ( values.length() == 3 && values.at( 2 ).isValid() )
5244 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5245 densify = std::clamp( densify, 0.0, 1.0 );
5253 return res > -1 ? QVariant( res ) : QVariant();
5258 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5259 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5261 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5266 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5267 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5269 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5274 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5275 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5277 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5283 if ( values.length() < 1 || values.length() > 2 )
5286 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5288 if ( values.length() == 2 )
5289 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5290 QString wkt = fGeom.
asWkt( prec );
5291 return QVariant( wkt );
5296 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5297 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5302 if ( values.length() != 2 )
5304 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5308 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5309 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5311 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5318 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5323 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5330 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5337 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5344 if ( pt1->
y() < pt2->
y() )
5346 else if ( pt1->
y() > pt2->
y() )
5354 if ( pt1->
x() < pt2->
x() )
5356 else if ( pt1->
x() > pt2->
x() )
5357 return M_PI + ( M_PI_2 );
5362 if ( pt1->
x() < pt2->
x() )
5364 if ( pt1->
y() < pt2->
y() )
5366 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
5370 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5377 if ( pt1->
y() > pt2->
y() )
5379 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5384 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5385 + ( M_PI + ( M_PI_2 ) );
5392 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5393 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5394 QString sourceCrs = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5395 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
5399 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
5407 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
5416 if ( sourceCrs.isEmpty() )
5418 sourceCrs = context->
variable( QStringLiteral(
"layer_crs" ) ).toString();
5421 if ( ellipsoid.isEmpty() )
5423 ellipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
5430 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
5438 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
5444 const double bearing = da.
bearing( point1, point2 );
5445 if ( std::isfinite( bearing ) )
5447 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
5460 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5464 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
5468 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5469 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5470 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5473 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
5480 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5481 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5483 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5490 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5494 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5501 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5509 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
5519 if ( values.length() != 3 )
5522 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5523 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5524 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5528 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
5534 if ( values.length() < 2 )
5537 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5540 return values.at( 0 );
5542 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5543 QVariant cachedExpression;
5548 if ( cachedExpression.isValid() )
5555 bool asc = values.value( 2 ).toBool();
5573 Q_ASSERT( collection );