68#include <QMimeDatabase>
69#include <QProcessEnvironment>
70#include <QCryptographicHash>
71#include <QRegularExpression>
94 QVariantList argValues;
98 const QList< QgsExpressionNode * > argList = args->
list();
105 v = QVariant::fromValue( n );
109 v = n->eval( parent, context );
111 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
112 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
115 argValues.append( v );
120 return func( argValues, context, parent, node );
131 return QStringList();
158 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
163 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
175 const QString &group,
176 const QString &helpText,
180 const QStringList &aliases,
184 , mAliases( aliases )
185 , mUsesGeometry( false )
186 , mUsesGeometryFunc( usesGeometry )
187 , mReferencedColumnsFunc( referencedColumns )
199 if ( mUsesGeometryFunc )
200 return mUsesGeometryFunc( node );
202 return mUsesGeometry;
212 if ( mReferencedColumnsFunc )
213 return mReferencedColumnsFunc( node );
215 return mReferencedColumns;
221 return mIsStaticFunc( node, parent, context );
229 return mPrepareFunc( node, parent, context );
241 mIsStaticFunc =
nullptr;
247 mPrepareFunc = prepareFunc;
252 if ( node && node->
args() )
254 const QList< QgsExpressionNode * > argList = node->
args()->
list();
257 if ( !argNode->isStatic( parent, context ) )
267 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
268 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
269 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
271 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
278 double current = start + step;
279 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
294 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
296 if ( name == QLatin1String(
"feature" ) )
298 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
300 else if ( name == QLatin1String(
"id" ) )
302 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
304 else if ( name == QLatin1String(
"geometry" ) )
320 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
329 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
331 return expression.evaluate( context );
336 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
337 return QVariant( std::sqrt( x ) );
342 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::fabs( val ) );
348 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return ( deg * M_PI ) / 180;
353 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
354 return ( 180 * rad ) / M_PI;
358 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
359 return QVariant( std::sin( x ) );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
364 return QVariant( std::cos( x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::tan( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
374 return QVariant( std::asin( x ) );
378 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
379 return QVariant( std::acos( x ) );
383 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
384 return QVariant( std::atan( x ) );
388 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
389 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
390 return QVariant( std::atan2( y, x ) );
394 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
395 return QVariant( std::exp( x ) );
399 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
402 return QVariant( std::log( x ) );
406 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
409 return QVariant( log10( x ) );
413 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
414 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
415 if ( x <= 0 || b <= 0 )
417 return QVariant( std::log( x ) / std::log( b ) );
421 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
422 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
426 std::random_device rd;
427 std::mt19937_64 generator( rd() );
429 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
432 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
435 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
440 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
441 std::hash<std::string> hasher;
442 seed = hasher( seedStr.toStdString() );
444 generator.seed( seed );
448 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
449 return QVariant( min + f * ( max - min ) );
453 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
454 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
458 std::random_device rd;
459 std::mt19937_64 generator( rd() );
461 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
464 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
467 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
472 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
473 std::hash<std::string> hasher;
474 seed = hasher( seedStr.toStdString() );
476 generator.seed( seed );
479 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
480 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
481 return QVariant( randomInteger );
484 return QVariant(
int( randomInteger ) );
489 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
490 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
491 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
492 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
493 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
495 if ( domainMin >= domainMax )
497 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
502 if ( val >= domainMax )
506 else if ( val <= domainMin )
512 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
513 double c = rangeMin - ( domainMin * m );
516 return QVariant( m * val +
c );
521 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
522 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
523 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
524 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
525 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
526 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
528 if ( domainMin >= domainMax )
530 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
540 if ( val >= domainMax )
544 else if ( val <= domainMin )
550 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
555 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
556 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
557 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
558 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
559 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
560 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
562 if ( domainMin >= domainMax )
564 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
574 if ( val >= domainMax )
578 else if ( val <= domainMin )
584 double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
585 return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
591 double maxVal = std::numeric_limits<double>::quiet_NaN();
592 for (
const QVariant &val : values )
595 if ( std::isnan( maxVal ) )
599 else if ( !std::isnan( testVal ) )
601 maxVal = std::max( maxVal, testVal );
605 if ( !std::isnan( maxVal ) )
607 result = QVariant( maxVal );
615 double minVal = std::numeric_limits<double>::quiet_NaN();
616 for (
const QVariant &val : values )
619 if ( std::isnan( minVal ) )
623 else if ( !std::isnan( testVal ) )
625 minVal = std::min( minVal, testVal );
629 if ( !std::isnan( minVal ) )
631 result = QVariant( minVal );
643 QVariant value = node->
eval( parent, context );
648 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
652 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
657 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
659 value = node->
eval( parent, context );
665 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
670 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
672 QString subExpression = node->
dump();
676 if ( values.count() > 3 )
678 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
681 if ( !nl || nl->value().isValid() )
686 if ( values.count() > 4 )
688 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
690 value = node->
eval( parent, context );
697 if ( values.count() > 5 )
699 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
702 if ( !nl || nl->value().isValid() )
704 orderBy = node->
dump();
709 QString aggregateError;
717 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() ) )
728 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
729 for (
const QString &varName : refVars )
732 if ( scope && !scope->
isStatic( varName ) )
740 if ( isStatic && ! parameters.
orderBy.isEmpty() )
742 for (
const auto &orderByClause : std::as_const( parameters.orderBy ) )
745 if ( orderByExpression.referencedVariables().contains( QStringLiteral(
"parent" ) ) || orderByExpression.referencedVariables().contains( QString() ) )
755 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
756 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
760 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
771 subContext.appendScope( subScope );
772 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
784 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
788 if ( !aggregateError.isEmpty() )
789 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
791 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
802 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
810 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
814 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
823 QVariant value = node->
eval( parent, context );
825 QString relationId = value.toString();
832 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
834 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
839 relation = relations.at( 0 );
846 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
848 value = node->
eval( parent, context );
854 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
859 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
861 QString subExpression = node->
dump();
865 if ( values.count() > 3 )
867 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
869 value = node->
eval( parent, context );
876 if ( values.count() > 4 )
878 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
881 if ( !nl || nl->value().isValid() )
883 orderBy = node->
dump();
894 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->id(),
895 QString::number(
static_cast< int >( aggregate ) ),
908 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
912 if ( !error.isEmpty() )
913 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
915 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
929 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
937 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
941 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
950 QString subExpression = node->
dump();
954 if ( values.count() > 1 )
956 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
959 if ( !nl || nl->value().isValid() )
960 groupBy = node->
dump();
964 if ( values.count() > 2 )
966 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
969 if ( !nl || nl->value().isValid() )
975 if ( orderByPos >= 0 && values.count() > orderByPos )
977 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
980 if ( !nl || nl->value().isValid() )
982 orderBy = node->
dump();
990 if ( !groupBy.isEmpty() )
993 QVariant groupByValue = groupByExp.evaluate( context );
994 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
997 if ( !parameters.
filter.isEmpty() )
998 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
1000 parameters.
filter = groupByClause;
1006 bool isStatic =
true;
1007 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
1008 for (
const QString &varName : refVars )
1011 if ( scope && !scope->
isStatic( varName ) )
1021 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter,
1022 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
1026 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number(
static_cast< int >( aggregate ) ), subExpression, parameters.
filter, orderBy );
1038 subContext.appendScope( subScope );
1040 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
1044 if ( !error.isEmpty() )
1045 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
1047 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1152 if ( values.count() > 3 )
1154 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1156 QVariant value = node->
eval( parent, context );
1158 parameters.
delimiter = value.toString();
1169 if ( values.count() > 3 )
1171 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1173 QVariant value = node->
eval( parent, context );
1175 parameters.
delimiter = value.toString();
1191 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1196 const double v = scale.toDouble( &ok );
1204 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1205 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1206 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1209 if ( testValue <= minValue )
1211 return QVariant( minValue );
1213 else if ( testValue >= maxValue )
1215 return QVariant( maxValue );
1219 return QVariant( testValue );
1225 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1226 return QVariant( std::floor( x ) );
1231 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1232 return QVariant( std::ceil( x ) );
1237 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1241 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1245 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1250 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1251 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1252 if ( format.isEmpty() && !language.isEmpty() )
1254 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1255 return QVariant( QDateTime() );
1258 if ( format.isEmpty() && language.isEmpty() )
1259 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1261 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1262 QLocale locale = QLocale();
1263 if ( !language.isEmpty() )
1265 locale = QLocale( language );
1268 QDateTime datetime = locale.toDateTime( datetimestring, format );
1269 if ( !datetime.isValid() )
1271 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1272 datetime = QDateTime();
1274 return QVariant( datetime );
1279 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1280 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1281 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1283 const QDate date( year, month, day );
1284 if ( !date.isValid() )
1286 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1289 return QVariant( date );
1294 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1295 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1296 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1298 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1299 if ( !time.isValid() )
1301 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1304 return QVariant( time );
1309 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1310 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1311 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1312 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1313 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1314 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1316 const QDate date( year, month, day );
1317 if ( !date.isValid() )
1319 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1322 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1323 if ( !time.isValid() )
1325 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1328 return QVariant( QDateTime( date, time ) );
1333 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1334 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1335 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1336 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1337 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1338 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1339 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1341 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1346 for (
const QVariant &value : values )
1357 const QVariant val1 = values.at( 0 );
1358 const QVariant val2 = values.at( 1 );
1368 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1369 return QVariant(
str.toLower() );
1373 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1374 return QVariant(
str.toUpper() );
1378 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1379 QStringList elems =
str.split(
' ' );
1380 for (
int i = 0; i < elems.size(); i++ )
1382 if ( elems[i].size() > 1 )
1383 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1385 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1390 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1391 return QVariant(
str.trimmed() );
1396 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1398 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1400 const QRegularExpression re( QStringLiteral(
"^([%1]*)" ).arg( QRegularExpression::escape( characters ) ) );
1401 str.replace( re, QString() );
1402 return QVariant(
str );
1407 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1409 const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1411 const QRegularExpression re( QStringLiteral(
"([%1]*)$" ).arg( QRegularExpression::escape( characters ) ) );
1412 str.replace( re, QString() );
1413 return QVariant(
str );
1418 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1419 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1425 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1426 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1432 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1433 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1435 return ( dist < 0 ? QVariant() : QVariant(
QgsStringUtils::hammingDistance( string1, string2, true ) ) );
1440 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1446 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1447 return QVariant( QString( character ) );
1452 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1454 if ( value.isEmpty() )
1459 int res = value.at( 0 ).unicode();
1460 return QVariant( res );
1465 if ( values.length() == 2 || values.length() == 3 )
1467 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1468 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1470 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1481 if ( values.at( 0 ).userType() == qMetaTypeId< QgsGeometry>() )
1484 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1488 return QVariant( geom.
length() );
1492 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1493 return QVariant(
str.length() );
1498 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1503 double totalLength = 0;
1506 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1508 totalLength += line->length3D();
1512 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1513 totalLength += segmentized->length3D();
1522 if ( values.count() == 2 && values.at( 1 ).userType() == QMetaType::Type::QVariantMap )
1524 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1525 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1526 QVector< QPair< QString, QString > > mapItems;
1528 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1530 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1534 std::sort( mapItems.begin(),
1536 [](
const QPair< QString, QString > &pair1,
1537 const QPair< QString, QString > &pair2 )
1539 return ( pair1.first.length() > pair2.first.length() );
1542 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1544 str =
str.replace( it->first, it->second );
1547 return QVariant(
str );
1549 else if ( values.count() == 3 )
1551 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1552 QVariantList before;
1554 bool isSingleReplacement =
false;
1556 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).userType() != QMetaType::Type::QStringList )
1558 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1562 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1565 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1567 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1568 isSingleReplacement =
true;
1572 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1575 if ( !isSingleReplacement && before.length() != after.length() )
1577 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1581 for (
int i = 0; i < before.length(); i++ )
1583 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1586 return QVariant(
str );
1590 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1597 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1598 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1599 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), 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.replace( re, after ) );
1612 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1613 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1615 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1616 if ( !re.isValid() )
1618 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1621 return QVariant( (
str.indexOf( re ) + 1 ) );
1626 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1627 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1628 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1630 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1631 if ( !re.isValid() )
1633 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1637 QRegularExpressionMatch matches = re.match(
str );
1638 if ( matches.hasMatch() )
1641 QStringList list = matches.capturedTexts();
1644 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1646 array += ( !( *it ).isEmpty() ) ? *it : empty;
1649 return QVariant( array );
1659 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1660 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1662 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1663 if ( !re.isValid() )
1665 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1670 QRegularExpressionMatch match = re.match(
str );
1671 if ( match.hasMatch() )
1674 if ( match.lastCapturedIndex() > 0 )
1677 return QVariant( match.captured( 1 ) );
1682 return QVariant( match.captured( 0 ) );
1687 return QVariant(
"" );
1693 QString uuid = QUuid::createUuid().toString();
1694 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1695 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1696 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1697 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1703 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1706 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1707 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1710 if ( values.at( 2 ).isValid() )
1711 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1717 from =
str.size() + from;
1723 else if ( from > 0 )
1731 len =
str.size() + len - from;
1738 return QVariant(
str.mid( from, len ) );
1744 return QVariant(
static_cast< int >( f.
id() ) );
1749 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1750 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1751 bool foundLayer =
false;
1752 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom](
QgsMapLayer * mapLayer )
1754 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
1755 if ( !layer || !layer->dataProvider() )
1757 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1761 if ( bandNb < 1 || bandNb > layer->bandCount() )
1763 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1769 parent->setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1777 if ( multiPoint.count() == 1 )
1779 point = multiPoint[0];
1788 double value = layer->dataProvider()->sample( point, bandNb );
1789 return std::isnan( value ) ? QVariant() : value;
1795 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1806 const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1807 const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1809 bool foundLayer =
false;
1810 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value](
QgsMapLayer * mapLayer )-> QVariant
1812 QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
1813 if ( !layer || !layer->dataProvider() )
1815 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1819 if ( bandNb < 1 || bandNb > layer->bandCount() )
1821 parent->setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster band number." ) );
1825 if ( std::isnan( value ) )
1827 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster value." ) );
1831 if ( ! layer->dataProvider()->attributeTable( bandNb ) )
1836 const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
1837 if ( data.isEmpty() )
1843 const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
1844 for (
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
1847 if ( field.isColor() || field.isRamp() )
1851 result.insert( fields.at( idx ).name, data.at( idx ) );
1859 parent->
setEvalErrorString( QObject::tr(
"Function `raster_attributes` requires a valid raster layer." ) );
1880 if ( values.size() == 1 )
1882 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1885 else if ( values.size() == 2 )
1887 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1888 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1892 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1901 QString table { R
"html(
1904 <tr><th>%1</th></tr>
1907 <tr><td>%2</td></tr>
1911 if ( values.size() == 1 )
1913 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1917 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_table` requires one parameter. %n given.",
nullptr, values.length() ) );
1921 if ( dict.isEmpty() )
1926 QStringList headers;
1929 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1931 headers.push_back( it.key().toHtmlEscaped() );
1932 cells.push_back( it.value().toString( ).toHtmlEscaped() );
1935 return table.arg( headers.join( QLatin1String(
"</th><th>" ) ), cells.join( QLatin1String(
"</td><td>" ) ) );
1940 QString table { R
"html(
1945 if ( values.size() == 1 )
1947 dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
1951 parent->
setEvalErrorString( QObject::tr(
"Function `map_to_html_dl` requires one parameter. %n given.",
nullptr, values.length() ) );
1955 if ( dict.isEmpty() )
1962 for (
auto it = dict.cbegin(); it != dict.cend(); ++it )
1964 rows.append( QStringLiteral(
"<dt>%1</dt><dd>%2</dd>" ).arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
1967 return table.arg( rows );
1975 layer = context->
variable( QStringLiteral(
"layer" ) );
1980 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
1982 layer = node->
eval( parent, context );
1993 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1997 const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
1998 if ( strength == QLatin1String(
"hard" ) )
2002 else if ( strength == QLatin1String(
"soft" ) )
2007 bool foundLayer =
false;
2008 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2010 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2013 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2019 for (
int i = 0; i < fields.
size(); i++ )
2034 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2046 layer = context->
variable( QStringLiteral(
"layer" ) );
2051 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
2053 layer = node->
eval( parent, context );
2064 feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
2068 const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
2069 if ( strength == QLatin1String(
"hard" ) )
2073 else if ( strength == QLatin1String(
"soft" ) )
2078 const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2080 bool foundLayer =
false;
2081 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength](
QgsMapLayer * mapLayer ) -> QVariant
2083 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2090 if ( fieldIndex == -1 )
2092 parent->
setEvalErrorString( QObject::tr(
"The attribute name did not match any field for the given feature" ) );
2103 parent->
setEvalErrorString( QObject::tr(
"No layer provided to conduct constraints checks" ) );
2119 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2124 for (
int i = 0; i < fields.
count(); ++i )
2138 if ( values.isEmpty() )
2141 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2143 else if ( values.size() == 1 )
2145 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2146 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2148 else if ( values.size() == 2 )
2150 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2151 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2155 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2162 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
2168 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
2174 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
2176 const QString fieldName { fields.
at( fieldIndex ).
name() };
2177 const QVariant attributeVal = feature.
attribute( fieldIndex );
2178 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
2181 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
2190 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
2202 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
2204 result.insert( fields.
at( fieldIndex ).
name(), value );
2220 bool evaluate =
true;
2224 if ( values.isEmpty() )
2227 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2229 else if ( values.size() == 1 )
2231 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), context, parent );
2232 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2234 else if ( values.size() == 2 )
2236 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2237 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2239 else if ( values.size() == 3 )
2241 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
2242 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2243 evaluate = values.value( 2 ).toBool();
2249 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2253 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
2285 subContext.setFeature( feature );
2294 exp.prepare( &subContext );
2295 return exp.evaluate( &subContext ).toString();
2301 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
2306 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
2313 if ( values.isEmpty() )
2316 layer = context->
variable( QStringLiteral(
"layer" ) );
2318 else if ( values.size() == 1 )
2320 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
2321 layer = context->
variable( QStringLiteral(
"layer" ) );
2323 else if ( values.size() == 2 )
2325 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
2326 layer = values.at( 0 );
2330 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
2334 bool foundLayer =
false;
2335 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature](
QgsMapLayer * mapLayer ) -> QVariant
2337 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2338 if ( !layer || !feature.
isValid() )
2355 if ( values.isEmpty() )
2356 layer = context->
variable( QStringLiteral(
"layer" ) );
2357 else if ( values.count() == 1 )
2358 layer = values.at( 0 );
2361 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
2365 bool foundLayer =
false;
2366 const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [](
QgsMapLayer * mapLayer ) -> QVariant
2368 QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
2384 static QMap<QString, qlonglong> counterCache;
2385 QVariant functionResult;
2387 auto fetchAndIncrementFunc = [ values, parent, &functionResult ](
QgsMapLayer * mapLayer,
const QString & databaseArgument )
2391 const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
2396 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
2397 if ( database.isEmpty() )
2399 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2404 database = databaseArgument;
2407 const QString table = values.at( 1 ).toString();
2408 const QString idColumn = values.at( 2 ).toString();
2409 const QString filterAttribute = values.at( 3 ).toString();
2410 const QVariant filterValue = values.at( 4 ).toString();
2411 const QVariantMap defaultValues = values.at( 5 ).toMap();
2417 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2420 functionResult = QVariant();
2424 QString errorMessage;
2425 QString currentValSql;
2427 qlonglong nextId = 0;
2428 bool cachedMode =
false;
2429 bool valueRetrieved =
false;
2431 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2438 auto cachedCounter = counterCache.find( cacheString );
2440 if ( cachedCounter != counterCache.end() )
2442 qlonglong &cachedValue = cachedCounter.value();
2443 nextId = cachedValue;
2445 cachedValue = nextId;
2446 valueRetrieved =
true;
2451 if ( !cachedMode || !valueRetrieved )
2453 int result = SQLITE_ERROR;
2456 if ( !filterAttribute.isNull() )
2461 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2463 if ( result == SQLITE_OK )
2466 if ( sqliteStatement.
step() == SQLITE_ROW )
2472 if ( cachedMode && result == SQLITE_OK )
2474 counterCache.insert( cacheString, nextId );
2478 counterCache.remove( cacheString );
2481 valueRetrieved =
true;
2485 if ( valueRetrieved )
2494 if ( !filterAttribute.isNull() )
2500 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2503 vals << iter.value().toString();
2506 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2507 upsertSql += QLatin1String(
" VALUES " );
2508 upsertSql +=
'(' + vals.join(
',' ) +
')';
2510 int result = SQLITE_ERROR;
2514 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2521 result = sqliteDb.
exec( upsertSql, errorMessage );
2523 if ( result == SQLITE_OK )
2525 functionResult = QVariant( nextId );
2530 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2531 functionResult = QVariant();
2536 functionResult = QVariant();
2539 bool foundLayer =
false;
2540 QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc](
QgsMapLayer * layer )
2542 fetchAndIncrementFunc( layer, QString() );
2546 const QString databasePath = values.at( 0 ).toString();
2549 fetchAndIncrementFunc(
nullptr, databasePath );
2553 return functionResult;
2559 for (
const QVariant &value : values )
2562 concat += QgsExpressionUtils::getStringValue( value, parent );
2569 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2570 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2575 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2576 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2577 return string.right( pos );
2582 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2583 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2584 return string.left( pos );
2589 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2590 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2591 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2592 return string.leftJustified( length, fill.at( 0 ),
true );
2597 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2598 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2599 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2600 return string.rightJustified( length, fill.at( 0 ),
true );
2605 if ( values.size() < 1 )
2607 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2611 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2612 for (
int n = 1; n < values.length(); n++ )
2614 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2622 return QVariant( QDateTime::currentDateTime() );
2627 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2628 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2629 if ( format.isEmpty() && !language.isEmpty() )
2631 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2632 return QVariant( QDate() );
2635 if ( format.isEmpty() && language.isEmpty() )
2636 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2638 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2639 QLocale locale = QLocale();
2640 if ( !language.isEmpty() )
2642 locale = QLocale( language );
2645 QDate date = locale.toDate( datestring, format );
2646 if ( !date.isValid() )
2648 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2651 return QVariant( date );
2656 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2657 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2658 if ( format.isEmpty() && !language.isEmpty() )
2660 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2661 return QVariant( QTime() );
2664 if ( format.isEmpty() && language.isEmpty() )
2665 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2667 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2668 QLocale locale = QLocale();
2669 if ( !language.isEmpty() )
2671 locale = QLocale( language );
2674 QTime time = locale.toTime( timestring, format );
2675 if ( !time.isValid() )
2677 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2680 return QVariant( time );
2685 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2694 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2695 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2696 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2698 QString formatString;
2699 if ( values.count() > 3 )
2700 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2703 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2707 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2711 else if ( ! formatString.isEmpty() )
2713 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2717 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2721 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2727 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2735 return floatToDegreeFormat( format, values, context, parent, node );
2742 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2744 return ok ? QVariant( value ) : QVariant();
2750 return floatToDegreeFormat( format, values, context, parent, node );
2755 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2756 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2757 qint64 seconds = d2.secsTo( d1 );
2758 return QVariant::fromValue(
QgsInterval( seconds ) );
2763 if ( !values.at( 0 ).canConvert<QDate>() )
2766 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2767 if ( !date.isValid() )
2772 return date.dayOfWeek() % 7;
2777 QVariant value = values.at( 0 );
2778 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2781 return QVariant( inter.
days() );
2785 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2786 return QVariant( d1.date().day() );
2792 QVariant value = values.at( 0 );
2793 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2796 return QVariant( inter.
years() );
2800 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2801 return QVariant( d1.date().year() );
2807 QVariant value = values.at( 0 );
2808 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2811 return QVariant( inter.
months() );
2815 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2816 return QVariant( d1.date().month() );
2822 QVariant value = values.at( 0 );
2823 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2826 return QVariant( inter.
weeks() );
2830 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2831 return QVariant( d1.date().weekNumber() );
2837 QVariant value = values.at( 0 );
2838 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2841 return QVariant( inter.
hours() );
2845 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2846 return QVariant( t1.hour() );
2852 QVariant value = values.at( 0 );
2853 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2856 return QVariant( inter.
minutes() );
2860 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2861 return QVariant( t1.minute() );
2867 QVariant value = values.at( 0 );
2868 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2871 return QVariant( inter.
seconds() );
2875 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2876 return QVariant( t1.second() );
2882 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2885 return QVariant( dt.toMSecsSinceEpoch() );
2895 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2897 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2902 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2905 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2908 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2914 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
2917 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2924#define ENSURE_GEOM_TYPE(f, g, geomtype) \
2925 if ( !(f).hasGeometry() ) \
2926 return QVariant(); \
2927 QgsGeometry g = (f).geometry(); \
2928 if ( (g).type() != (geomtype) ) \
2935 if ( g.isMultipart() )
2937 return g.asMultiPoint().at( 0 ).x();
2941 return g.asPoint().x();
2949 if ( g.isMultipart() )
2951 return g.asMultiPoint().at( 0 ).y();
2955 return g.asPoint().y();
2969 if ( g.isEmpty() || !abGeom->
is3D() )
2974 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2980 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2982 if ( collection->numGeometries() > 0 )
2984 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2995 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3001 return QVariant( isValid );
3006 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3010 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
3011#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
3016 if ( methodString.compare( QLatin1String(
"linework" ), Qt::CaseInsensitive ) == 0 )
3018 else if ( methodString.compare( QLatin1String(
"structure" ), Qt::CaseInsensitive ) == 0 )
3021 const bool keepCollapsed = values.value( 2 ).toBool();
3026 valid = geom.
makeValid( method, keepCollapsed );
3030 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
3034 return QVariant::fromValue( valid );
3039 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3045 for (
int i = 0; i < multiGeom.size(); ++i )
3047 array += QVariant::fromValue( multiGeom.at( i ) );
3055 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3067 QVariant result( centroid.asPoint().
x() );
3073 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3085 QVariant result( centroid.asPoint().
y() );
3091 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3101 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3109 if ( collection->numGeometries() == 1 )
3111 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3122 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3132 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3140 if ( collection->numGeometries() == 1 )
3142 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
3153 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3158 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3185 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3202 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3219 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3224 bool ignoreClosing =
false;
3225 if ( values.length() > 1 )
3227 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3237 bool skipLast =
false;
3238 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
3243 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
3255 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3266 for (
int i = 0; i < line->numPoints() - 1; ++i )
3270 << line->pointN( i )
3271 << line->pointN( i + 1 ) );
3282 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3292 if ( collection->numGeometries() == 1 )
3294 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
3299 if ( !curvePolygon )
3303 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3309 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
3315 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3325 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
3331 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
3337 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3346 return QVariant::fromValue(
QgsGeometry( boundary ) );
3351 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3360 return QVariant::fromValue( merged );
3365 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3369 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3374 if ( sharedPaths.
isNull() )
3377 return QVariant::fromValue( sharedPaths );
3383 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3388 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3391 if ( simplified.
isNull() )
3399 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3404 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3409 if ( simplified.
isNull() )
3417 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3422 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3423 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3424 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3425 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3427 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3436 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3441 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3442 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3443 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3454 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3459 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3460 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3461 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3462 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3463 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3466 minAmplitude, maxAmplitude, seed );
3475 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3480 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3481 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3482 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3493 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3498 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3499 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3500 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3501 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3502 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3505 minAmplitude, maxAmplitude, seed );
3514 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3519 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3520 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3521 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3532 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3537 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3538 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3539 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3540 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3541 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3544 minAmplitude, maxAmplitude, seed );
3553 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3558 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3559 QVector< double > dashPattern;
3560 dashPattern.reserve( pattern.size() );
3561 for (
const QVariant &value : std::as_const( pattern ) )
3564 double v = value.toDouble( &ok );
3571 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3576 if ( dashPattern.size() % 2 != 0 )
3578 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3582 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3584 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3586 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3588 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3590 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3592 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3596 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3600 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3602 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3604 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3606 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3608 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3610 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3614 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3618 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3620 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3622 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3624 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3628 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3632 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3643 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3648 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3650 if ( densified.
isNull() )
3658 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3663 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3665 if ( densified.
isNull() )
3674 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3676 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3683 QVector< QgsGeometry > parts;
3684 parts.reserve( list.size() );
3685 for (
const QVariant &value : std::as_const( list ) )
3687 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
3703 if ( values.count() < 2 || values.count() > 4 )
3705 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3709 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3710 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3711 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3712 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3713 switch ( values.count() )
3727 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3728 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3729 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3735 if ( values.empty() )
3740 QVector<QgsPoint> points;
3741 points.reserve( values.count() );
3743 auto addPoint = [&points](
const QgsGeometry & geom )
3751 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3758 for (
const QVariant &value : values )
3760 if ( value.userType() == QMetaType::Type::QVariantList )
3762 const QVariantList list = value.toList();
3763 for (
const QVariant &v : list )
3765 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3770 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3774 if ( points.count() < 2 )
3782 if ( values.count() < 1 )
3784 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3788 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3796 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3798 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3805 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3810 if ( !exteriorRing )
3813 polygon->setExteriorRing( exteriorRing->
segmentize() );
3816 for (
int i = 1; i < values.count(); ++i )
3818 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3825 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3832 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3840 polygon->addInteriorRing( ring->
segmentize() );
3843 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3848 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3849 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3850 lineString->clear();
3852 for (
const QVariant &value : values )
3854 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3861 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3868 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3876 lineString->addVertex( *point );
3879 tr->setExteriorRing( lineString.release() );
3881 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3886 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3893 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3894 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3901 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3908 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3916 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3921 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3928 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3929 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3930 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3931 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3937 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3944 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3951 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3952 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3958 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3965 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3972 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3975 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3982 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3986 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3993 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4000 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
4007 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4022 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4028 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4034 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4035 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4043 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4049 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4055 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
4064 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
4067 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
4068 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
4069 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
4088 return QVariant::fromValue( geom.
vertexAt( idx ) );
4096 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4098 const QVariant v = pointAt( geom, idx, parent );
4101 return QVariant( v.value<
QgsPoint>().
x() );
4107 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4109 return fcnOldXat( values, f, parent, node );
4111 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4113 return fcnOldXat( QVariantList() << values[1], f, parent, node );
4116 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4122 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4124 const QVariant v = pointAt( geom, vertexNumber, parent );
4126 return QVariant( v.value<
QgsPoint>().
x() );
4136 const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4138 const QVariant v = pointAt( geom, idx, parent );
4141 return QVariant( v.value<
QgsPoint>().
y() );
4147 if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() )
4149 return fcnOldYat( values, f, parent, node );
4151 else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() )
4153 return fcnOldYat( QVariantList() << values[1], f, parent, node );
4156 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4162 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4164 const QVariant v = pointAt( geom, vertexNumber, parent );
4166 return QVariant( v.value<
QgsPoint>().
y() );
4173 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4179 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4181 const QVariant v = pointAt( geom, vertexNumber, parent );
4183 return QVariant( v.value<
QgsPoint>().
z() );
4190 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4196 const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4198 const QVariant v = pointAt( geom, vertexNumber, parent );
4200 return QVariant( v.value<
QgsPoint>().
m() );
4219 return QVariant::fromValue( geom );
4227 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4229 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4235 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
4241 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4246 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4253 ogcContext.
layer = mapLayerPtr.data();
4254 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
4258 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4271 return QVariant( area );
4281 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4286 return QVariant( geom.
area() );
4298 return QVariant( len );
4315 return QVariant( len );
4319 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
4325 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4331 return QVariant( geom.
length() );
4336 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4337 return QVariant( geom.
isNull() ? 0 : geom.constGet()->nCoordinates() );
4342 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4351 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4360 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4375 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
4376 if ( !curvePolygon )
4379 return QVariant( curvePolygon->
isEmpty() ? 0 : curvePolygon->numInteriorRings() );
4388 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4395 return QVariant( curvePolygon->
ringCount() );
4397 bool foundPoly =
false;
4405 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
4406 if ( !curvePolygon )
4417 return QVariant( ringCount );
4422 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4424 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
4430 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4436 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4442 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4451 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4457 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4463 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4469 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4475 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4483 double max = std::numeric_limits< double >::lowest();
4487 double z = ( *it ).z();
4493 if ( max == std::numeric_limits< double >::lowest() )
4496 return QVariant( max );
4501 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4509 double min = std::numeric_limits< double >::max();
4513 double z = ( *it ).z();
4519 if ( min == std::numeric_limits< double >::max() )
4522 return QVariant( min );
4527 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4535 double min = std::numeric_limits< double >::max();
4539 double m = ( *it ).m();
4545 if ( min == std::numeric_limits< double >::max() )
4548 return QVariant( min );
4553 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4561 double max = std::numeric_limits< double >::lowest();
4565 double m = ( *it ).m();
4571 if ( max == std::numeric_limits< double >::lowest() )
4574 return QVariant( max );
4579 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4580 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
4583 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
4592 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4596 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4605 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4610 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4621 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4625 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4627 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4632 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4636 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4643 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4651 return QVariant::fromValue( curve->
isClosed() );
4656 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4669 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4670 closedLine->close();
4672 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4682 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4684 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4685 closedLine->close();
4687 closed->addGeometry( closedLine.release() );
4690 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4698 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4702 return QVariant::fromValue( fGeom.
isEmpty() );
4708 return QVariant::fromValue(
true );
4710 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4711 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4716 if ( values.length() < 2 || values.length() > 3 )
4719 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4720 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4727 if ( values.length() == 2 )
4730 QString result = engine->relate( sGeom.
constGet() );
4731 return QVariant::fromValue( result );
4736 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4737 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4738 return QVariant::fromValue( result );
4744 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4745 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4750 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4751 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4752 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4756 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4757 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4758 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4762 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4763 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4764 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4768 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4769 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4770 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4774 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4775 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4776 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4780 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4781 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4782 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4786 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4787 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4788 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4793 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4794 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4795 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4796 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4797 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4798 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4801 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4803 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4807 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4809 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4813 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4819 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4821 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4826 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4828 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4833 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4835 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4840 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4841 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4848 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4855 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4859 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4860 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4861 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4862 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4865 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4871 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4874 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4878 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4879 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4880 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4883 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4889 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4892 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4896 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4899 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4905 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4906 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4907 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4908 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4909 if ( joinInt < 1 || joinInt > 3 )
4913 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4916 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4922 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4923 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4924 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4926 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4927 if ( joinInt < 1 || joinInt > 3 )
4931 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4934 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4940 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4941 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4942 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4945 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4951 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4952 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4953 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4955 return QVariant::fromValue( fGeom );
4960 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4961 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4962 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4964 const bool perPart = values.value( 3 ).toBool();
4971 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4974 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4975 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4976 t.rotate( -rotation );
4977 t.translate( -partCenter.
x(), -partCenter.
y() );
4978 ( *it )->transform( t );
4980 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4992 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
5000 fGeom.
rotate( rotation, pt );
5001 return QVariant::fromValue( fGeom );
5007 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5008 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5009 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5010 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
5021 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
5029 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
5030 t.scale( xScale, yScale );
5031 t.translate( -pt.
x(), -pt.
y() );
5033 return QVariant::fromValue( fGeom );
5038 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5044 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5045 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5047 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5049 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
5050 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
5052 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
5053 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
5054 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
5055 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
5066 QTransform transform;
5067 transform.translate( deltaX, deltaY );
5068 transform.rotate( rotationZ );
5069 transform.scale( scaleX, scaleY );
5070 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
5072 return QVariant::fromValue( fGeom );
5078 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5080 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5085 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5087 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5093 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5094 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5096 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5102 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5104 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5108#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
5113 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5114 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5115 const bool allowHoles = values.value( 2 ).toBool();
5117 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5130 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5132 if ( values.length() == 2 )
5133 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5141 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5147 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5149 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5155 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5161 double area,
angle, width, height;
5174 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5175 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5177 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5183 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5190 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
5195 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
5203 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
5205 reversed->addGeometry( curve->
reversed() );
5212 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
5219 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5230 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
5239 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
5245 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5246 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5247 return QVariant( fGeom.
distance( sGeom ) );
5252 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5253 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5256 if ( values.length() == 3 && values.at( 2 ).isValid() )
5258 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5259 densify = std::clamp( densify, 0.0, 1.0 );
5267 return res > -1 ? QVariant( res ) : QVariant();
5272 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5273 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5275 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5280 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5281 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5283 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5288 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5289 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5291 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5297 if ( values.length() < 1 || values.length() > 2 )
5300 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5302 if ( values.length() == 2 )
5303 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5304 QString wkt = fGeom.
asWkt( prec );
5305 return QVariant( wkt );
5310 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5311 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
5316 if ( values.length() != 2 )
5318 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
5322 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5323 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5325 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5332 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5337 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5344 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5351 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
5358 if ( pt1->
y() < pt2->
y() )
5360 else if ( pt1->
y() > pt2->
y() )
5368 if ( pt1->
x() < pt2->
x() )
5370 else if ( pt1->
x() > pt2->
x() )
5371 return M_PI + ( M_PI_2 );
5376 if ( pt1->
x() < pt2->
x() )
5378 if ( pt1->
y() < pt2->
y() )
5380 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() ) )
5391 if ( pt1->
y() > pt2->
y() )
5393 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
5398 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
5399 + ( M_PI + ( M_PI_2 ) );
5406 const QgsGeometry geom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5407 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5408 QString sourceCrs = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5409 QString ellipsoid = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
5413 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires two valid point geometries." ) );
5421 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires point geometries or multi point geometries with a single part." ) );
5430 if ( sourceCrs.isEmpty() )
5432 sourceCrs = context->
variable( QStringLiteral(
"layer_crs" ) ).toString();
5435 if ( ellipsoid.isEmpty() )
5437 ellipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
5444 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid source CRS." ) );
5452 parent->
setEvalErrorString( QObject::tr(
"Function `bearing` requires a valid ellipsoid acronym or ellipsoid authority ID." ) );
5458 const double bearing = da.
bearing( point1, point2 );
5459 if ( std::isfinite( bearing ) )
5461 return std::fmod( bearing + 2 * M_PI, 2 * M_PI );
5474 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5478 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
5482 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5483 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5484 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
5487 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
5494 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5495 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5497 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
5504 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5508 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
5515 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
5523 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
5533 if ( values.length() != 3 )
5536 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5537 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5538 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5542 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
5548 if ( values.length() < 2 )
5551 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5554 return values.at( 0 );
5556 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5557 QVariant cachedExpression;
5562 if ( cachedExpression.isValid() )