67 #include <QMimeDatabase>
68 #include <QProcessEnvironment>
69 #include <QCryptographicHash>
70 #include <QRegularExpression>
93 QVariantList argValues;
97 const QList< QgsExpressionNode * > argList = args->
list();
104 v = QVariant::fromValue( n );
108 v = n->eval( parent, context );
110 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
111 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
114 argValues.append( v );
119 return func( argValues, context, parent, node );
130 return QStringList();
157 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
162 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
174 const QString &group,
175 const QString &helpText,
179 const QStringList &aliases,
183 , mAliases( aliases )
184 , mUsesGeometry( false )
185 , mUsesGeometryFunc( usesGeometry )
186 , mReferencedColumnsFunc( referencedColumns )
198 if ( mUsesGeometryFunc )
199 return mUsesGeometryFunc( node );
201 return mUsesGeometry;
206 if ( mReferencedColumnsFunc )
207 return mReferencedColumnsFunc( node );
209 return mReferencedColumns;
215 return mIsStaticFunc( node, parent, context );
223 return mPrepareFunc( node, parent, context );
235 mIsStaticFunc =
nullptr;
241 mPrepareFunc = prepareFunc;
246 if ( node && node->
args() )
248 const QList< QgsExpressionNode * > argList = node->
args()->
list();
251 if ( !argNode->isStatic( parent, context ) )
261 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
262 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
263 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
265 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
272 double current = start + step;
273 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
288 QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
294 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
303 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
305 return expression.evaluate( context );
310 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
311 return QVariant( std::sqrt( x ) );
316 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
317 return QVariant( std::fabs( val ) );
322 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
323 return ( deg * M_PI ) / 180;
327 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
328 return ( 180 * rad ) / M_PI;
332 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
333 return QVariant( std::sin( x ) );
337 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
338 return QVariant( std::cos( x ) );
342 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::tan( x ) );
347 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
348 return QVariant( std::asin( x ) );
352 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
353 return QVariant( std::acos( x ) );
357 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
358 return QVariant( std::atan( x ) );
362 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
364 return QVariant( std::atan2( y, x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::exp( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
376 return QVariant( std::log( x ) );
380 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
383 return QVariant( log10( x ) );
387 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
388 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
389 if ( x <= 0 || b <= 0 )
391 return QVariant( std::log( x ) / std::log( b ) );
395 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
396 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
400 std::random_device rd;
401 std::mt19937_64 generator( rd() );
403 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
406 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
409 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
414 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
415 std::hash<std::string> hasher;
416 seed = hasher( seedStr.toStdString() );
418 generator.seed( seed );
422 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
423 return QVariant( min + f * ( max - min ) );
427 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
428 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
432 std::random_device rd;
433 std::mt19937_64 generator( rd() );
435 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
438 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
441 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
446 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
447 std::hash<std::string> hasher;
448 seed = hasher( seedStr.toStdString() );
450 generator.seed( seed );
453 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
454 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
455 return QVariant( randomInteger );
458 return QVariant(
int( randomInteger ) );
463 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
464 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
465 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
466 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
467 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
469 if ( domainMin >= domainMax )
471 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
476 if ( val >= domainMax )
480 else if ( val <= domainMin )
486 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
487 double c = rangeMin - ( domainMin * m );
490 return QVariant( m * val +
c );
495 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
496 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
497 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
498 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
499 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
500 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
502 if ( domainMin >= domainMax )
504 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
514 if ( val >= domainMax )
518 else if ( val <= domainMin )
524 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
529 QVariant result( QVariant::Double );
530 double maxVal = std::numeric_limits<double>::quiet_NaN();
531 for (
const QVariant &val : values )
533 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
534 if ( std::isnan( maxVal ) )
538 else if ( !std::isnan( testVal ) )
540 maxVal = std::max( maxVal, testVal );
544 if ( !std::isnan( maxVal ) )
546 result = QVariant( maxVal );
553 QVariant result( QVariant::Double );
554 double minVal = std::numeric_limits<double>::quiet_NaN();
555 for (
const QVariant &val : values )
557 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
558 if ( std::isnan( minVal ) )
562 else if ( !std::isnan( testVal ) )
564 minVal = std::min( minVal, testVal );
568 if ( !std::isnan( minVal ) )
570 result = QVariant( minVal );
582 QVariant value = node->
eval( parent, context );
584 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, parent );
587 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
592 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
594 value = node->
eval( parent, context );
600 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
605 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
607 QString subExpression = node->
dump();
611 if ( values.count() > 3 )
613 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
616 if ( !nl || nl->value().isValid() )
621 if ( values.count() > 4 )
623 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
625 value = node->
eval( parent, context );
632 if ( values.count() > 5 )
634 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
637 if ( !nl || nl->value().isValid() )
639 orderBy = node->
dump();
644 QString aggregateError;
652 bool isStatic =
true;
653 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
654 || filterExp.referencedVariables().contains( QString() )
655 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
656 || subExp.referencedVariables().contains( QString() ) )
662 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
663 for (
const QString &varName : refVars )
666 if ( scope && !scope->
isStatic( varName ) )
676 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
677 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
681 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
692 subContext.appendScope( subScope );
693 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
705 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
709 if ( !aggregateError.isEmpty() )
710 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
712 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
723 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
728 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
731 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
740 QVariant value = node->
eval( parent, context );
742 QString relationId = value.toString();
749 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
751 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
756 relation = relations.at( 0 );
763 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
765 value = node->
eval( parent, context );
771 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
776 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
778 QString subExpression = node->
dump();
782 if ( values.count() > 3 )
784 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
786 value = node->
eval( parent, context );
793 if ( values.count() > 4 )
795 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
798 if ( !nl || nl->value().isValid() )
800 orderBy = node->
dump();
811 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->
id(),
812 QString::number(
static_cast< int >( aggregate ) ),
825 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
829 if ( !error.isEmpty() )
830 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
832 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
846 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
851 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
854 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
863 QString subExpression = node->
dump();
867 if ( values.count() > 1 )
869 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
872 if ( !nl || nl->value().isValid() )
873 groupBy = node->
dump();
877 if ( values.count() > 2 )
879 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
882 if ( !nl || nl->value().isValid() )
888 if ( orderByPos >= 0 && values.count() > orderByPos )
890 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
893 if ( !nl || nl->value().isValid() )
895 orderBy = node->
dump();
903 if ( !groupBy.isEmpty() )
906 QVariant groupByValue = groupByExp.evaluate( context );
907 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
908 groupByValue.isNull() ? QStringLiteral(
"is" ) : QStringLiteral(
"=" ),
910 if ( !parameters.
filter.isEmpty() )
911 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
913 parameters.
filter = groupByClause;
919 bool isStatic =
true;
920 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
921 for (
const QString &varName : refVars )
924 if ( scope && !scope->
isStatic( varName ) )
934 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter,
935 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
939 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
951 subContext.appendScope( subScope );
953 result = vl->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
957 if ( !error.isEmpty() )
958 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
960 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1065 if ( values.count() > 3 )
1067 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1069 QVariant value = node->
eval( parent, context );
1071 parameters.
delimiter = value.toString();
1082 if ( values.count() > 3 )
1084 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1086 QVariant value = node->
eval( parent, context );
1088 parameters.
delimiter = value.toString();
1104 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1106 if ( !scale.isValid() || scale.isNull() )
1109 const double v = scale.toDouble( &ok );
1117 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1118 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1119 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1122 if ( testValue <= minValue )
1124 return QVariant( minValue );
1126 else if ( testValue >= maxValue )
1128 return QVariant( maxValue );
1132 return QVariant( testValue );
1138 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1139 return QVariant( std::floor( x ) );
1144 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1145 return QVariant( std::ceil( x ) );
1150 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1154 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1158 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1163 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1164 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1165 if ( format.isEmpty() && !language.isEmpty() )
1167 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1168 return QVariant( QDateTime() );
1171 if ( format.isEmpty() && language.isEmpty() )
1172 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1174 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1175 QLocale locale = QLocale();
1176 if ( !language.isEmpty() )
1178 locale = QLocale( language );
1181 QDateTime datetime = locale.toDateTime( datetimestring, format );
1182 if ( !datetime.isValid() )
1184 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1185 datetime = QDateTime();
1187 return QVariant( datetime );
1192 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1193 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1194 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1196 const QDate date( year, month, day );
1197 if ( !date.isValid() )
1199 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1202 return QVariant( date );
1207 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1208 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1209 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1211 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1212 if ( !time.isValid() )
1214 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1217 return QVariant( time );
1222 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1223 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1224 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1225 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1226 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1227 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1229 const QDate date( year, month, day );
1230 if ( !date.isValid() )
1232 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1235 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1236 if ( !time.isValid() )
1238 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1241 return QVariant( QDateTime( date, time ) );
1246 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1247 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1248 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1249 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1250 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1251 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1252 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1254 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1259 for (
const QVariant &value : values )
1261 if ( value.isNull() )
1270 const QVariant val1 = values.at( 0 );
1271 const QVariant val2 = values.at( 1 );
1281 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1282 return QVariant(
str.toLower() );
1286 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1287 return QVariant(
str.toUpper() );
1291 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1292 QStringList elems =
str.split(
' ' );
1293 for (
int i = 0; i < elems.size(); i++ )
1295 if ( elems[i].size() > 1 )
1296 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1298 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1303 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1304 return QVariant(
str.trimmed() );
1309 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1310 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1316 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1317 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1323 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1324 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1331 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1337 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1338 return QVariant( QString( character ) );
1343 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1345 if ( value.isEmpty() )
1350 int res = value.at( 0 ).unicode();
1351 return QVariant( res );
1356 if ( values.length() == 2 || values.length() == 3 )
1358 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1359 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1361 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1375 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1379 return QVariant( geom.
length() );
1383 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1384 return QVariant(
str.length() );
1389 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1394 double totalLength = 0;
1397 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1399 totalLength += line->length3D();
1403 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1404 totalLength += segmentized->length3D();
1413 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1415 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1416 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1417 QVector< QPair< QString, QString > > mapItems;
1419 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1421 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1425 std::sort( mapItems.begin(),
1427 [](
const QPair< QString, QString > &pair1,
1428 const QPair< QString, QString > &pair2 )
1430 return ( pair1.first.length() > pair2.first.length() );
1433 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1435 str =
str.replace( it->first, it->second );
1438 return QVariant(
str );
1440 else if ( values.count() == 3 )
1442 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1443 QVariantList before;
1445 bool isSingleReplacement =
false;
1447 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
1449 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1453 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1456 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1458 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1459 isSingleReplacement =
true;
1463 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1466 if ( !isSingleReplacement && before.length() != after.length() )
1468 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1472 for (
int i = 0; i < before.length(); i++ )
1474 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1477 return QVariant(
str );
1481 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1488 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1489 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1490 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1492 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1493 if ( !re.isValid() )
1495 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1498 return QVariant(
str.replace( re, after ) );
1503 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1504 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1506 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1507 if ( !re.isValid() )
1509 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1512 return QVariant( (
str.indexOf( re ) + 1 ) );
1517 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1518 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1519 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1521 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1522 if ( !re.isValid() )
1524 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1528 QRegularExpressionMatch matches = re.match(
str );
1529 if ( matches.hasMatch() )
1532 QStringList list = matches.capturedTexts();
1535 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1537 array += ( !( *it ).isEmpty() ) ? *it : empty;
1540 return QVariant( array );
1550 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1551 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1553 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1554 if ( !re.isValid() )
1556 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1561 QRegularExpressionMatch match = re.match(
str );
1562 if ( match.hasMatch() )
1565 if ( match.lastCapturedIndex() > 0 )
1568 return QVariant( match.captured( 1 ) );
1573 return QVariant( match.captured( 0 ) );
1578 return QVariant(
"" );
1584 QString uuid = QUuid::createUuid().toString();
1585 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1586 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1587 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1588 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1594 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1597 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1598 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1601 if ( values.at( 2 ).isValid() )
1602 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1608 from =
str.size() + from;
1614 else if ( from > 0 )
1622 len =
str.size() + len - from;
1629 return QVariant(
str.mid( from, len ) );
1635 return QVariant(
static_cast< int >( f.
id() ) );
1640 QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
1643 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1647 int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1648 if ( bandNb < 1 || bandNb > layer->
bandCount() )
1650 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1654 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1657 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1665 if ( multiPoint.count() == 1 )
1667 point = multiPoint[0];
1677 return std::isnan( value ) ? QVariant() : value;
1692 if ( values.size() == 1 )
1694 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1697 else if ( values.size() == 2 )
1699 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1700 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1704 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1714 if ( values.size() == 0 || values.at( 0 ).isNull() )
1720 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1725 for (
int i = 0; i < fields.
count(); ++i )
1737 if ( values.isEmpty() )
1740 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1742 else if ( values.size() == 1 )
1744 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1745 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1747 else if ( values.size() == 2 )
1749 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1750 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1754 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1760 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
1766 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
1772 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
1774 const QString fieldName { fields.
at( fieldIndex ).
name() };
1775 const QVariant attributeVal = feature.
attribute( fieldIndex );
1776 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
1779 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
1788 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
1800 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
1802 result.insert( fields.
at( fieldIndex ).
name(), value );
1818 bool evaluate =
true;
1820 if ( values.isEmpty() )
1823 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1825 else if ( values.size() == 1 )
1827 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1828 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1830 else if ( values.size() == 2 )
1832 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1833 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1835 else if ( values.size() == 3 )
1837 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1838 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1839 evaluate = values.value( 2 ).toBool();
1845 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1849 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1880 subContext.setFeature( feature );
1889 exp.prepare( &subContext );
1890 return exp.evaluate( &subContext ).toString();
1896 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
1901 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
1909 if ( values.isEmpty() )
1912 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1914 else if ( values.size() == 1 )
1916 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1917 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1919 else if ( values.size() == 2 )
1921 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1922 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1926 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1930 if ( !layer || !feature.
isValid() )
1932 return QVariant( QVariant::Bool );
1942 if ( values.isEmpty() )
1943 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1944 else if ( values.count() == 1 )
1945 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1948 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
1954 return QVariant( QVariant::LongLong );
1962 static QMap<QString, qlonglong> counterCache;
1963 QVariant functionResult;
1965 std::function<void()> fetchAndIncrementFunc = [ =, &functionResult ]()
1968 const QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1973 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
1974 if ( database.isEmpty() )
1976 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
1981 database = values.at( 0 ).toString();
1984 const QString table = values.at( 1 ).toString();
1985 const QString idColumn = values.at( 2 ).toString();
1986 const QString filterAttribute = values.at( 3 ).toString();
1987 const QVariant filterValue = values.at( 4 ).toString();
1988 const QVariantMap defaultValues = values.at( 5 ).toMap();
1994 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
1997 functionResult = QVariant();
2001 QString errorMessage;
2002 QString currentValSql;
2004 qlonglong nextId = 0;
2005 bool cachedMode =
false;
2006 bool valueRetrieved =
false;
2008 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2015 auto cachedCounter = counterCache.find( cacheString );
2017 if ( cachedCounter != counterCache.end() )
2019 qlonglong &cachedValue = cachedCounter.value();
2020 nextId = cachedValue;
2022 cachedValue = nextId;
2023 valueRetrieved =
true;
2028 if ( !cachedMode || !valueRetrieved )
2030 int result = SQLITE_ERROR;
2033 if ( !filterAttribute.isNull() )
2038 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2040 if ( result == SQLITE_OK )
2043 if ( sqliteStatement.
step() == SQLITE_ROW )
2049 if ( cachedMode && result == SQLITE_OK )
2051 counterCache.insert( cacheString, nextId );
2055 counterCache.remove( cacheString );
2058 valueRetrieved =
true;
2062 if ( valueRetrieved )
2071 if ( !filterAttribute.isNull() )
2077 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2080 vals << iter.value().toString();
2083 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2084 upsertSql += QLatin1String(
" VALUES " );
2085 upsertSql +=
'(' + vals.join(
',' ) +
')';
2087 int result = SQLITE_ERROR;
2091 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2098 result = sqliteDb.
exec( upsertSql, errorMessage );
2100 if ( result == SQLITE_OK )
2102 functionResult = QVariant( nextId );
2107 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2108 functionResult = QVariant();
2113 functionResult = QVariant();
2118 return functionResult;
2124 for (
const QVariant &value : values )
2126 if ( !value.isNull() )
2127 concat += QgsExpressionUtils::getStringValue( value, parent );
2134 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2135 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2140 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2141 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2142 return string.right( pos );
2147 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2148 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2149 return string.left( pos );
2154 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2155 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2156 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2157 return string.leftJustified( length, fill.at( 0 ),
true );
2162 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2163 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2164 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2165 return string.rightJustified( length, fill.at( 0 ),
true );
2170 if ( values.size() < 1 )
2172 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2176 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2177 for (
int n = 1; n < values.length(); n++ )
2179 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2187 return QVariant( QDateTime::currentDateTime() );
2192 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2193 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2194 if ( format.isEmpty() && !language.isEmpty() )
2196 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2197 return QVariant( QDate() );
2200 if ( format.isEmpty() && language.isEmpty() )
2201 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2203 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2204 QLocale locale = QLocale();
2205 if ( !language.isEmpty() )
2207 locale = QLocale( language );
2210 QDate date = locale.toDate( datestring, format );
2211 if ( !date.isValid() )
2213 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2216 return QVariant( date );
2221 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2222 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2223 if ( format.isEmpty() && !language.isEmpty() )
2225 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2226 return QVariant( QTime() );
2229 if ( format.isEmpty() && language.isEmpty() )
2230 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2232 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2233 QLocale locale = QLocale();
2234 if ( !language.isEmpty() )
2236 locale = QLocale( language );
2239 QTime time = locale.toTime( timestring, format );
2240 if ( !time.isValid() )
2242 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2245 return QVariant( time );
2250 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2259 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2260 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2261 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2263 QString formatString;
2264 if ( values.count() > 3 )
2265 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2267 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2268 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2272 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2276 else if ( ! formatString.isEmpty() )
2278 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2282 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2286 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2292 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2300 return floatToDegreeFormat( format, values, context, parent, node );
2307 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2309 return ok ? QVariant( value ) : QVariant();
2315 return floatToDegreeFormat( format, values, context, parent, node );
2320 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2321 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2322 qint64 seconds = d2.secsTo( d1 );
2323 return QVariant::fromValue(
QgsInterval( seconds ) );
2328 if ( !values.at( 0 ).canConvert<QDate>() )
2331 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2332 if ( !date.isValid() )
2337 return date.dayOfWeek() % 7;
2342 QVariant value = values.at( 0 );
2343 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2346 return QVariant( inter.
days() );
2350 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2351 return QVariant( d1.date().day() );
2357 QVariant value = values.at( 0 );
2358 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2361 return QVariant( inter.
years() );
2365 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2366 return QVariant( d1.date().year() );
2372 QVariant value = values.at( 0 );
2373 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2376 return QVariant( inter.
months() );
2380 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2381 return QVariant( d1.date().month() );
2387 QVariant value = values.at( 0 );
2388 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2391 return QVariant( inter.
weeks() );
2395 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2396 return QVariant( d1.date().weekNumber() );
2402 QVariant value = values.at( 0 );
2403 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2406 return QVariant( inter.
hours() );
2410 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2411 return QVariant( t1.hour() );
2417 QVariant value = values.at( 0 );
2418 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2421 return QVariant( inter.
minutes() );
2425 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2426 return QVariant( t1.minute() );
2432 QVariant value = values.at( 0 );
2433 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2436 return QVariant( inter.
seconds() );
2440 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2441 return QVariant( t1.second() );
2447 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2450 return QVariant( dt.toMSecsSinceEpoch() );
2460 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2462 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2467 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2470 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2473 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2479 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2482 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2489 #define ENSURE_GEOM_TYPE(f, g, geomtype) \
2490 if ( !(f).hasGeometry() ) \
2491 return QVariant(); \
2492 QgsGeometry g = (f).geometry(); \
2493 if ( (g).type() != (geomtype) ) \
2500 if ( g.isMultipart() )
2502 return g.asMultiPoint().at( 0 ).x();
2506 return g.asPoint().x();
2514 if ( g.isMultipart() )
2516 return g.asMultiPoint().at( 0 ).y();
2520 return g.asPoint().y();
2534 if ( g.isEmpty() || !abGeom->
is3D() )
2539 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2545 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2547 if ( collection->numGeometries() > 0 )
2549 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2560 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2566 return QVariant( isValid );
2571 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2583 QVariant result(
centroid.asPoint().
x() );
2589 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2601 QVariant result(
centroid.asPoint().
y() );
2607 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2617 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2625 if ( collection->numGeometries() == 1 )
2627 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2638 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2648 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2656 if ( collection->numGeometries() == 1 )
2658 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2669 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2674 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2701 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2718 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2735 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2740 bool ignoreClosing =
false;
2741 if ( values.length() > 1 )
2743 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
2753 bool skipLast =
false;
2754 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
2759 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
2771 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2782 for (
int i = 0; i < line->numPoints() - 1; ++i )
2786 << line->pointN( i )
2787 << line->pointN( i + 1 ) );
2798 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2808 if ( collection->numGeometries() == 1 )
2810 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
2815 if ( !curvePolygon )
2819 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2825 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
2831 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2841 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2847 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
2853 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2862 return QVariant::fromValue(
QgsGeometry( boundary ) );
2867 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2876 return QVariant::fromValue( merged );
2881 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2886 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2889 if ( simplified.
isNull() )
2897 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2902 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2907 if ( simplified.
isNull() )
2915 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2920 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
2921 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
2922 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2923 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
2925 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
2934 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2939 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2940 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2941 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
2952 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2957 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2958 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2959 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2960 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
2961 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
2964 minAmplitude, maxAmplitude, seed );
2973 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2978 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2979 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2980 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
2991 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2996 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2997 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2998 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2999 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3000 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3003 minAmplitude, maxAmplitude, seed );
3012 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3017 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3018 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3019 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3030 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3035 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3036 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3037 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3038 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3039 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3042 minAmplitude, maxAmplitude, seed );
3051 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3056 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3057 QVector< double > dashPattern;
3058 dashPattern.reserve( pattern.size() );
3059 for (
const QVariant &value : std::as_const( pattern ) )
3062 double v = value.toDouble( &ok );
3069 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3074 if ( dashPattern.size() % 2 != 0 )
3076 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3080 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3082 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3084 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3086 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3088 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3090 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3094 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3098 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3100 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3102 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3104 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3106 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3108 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3112 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3116 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3118 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3120 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3122 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3126 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3130 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3141 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3146 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3148 if ( densified.
isNull() )
3156 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3161 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3163 if ( densified.
isNull() )
3172 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3174 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3181 QVector< QgsGeometry > parts;
3182 parts.reserve( list.size() );
3183 for (
const QVariant &value : std::as_const( list ) )
3201 if ( values.count() < 2 || values.count() > 4 )
3203 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3207 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3208 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3209 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3210 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3211 switch ( values.count() )
3225 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3226 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3227 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3233 if ( values.empty() )
3238 QVector<QgsPoint> points;
3239 points.reserve( values.count() );
3241 auto addPoint = [&points](
const QgsGeometry & geom )
3249 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3256 for (
const QVariant &value : values )
3258 if ( value.type() == QVariant::List )
3260 const QVariantList list = value.toList();
3261 for (
const QVariant &v : list )
3263 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3268 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3272 if ( points.count() < 2 )
3280 if ( values.count() < 1 )
3282 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3286 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3294 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3296 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3303 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3308 if ( !exteriorRing )
3311 polygon->setExteriorRing( exteriorRing->
segmentize() );
3314 for (
int i = 1; i < values.count(); ++i )
3316 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3323 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3330 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3338 polygon->addInteriorRing( ring->
segmentize() );
3341 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3346 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3347 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3348 lineString->clear();
3350 for (
const QVariant &value : values )
3352 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3359 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3366 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3374 lineString->addVertex( *point );
3377 tr->setExteriorRing( lineString.release() );
3379 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3384 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3391 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3392 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3399 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3406 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3414 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3419 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3426 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3427 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3428 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3429 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3435 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3442 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3449 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3450 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3456 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3463 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3470 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3473 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3480 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3484 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3491 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3498 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3505 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3520 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3526 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3532 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3533 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3541 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3547 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3553 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3562 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3565 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3566 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3567 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
3575 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
3591 return QVariant( QPointF( p.
x(), p.
y() ) );
3596 QVariant v = pointAt( values, f, parent );
3597 if ( v.type() == QVariant::PointF )
3598 return QVariant( v.toPointF().x() );
3604 QVariant v = pointAt( values, f, parent );
3605 if ( v.type() == QVariant::PointF )
3606 return QVariant( v.toPointF().y() );
3623 return QVariant::fromValue( geom );
3631 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3633 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3639 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
3645 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3650 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3657 ogcContext.
layer = mapLayerPtr.data();
3658 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
3662 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3675 return QVariant( area );
3685 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3690 return QVariant( geom.
area() );
3702 return QVariant( len );
3719 return QVariant( len );
3723 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
3729 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3735 return QVariant( geom.
length() );
3740 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3746 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3755 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3764 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3779 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
3780 if ( !curvePolygon )
3792 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3799 return QVariant( curvePolygon->
ringCount() );
3801 bool foundPoly =
false;
3809 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
3810 if ( !curvePolygon )
3821 return QVariant( ringCount );
3826 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3828 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
3834 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3840 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3846 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3855 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3861 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3867 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3873 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3879 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3887 double max = std::numeric_limits< double >::lowest();
3891 double z = ( *it ).z();
3897 if ( max == std::numeric_limits< double >::lowest() )
3898 return QVariant( QVariant::Double );
3900 return QVariant( max );
3905 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3913 double min = std::numeric_limits< double >::max();
3917 double z = ( *it ).z();
3923 if ( min == std::numeric_limits< double >::max() )
3924 return QVariant( QVariant::Double );
3926 return QVariant( min );
3931 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3939 double min = std::numeric_limits< double >::max();
3943 double m = ( *it ).m();
3949 if ( min == std::numeric_limits< double >::max() )
3950 return QVariant( QVariant::Double );
3952 return QVariant( min );
3957 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3965 double max = std::numeric_limits< double >::lowest();
3969 double m = ( *it ).m();
3975 if ( max == std::numeric_limits< double >::lowest() )
3976 return QVariant( QVariant::Double );
3978 return QVariant( max );
3983 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3984 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
3987 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
3996 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4000 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4009 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4014 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4025 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4029 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4031 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4036 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4040 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4047 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4055 return QVariant::fromValue( curve->
isClosed() );
4060 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4073 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4074 closedLine->close();
4076 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4086 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4088 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4089 closedLine->close();
4091 closed->addGeometry( closedLine.release() );
4094 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4102 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4106 return QVariant::fromValue( fGeom.
isEmpty() );
4111 if ( values.at( 0 ).isNull() )
4112 return QVariant::fromValue(
true );
4114 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4115 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4120 if ( values.length() < 2 || values.length() > 3 )
4123 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4124 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4131 if ( values.length() == 2 )
4134 QString result = engine->relate( sGeom.
constGet() );
4135 return QVariant::fromValue( result );
4140 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4141 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4142 return QVariant::fromValue( result );
4148 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4149 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4154 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4155 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4156 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4160 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4161 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4162 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4166 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4167 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4168 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4172 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4173 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4174 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4178 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4179 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4180 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4184 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4185 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4186 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4190 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4191 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4192 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4197 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4198 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4199 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4200 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4201 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4202 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4205 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4206 capStyle = Qgis::EndCapStyle::Flat;
4207 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4208 capStyle = Qgis::EndCapStyle::Square;
4211 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4212 joinStyle = Qgis::JoinStyle::Miter;
4213 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4214 joinStyle = Qgis::JoinStyle::Bevel;
4217 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4223 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4225 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4230 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4232 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4237 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4239 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4244 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4245 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4252 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4259 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4263 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4264 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4265 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4266 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4269 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4275 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4278 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4282 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4283 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4284 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4287 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4293 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4296 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4300 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4303 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4309 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4310 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4311 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4312 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4313 if ( joinInt < 1 || joinInt > 3 )
4317 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4320 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4326 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4327 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4328 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4330 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4331 if ( joinInt < 1 || joinInt > 3 )
4335 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4338 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4344 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4345 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4346 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4349 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4355 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4356 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4357 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4359 return QVariant::fromValue( fGeom );
4364 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4365 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4366 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4368 const bool perPart = values.value( 3 ).toBool();
4375 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4378 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4379 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4380 t.rotate( -rotation );
4381 t.translate( -partCenter.
x(), -partCenter.
y() );
4382 ( *it )->transform( t );
4384 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4396 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4404 fGeom.
rotate( rotation, pt );
4405 return QVariant::fromValue( fGeom );
4411 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4412 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4413 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4414 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
4425 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
4433 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
4434 t.scale( xScale, yScale );
4435 t.translate( -pt.
x(), -pt.
y() );
4437 return QVariant::fromValue( fGeom );
4442 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4448 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4449 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4451 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4453 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4454 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4456 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
4457 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
4458 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
4459 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
4470 QTransform transform;
4471 transform.translate( deltaX, deltaY );
4472 transform.rotate( rotationZ );
4473 transform.scale( scaleX, scaleY );
4474 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
4476 return QVariant::fromValue( fGeom );
4482 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4484 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4489 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4491 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4497 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4498 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4500 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4506 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4508 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4515 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4517 if ( values.length() == 2 )
4518 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4526 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4532 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4534 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4540 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4546 double area,
angle, width, height;
4559 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4560 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4562 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4568 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4575 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
4580 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
4588 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
4590 reversed->addGeometry( curve->
reversed() );
4597 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
4604 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4615 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
4624 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
4630 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4631 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4632 return QVariant( fGeom.
distance( sGeom ) );
4637 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4638 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4641 if ( values.length() == 3 && values.at( 2 ).isValid() )
4643 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4644 densify = std::clamp( densify, 0.0, 1.0 );
4652 return res > -1 ? QVariant( res ) : QVariant();
4657 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4658 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4660 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4665 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4666 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4668 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4673 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4674 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4676 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4682 if ( values.length() < 1 || values.length() > 2 )
4685 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4687 if ( values.length() == 2 )
4688 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4689 QString wkt = fGeom.
asWkt( prec );
4690 return QVariant( wkt );
4695 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4696 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
4701 if ( values.length() != 2 )
4703 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
4707 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4708 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4710 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4717 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4722 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4729 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4736 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
4743 if ( pt1->
y() < pt2->
y() )
4745 else if ( pt1->
y() > pt2->
y() )
4753 if ( pt1->
x() < pt2->
x() )
4755 else if ( pt1->
x() > pt2->
x() )
4756 return M_PI + ( M_PI_2 );
4761 if ( pt1->
x() < pt2->
x() )
4763 if ( pt1->
y() < pt2->
y() )
4765 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
4769 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4776 if ( pt1->
y() > pt2->
y() )
4778 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
4783 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4784 + ( M_PI + ( M_PI_2 ) );
4791 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4795 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
4799 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4800 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4801 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4804 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
4811 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4812 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4814 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4821 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4825 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4832 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4840 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
4850 if ( values.length() != 3 )
4853 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4854 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4855 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4859 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
4865 if ( values.length() < 2 )
4868 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4871 return values.at( 0 );
4873 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4874 QVariant cachedExpression;
4879 if ( cachedExpression.isValid() )
4886 bool asc = values.value( 2 ).toBool();
4904 Q_ASSERT( collection );
4908 QgsExpressionSorter sorter( orderBy );
4910 QList<QgsFeature> partFeatures;
4911 partFeatures.reserve( collection->
partCount() );
4912 for (
int i = 0; i < collection->
partCount(); ++i )
4918 sorter.sortFeatures( partFeatures, unconstedContext );
4922 Q_ASSERT( orderedGeom );
4927 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
4932 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
4935 delete unconstedContext;
4942 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4943 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4947 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4953 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4954 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4958 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4964 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4965 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4969 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4975 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4978 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
4984 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
4991 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4998 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4999 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5001 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
5003 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
5008 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5009 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5016 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5017 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5022 vertex = count + vertex;
5030 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5031 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5036 vertex = count + vertex;
5044 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5045 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5049 return distance >= 0 ? distance : QVariant();
5054 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
5056 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5057 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5060 if ( values.length() >= 1 )
5062 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5063 return QVariant( qlonglong( std::round( number ) ) );
5078 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5079 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5080 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5087 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5088 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5089 return locale.toString( value,
'f', places );
5094 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
5095 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5096 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5098 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5099 return locale.toString( datetime, format );
5105 int avg = ( color.red() + color.green() + color.blue() ) / 3;
5106 int alpha = color.alpha();
5108 color.setRgb( avg, avg, avg, alpha );
5117 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5122 else if ( ratio < 0 )
5127 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
5128 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
5129 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
5130 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
5132 QColor newColor( red, green, blue, alpha );
5139 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5140 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5141 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5142 QColor color = QColor( red, green, blue );
5143 if ( ! color.isValid() )
5145 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
5146 color = QColor( 0, 0, 0 );
5149 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5154 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5155 QVariant value = node->
eval( parent, context );
5159 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5161 value = node->
eval( parent, context );
5169 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5171 QVariant value = node->
eval( parent, context );
5173 if ( value.toBool() )
5175 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5177 value = node->
eval( parent, context );
5182 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
5184 value = node->
eval( parent, context );
5192 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5193 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5194 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5195 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
5196 QColor color = QColor( red, green, blue, alpha );
5197 if ( ! color.isValid() )
5199 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
5200 color = QColor( 0, 0, 0 );
5211 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
5216 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5220 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
5225 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5226 QColor color = ramp->
color( value );
5233 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5235 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5237 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5239 QColor color = QColor::fromHslF( hue, saturation, lightness );
5241 if ( ! color.isValid() )
5243 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
5244 color = QColor( 0, 0, 0 );
5247 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5253 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5255 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5257 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5259 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5261 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
5262 if ( ! color.isValid() )
5264 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
5265 color = QColor( 0, 0, 0 );
5273 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5275 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5277 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5279 QColor color = QColor::fromHsvF( hue, saturation, value );
5281 if ( ! color.isValid() )
5283 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
5284 color = QColor( 0, 0, 0 );
5287 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5293 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5295 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5297 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5299 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5301 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
5302 if ( ! color.isValid() )
5304 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
5305 color = QColor( 0, 0, 0 );
5313 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5315 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5317 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5319 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5321 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
5323 if ( ! color.isValid() )
5325 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
5326 color = QColor( 0, 0, 0 );
5329 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5335 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5337 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5339 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5341 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5343 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
5345 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
5346 if ( ! color.isValid() )
5348 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
5349 color = QColor( 0, 0, 0 );
5357 if ( ! color.isValid() )
5359 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5363 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5364 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5366 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5367 return color.green();
5368 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5369 return color.blue();
5370 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5371 return color.alpha();
5372 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5373 return color.hsvHueF() * 360;
5374 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5375 return color.hsvSaturationF() * 100;
5376 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5377 return color.valueF() * 100;
5378 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5379 return color.hslHueF() * 360;
5380 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5381 return color.hslSaturationF() * 100;
5382 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5383 return color.lightnessF() * 100;
5384 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5385 return color.cyanF() * 100;
5386 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5387 return color.magentaF() * 100;
5388 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5389 return color.yellowF() * 100;
5390 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5391 return color.blackF() * 100;
5393 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5399 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5400 if ( map.count() < 1 )
5402 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
5406 QList< QColor > colors;
5408 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5411 if ( !colors.last().isValid() )
5413 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
5417 double step = it.key().toDouble();
5418 if ( it == map.constBegin() )
5423 else if ( it == map.constEnd() )
5433 bool discrete = values.at( 1 ).toBool();
5435 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
5441 if ( ! color.isValid() )
5443 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5447 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5448 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5449 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5450 color.setRed( value );
5451 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5452 color.setGreen( value );
5453 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5454 color.setBlue( value );
5455 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5456 color.setAlpha( value );
5457 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5458 color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
5459 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5460 color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
5461 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5462 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
5463 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5464 color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
5465 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5466 color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
5467 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5468 color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
5469 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5470 color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
5471 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5472 color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
5473 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5474 color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
5475 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5476 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
5479 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5488 if ( ! color.isValid() )
5490 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5494 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5502 if ( ! color.isValid() )
5504 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5508 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5515 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
5518 return QVariant::fromValue( geom );
5524 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5525 QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5526 QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5530 return QVariant::fromValue( fGeom );
5533 return QVariant::fromValue( fGeom );
5542 return QVariant::fromValue( fGeom );
5556 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
5559 QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
5571 result = QVariant::fromValue( fet );
5581 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), parent );
5584 if ( !featureSource )
5589 QString cacheValueKey;
5590 if ( values.at( 1 ).type() == QVariant::Map )
5592 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
5594 QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
5595 QString filterString;
5596 for ( ; i != attributeMap.constEnd(); ++i )
5598 if ( !filterString.isEmpty() )
5600 filterString.append(
" AND " );
5604 cacheValueKey = QStringLiteral(
"getfeature:%1:%2" ).arg( featureSource->id(), filterString );
5613 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5614 int attributeId = featureSource->fields().lookupField( attribute );
5615 if ( attributeId == -1 )
5620 const QVariant &attVal = values.at( 2 );
5622 cacheValueKey = QStringLiteral(
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
5645 res = QVariant::fromValue( fet );
5660 if ( !values.isEmpty() )
5663 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
5664 fieldName = col->
name();
5665 else if ( values.size() == 2 )
5666 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5669 QVariant value = values.at( 0 );
5674 if ( fieldIndex == -1 )
5676 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5680 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
5682 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName, value.toString() );
5691 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName );
5702 result =
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
5709 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5717 const QVariant data = values.at( 0 );
5718 const QMimeDatabase db;
5719 return db.mimeTypeForData( data.toByteArray() ).name();
5724 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5730 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5731 if ( QString::compare( layerProperty, QStringLiteral(
"name" ), Qt::CaseInsensitive ) == 0 )
5732 return layer->
name();
5733 else if ( QString::compare( layerProperty, QStringLiteral(
"id" ), Qt::CaseInsensitive ) == 0 )
5735 else if ( QString::compare( layerProperty, QStringLiteral(
"title" ), Qt::CaseInsensitive ) == 0 )
5737 else if ( QString::compare( layerProperty, QStringLiteral(
"abstract" ), Qt::CaseInsensitive ) == 0 )
5739 else if ( QString::compare( layerProperty, QStringLiteral(
"keywords" ), Qt::CaseInsensitive ) == 0 )
5741 QStringList keywords;
5743 for (
auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
5745 keywords.append( it.value() );
5747 if ( !keywords.isEmpty() )
5751 else if ( QString::compare( layerProperty, QStringLiteral(
"data_url" ), Qt::CaseInsensitive ) == 0 )
5753 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution" ), Qt::CaseInsensitive ) == 0 )
5757 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
5759 else if ( QString::compare( layerProperty, QStringLiteral(
"source" ), Qt::CaseInsensitive ) == 0 )
5761 else if ( QString::compare( layerProperty, QStringLiteral(
"min_scale" ), Qt::CaseInsensitive ) == 0 )
5763 else if ( QString::compare( layerProperty, QStringLiteral(
"max_scale" ), Qt::CaseInsensitive ) == 0 )
5765 else if ( QString::compare( layerProperty, QStringLiteral(
"is_editable" ), Qt::CaseInsensitive ) == 0 )
5767 else if ( QString::compare( layerProperty, QStringLiteral(
"crs" ), Qt::CaseInsensitive ) == 0 )
5769 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
5771 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_description" ), Qt::CaseInsensitive ) == 0 )
5773 else if ( QString::compare( layerProperty, QStringLiteral(
"extent" ), Qt::CaseInsensitive ) == 0 )
5776 QVariant result = QVariant::fromValue( extentGeom );
5779 else if ( QString::compare( layerProperty, QStringLiteral(
"distance_units" ), Qt::CaseInsensitive ) == 0 )
5781 else if ( QString::compare( layerProperty, QStringLiteral(
"path" ), Qt::CaseInsensitive ) == 0 )
5784 return decodedUri.value( QStringLiteral(
"path" ) );
5786 else if ( QString::compare( layerProperty, QStringLiteral(
"type" ), Qt::CaseInsensitive ) == 0 )
5788 switch ( layer->
type() )
5791 return QCoreApplication::translate(
"expressions",
"Vector" );
5793 return QCoreApplication::translate(
"expressions",
"Raster" );
5795 return QCoreApplication::translate(
"expressions",
"Mesh" );
5797 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
5799 return QCoreApplication::translate(
"expressions",
"Plugin" );
5801 return QCoreApplication::translate(
"expressions",
"Annotation" );
5803 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
5805 return QCoreApplication::translate(
"expressions",
"Group" );
5811 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
5814 if ( QString::compare( layerProperty, QStringLiteral(
"storage_type" ), Qt::CaseInsensitive ) == 0 )
5816 else if ( QString::compare( layerProperty, QStringLiteral(
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
5818 else if ( QString::compare( layerProperty, QStringLiteral(
"feature_count" ), Qt::CaseInsensitive ) == 0 )
5828 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5831 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
5841 const QString uriPart = values.at( 1 ).toString();
5845 if ( !uriPart.isNull() )
5847 return decodedUri.value( values.at( 1 ).toString() );
5857 QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5864 if ( !layersByName.isEmpty() )
5866 layer = layersByName.at( 0 );
5877 int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5878 if ( band < 1 || band > rl->
bandCount() )
5880 parent->
setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer %2" ).arg( band ).arg( layerIdOrName ) );
5884 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5887 if ( QString::compare( layerProperty, QStringLiteral(
"avg" ), Qt::CaseInsensitive ) == 0 )
5889 else if ( QString::compare( layerProperty, QStringLiteral(
"stdev" ), Qt::CaseInsensitive ) == 0 )
5891 else if ( QString::compare( layerProperty, QStringLiteral(
"min" ), Qt::CaseInsensitive ) == 0 )
5893 else if ( QString::compare( layerProperty, QStringLiteral(
"max" ), Qt::CaseInsensitive ) == 0 )
5895 else if ( QString::compare( layerProperty, QStringLiteral(
"range" ), Qt::CaseInsensitive ) == 0 )
5897 else if ( QString::compare( layerProperty, QStringLiteral(
"sum" ), Qt::CaseInsensitive ) == 0 )
5901 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
5931 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5932 bool ascending = values.value( 1 ).toBool();
5933 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
5939 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
5944 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
5949 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
5954 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5955 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5957 for (
const auto &item : listB )
5959 if ( listA.contains( item ) )
5963 return QVariant( match == listB.count() );
5968 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
5973 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5974 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5975 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
5976 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
5977 return list.at( list.length() + pos );
5983 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5984 return list.value( 0 );
5989 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5990 return list.value( list.size() - 1 );
5995 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5996 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool {
return (
qgsVariantLessThan( a, b ) ); } );
6001 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6002 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool {
return (
qgsVariantLessThan( a, b ) ); } );
6007 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6010 for (
const QVariant &item : list )
6012 switch ( item.userType() )
6014 case QMetaType::Int:
6015 case QMetaType::UInt:
6016 case QMetaType::LongLong:
6017 case QMetaType::ULongLong:
6018 case QMetaType::Float:
6019 case QMetaType::Double:
6020 total += item.toDouble();
6025 return i == 0 ? QVariant() : total / i;
6030 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6031 QVariantList numbers;
6032 for (
const auto &item : list )
6034 switch ( item.userType() )
6036 case QMetaType::Int:
6037 case QMetaType::UInt:
6038 case QMetaType::LongLong:
6039 case QMetaType::ULongLong:
6040 case QMetaType::Float:
6041 case QMetaType::Double:
6042 numbers.append( item );
6046 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
6047 const int count = numbers.count();
6052 else if ( count % 2 )
6054 return numbers.at( count / 2 );
6058 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
6064 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6067 for (
const QVariant &item : list )
6069 switch ( item.userType() )
6071 case QMetaType::Int:
6072 case QMetaType::UInt:
6073 case QMetaType::LongLong:
6074 case QMetaType::ULongLong:
6075 case QMetaType::Float:
6076 case QMetaType::Double:
6077 total += item.toDouble();
6082 return i == 0 ? QVariant() : total;
6085 static QVariant convertToSameType(
const QVariant &value, QVariant::Type type )
6087 QVariant result = value;
6088 result.convert(
static_cast<int>( type ) );
6094 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6095 QHash< QVariant, int > hash;
6096 for (
const auto &item : list )
6100 const QList< int > occurrences = hash.values();
6101 if ( occurrences.empty() )
6102 return QVariantList();
6104 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6106 const QString option = values.at( 1 ).toString();
6107 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6109 return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
6111 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6113 if ( hash.isEmpty() )
6116 return QVariant( hash.keys( maxValue ).first() );
6118 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6120 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
6122 else if ( option.compare( QLatin1String(
"real_majority" ), Qt::CaseInsensitive ) == 0 )
6124 if ( maxValue * 2 <= list.size() )
6127 return QVariant( hash.keys( maxValue ).first() );
6138 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6139 QHash< QVariant, int > hash;
6140 for (
const auto &item : list )
6144 const QList< int > occurrences = hash.values();
6145 if ( occurrences.empty() )
6146 return QVariantList();
6148 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
6150 const QString option = values.at( 1 ).toString();
6151 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6153 return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
6155 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6157 if ( hash.isEmpty() )
6160 return QVariant( hash.keys( minValue ).first() );
6162 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6164 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
6166 else if ( option.compare( QLatin1String(
"real_minority" ), Qt::CaseInsensitive ) == 0 )
6168 if ( hash.keys().isEmpty() )
6172 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6173 if ( maxValue * 2 > list.size() )
6174 hash.remove( hash.key( maxValue ) );
6176 return convertToSameType( hash.keys(), values.at( 0 ).type() );
6187 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6188 list.append( values.at( 1 ) );
6189 return convertToSameType( list, values.at( 0 ).type() );
6194 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6195 list.prepend( values.at( 1 ) );
6196 return convertToSameType( list, values.at( 0 ).type() );
6201 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6202 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
6203 return convertToSameType( list, values.at( 0 ).type() );
6208 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6209 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6211 position = position + list.length();
6212 if ( position >= 0 && position < list.length() )
6213 list.removeAt( position );
6214 return convertToSameType( list, values.at( 0 ).type() );
6219 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6220 list.removeAll( values.at( 1 ) );
6221 return convertToSameType( list, values.at( 0 ).type() );
6226 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
6228 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
6230 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6231 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6233 int index = list.indexOf( it.key() );
6234 while ( index >= 0 )
6236 list.replace( index, it.value() );
6237 index = list.indexOf( it.key() );
6241 return convertToSameType( list, values.at( 0 ).type() );
6243 else if ( values.count() == 3 )
6245 QVariantList before;
6247 bool isSingleReplacement =
false;
6249 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
6251 before = QVariantList() << values.at( 1 );
6255 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6258 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
6260 after = QVariantList() << values.at( 2 );
6261 isSingleReplacement =
true;
6265 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
6268 if ( !isSingleReplacement && before.length() != after.length() )
6270 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
6274 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6275 for (
int i = 0; i < before.length(); i++ )
6277 int index = list.indexOf( before.at( i ) );
6278 while ( index >= 0 )
6280 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
6281 index = list.indexOf( before.at( i ) );
6285 return convertToSameType( list, values.at( 0 ).type() );
6289 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
6296 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6297 QVariantList list_new;
6299 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
6301 while ( list.removeOne( cur ) )
6303 list_new.append( cur );
6307 list_new.append( list );
6309 return convertToSameType( list_new, values.at( 0 ).type() );
6315 for (
const QVariant &cur : values )
6317 list += QgsExpressionUtils::getListValue( cur, parent );
6319 return convertToSameType( list, values.at( 0 ).type() );
6324 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6325 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6326 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6327 int slice_length = 0;
6329 if ( start_pos < 0 )
6331 start_pos = list.length() + start_pos;
6335 slice_length = end_pos - start_pos + 1;
6339 slice_length = list.length() + end_pos - start_pos + 1;
6342 if ( slice_length < 0 )
6346 list = list.mid( start_pos, slice_length );
6352 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6353 std::reverse( list.begin(), list.end() );
6359 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6360 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6361 for (
const QVariant &cur : array2 )
6363 if ( array1.contains( cur ) )
6364 return QVariant(
true );
6366 return QVariant(
false );
6371 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6373 QVariantList distinct;
6375 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6377 if ( !distinct.contains( *it ) )
6379 distinct += ( *it );
6388 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6389 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6390 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6394 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6396 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
6397 if ( it != ( array.constEnd() - 1 ) )
6403 return QVariant(
str );
6408 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6409 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6410 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6412 QStringList list =
str.split( delimiter );
6415 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
6417 array += ( !( *it ).isEmpty() ) ? *it : empty;
6425 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6426 QJsonDocument document = QJsonDocument::fromJson(
str.toUtf8() );
6427 if ( document.isNull() )
6430 return document.toVariant();
6436 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
6437 return document.toJson( QJsonDocument::Compact );
6442 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6443 if (
str.isEmpty() )
6444 return QVariantMap();
6452 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6459 for (
int i = 0; i + 1 < values.length(); i += 2 )
6461 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
6468 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6469 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6470 QVariantMap resultMap;
6472 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6474 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
6482 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
6487 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
6492 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6493 map.remove( values.at( 1 ).toString() );
6499 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6500 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
6507 for (
const QVariant &cur : values )
6509 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
6510 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
6511 result.insert( it.key(), it.value() );
6518 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
6523 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
6528 QString envVarName = values.at( 0 ).toString();
6529 return QProcessEnvironment::systemEnvironment().value( envVarName );
6534 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6537 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"base_file_name" ) ) );
6540 return QFileInfo( file ).completeBaseName();
6545 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6548 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_suffix" ) ) );
6551 return QFileInfo( file ).completeSuffix();
6556 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6559 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_exists" ) ) );
6562 return QFileInfo::exists( file );
6567 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6570 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_name" ) ) );
6573 return QFileInfo( file ).fileName();
6578 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6581 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"is_file" ) ) );
6584 return QFileInfo( file ).isFile();
6589 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6592 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"is_directory" ) ) );
6595 return QFileInfo( file ).isDir();
6600 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6603 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_path" ) ) );
6606 return QDir::toNativeSeparators( QFileInfo( file ).path() );
6611 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6614 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_size" ) ) );
6617 return QFileInfo( file ).size();
6620 static QVariant fcnHash(
const QString &
str,
const QCryptographicHash::Algorithm
algorithm )
6622 return QString( QCryptographicHash::hash(
str.toUtf8(),
algorithm ).toHex() );
6628 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6629 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
6631 if ( method == QLatin1String(
"md4" ) )
6633 hash = fcnHash(
str, QCryptographicHash::Md4 );
6635 else if ( method == QLatin1String(
"md5" ) )
6637 hash = fcnHash(
str, QCryptographicHash::Md5 );
6639 else if ( method == QLatin1String(
"sha1" ) )
6641 hash = fcnHash(
str, QCryptographicHash::Sha1 );
6643 else if ( method == QLatin1String(
"sha224" ) )
6645 hash = fcnHash(
str, QCryptographicHash::Sha224 );
6647 else if ( method == QLatin1String(
"sha256" ) )
6649 hash = fcnHash(
str, QCryptographicHash::Sha256 );
6651 else if ( method == QLatin1String(
"sha384" ) )
6653 hash = fcnHash(
str, QCryptographicHash::Sha384 );
6655 else if ( method == QLatin1String(
"sha512" ) )
6657 hash = fcnHash(
str, QCryptographicHash::Sha512 );
6659 else if ( method == QLatin1String(
"sha3_224" ) )
6661 hash = fcnHash(
str, QCryptographicHash::Sha3_224 );
6663 else if ( method == QLatin1String(
"sha3_256" ) )
6665 hash = fcnHash(
str, QCryptographicHash::Sha3_256 );
6667 else if ( method == QLatin1String(
"sha3_384" ) )
6669 hash = fcnHash(
str, QCryptographicHash::Sha3_384 );
6671 else if ( method == QLatin1String(
"sha3_512" ) )
6673 hash = fcnHash(
str, QCryptographicHash::Sha3_512 );
6675 else if ( method == QLatin1String(
"keccak_224" ) )
6677 hash = fcnHash(
str, QCryptographicHash::Keccak_224 );
6679 else if ( method == QLatin1String(
"keccak_256" ) )
6681 hash = fcnHash(
str, QCryptographicHash::Keccak_256 );
6683 else if ( method == QLatin1String(
"keccak_384" ) )
6685 hash = fcnHash(
str, QCryptographicHash::Keccak_384 );
6687 else if ( method == QLatin1String(
"keccak_512" ) )
6689 hash = fcnHash(
str, QCryptographicHash::Keccak_512 );
6693 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg(
str ) );
6700 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
6705 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
6710 const QByteArray input = values.at( 0 ).toByteArray();
6711 return QVariant( QString( input.toBase64() ) );
6716 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6718 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6720 query.addQueryItem( it.key(), it.value().toString() );
6722 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
6727 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6728 const QByteArray base64 = value.toLocal8Bit();
6729 const QByteArray decoded = QByteArray::fromBase64( base64 );
6730 return QVariant( decoded );
6735 static QVariant executeGeomOverlay(
const QVariantList &values,
const QgsExpressionContext *context,
QgsExpression *parent,
const RelationFunction &relationFunction,
bool invert =
false,
double bboxGrow = 0,
bool isNearestFunc =
false,
bool isIntersectsFunc =
false )
6738 const QVariant sourceLayerRef = context->
variable( QStringLiteral(
"layer" ) );
6739 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, parent );
6747 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6750 const bool layerCanBeCached = node->
isStatic( parent, context );
6751 QVariant targetLayerValue = node->
eval( parent, context );
6755 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6757 QString subExpString = node->dump();
6759 bool testOnly = ( subExpString ==
"NULL" );
6760 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, parent );
6763 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
6768 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6770 QString filterString = node->dump();
6771 if ( filterString !=
"NULL" )
6777 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
6779 QVariant limitValue = node->eval( parent, context );
6781 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
6784 double max_distance = 0;
6785 if ( isNearestFunc )
6787 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
6789 QVariant distanceValue = node->eval( parent, context );
6791 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
6795 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
6797 QVariant cacheValue = node->eval( parent, context );
6799 bool cacheEnabled = cacheValue.toBool();
6805 double minOverlap { -1 };
6806 double minInscribedCircleRadius { -1 };
6807 bool returnDetails =
false;
6808 bool sortByMeasure =
false;
6809 bool sortAscending =
false;
6810 bool requireMeasures =
false;
6811 bool overlapOrRadiusFilter =
false;
6812 if ( isIntersectsFunc )
6815 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
6817 const QVariant minOverlapValue = node->eval( parent, context );
6819 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
6820 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
6822 const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
6824 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
6825 #if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<9
6826 if ( minInscribedCircleRadiusValue != -1 )
6828 parent->
setEvalErrorString( QObject::tr(
"'min_inscribed_circle_radius' is only available when QGIS is built with GEOS >= 3.9." ) );
6832 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
6834 returnDetails = !testOnly && node->eval( parent, context ).toBool();
6835 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
6837 const QString sorting { node->eval( parent, context ).toString().toLower() };
6838 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
6839 sortAscending = sorting.startsWith(
"asc" );
6840 requireMeasures = sortByMeasure || returnDetails;
6841 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
6848 if ( sourceLayer && targetLayer->
crs() != sourceLayer->
crs() )
6854 bool sameLayers = ( sourceLayer && sourceLayer->
id() == targetLayer->
id() );
6857 if ( bboxGrow != 0 )
6859 intDomain.
grow( bboxGrow );
6862 const QString cacheBase { QStringLiteral(
"%1:%2:%3" ).arg( targetLayer->
id(), subExpString, filterString ) };
6868 QList<QgsFeature> features;
6869 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
6873 const QString cacheLayer { QStringLiteral(
"ovrlaylyr:%1" ).arg( cacheBase ) };
6874 const QString cacheIndex { QStringLiteral(
"ovrlayidx:%1" ).arg( cacheBase ) };
6878 cachedTarget = targetLayer->
materialize( request );
6879 if ( layerCanBeCached )
6880 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
6890 if ( layerCanBeCached )
6891 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
6898 QList<QgsFeatureId> fidsList;
6899 if ( isNearestFunc )
6901 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
6905 fidsList = spatialIndex.
intersects( intDomain );
6908 QListIterator<QgsFeatureId> i( fidsList );
6909 while ( i.hasNext() )
6912 if ( sameLayers && feat.
id() == fId2 )
6914 features.append( cachedTarget->
getFeature( fId2 ) );
6927 if ( sameLayers && feat.
id() == feat2.
id() )
6929 features.append( feat2 );
6937 const QString expCacheKey { QStringLiteral(
"exp:%1" ).arg( cacheBase ) };
6938 const QString ctxCacheKey { QStringLiteral(
"ctx:%1" ).arg( cacheBase ) };
6944 subExpression.
prepare( &subContext );
6957 auto testLinestring = [ = ](
const QgsGeometry intersection,
double & overlapValue ) ->
bool
6959 bool testResult {
false };
6961 QVector<double> overlapValues;
6964 const QgsCurve *geom = qgsgeometry_cast< const QgsCurve * >( *it );
6966 if ( minOverlap != -1 || requireMeasures )
6968 overlapValue = geom->
length();
6969 overlapValues.append( overlapValue );
6970 if ( minOverlap != -1 )
6972 if ( overlapValue >= minOverlap )
6984 if ( ! overlapValues.isEmpty() )
6986 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
6993 auto testPolygon = [ = ](
const QgsGeometry intersection,
double & radiusValue,
double & overlapValue ) ->
bool
6996 bool testResult {
false };
6998 QVector<double> overlapValues;
6999 QVector<double> radiusValues;
7002 const QgsCurvePolygon *geom = qgsgeometry_cast< const QgsCurvePolygon * >( *it );
7004 if ( minOverlap != -1 || requireMeasures )
7006 overlapValue = geom->
area();
7007 overlapValues.append( geom->
area() );
7008 if ( minOverlap != - 1 )
7010 if ( overlapValue >= minOverlap )
7021 #if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
7023 if ( minInscribedCircleRadius != -1 || requireMeasures )
7026 const double width = bbox.
width();
7027 const double height = bbox.
height();
7028 const double size = width > height ? width : height;
7029 const double tolerance = size / 100.0;
7031 testResult = radiusValue >= minInscribedCircleRadius;
7032 radiusValues.append( radiusValues );
7038 if ( !radiusValues.isEmpty() )
7040 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
7043 if ( ! overlapValues.isEmpty() )
7045 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
7055 QVariantList results;
7057 QListIterator<QgsFeature> i( features );
7058 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
7064 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
7067 double overlapValue = -1;
7068 double radiusValue = -1;
7070 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
7077 switch ( intersection.
type() )
7080 case QgsWkbTypes::GeometryType::PolygonGeometry:
7084 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
7086 if ( ! testResult && overlapOrRadiusFilter )
7094 case QgsWkbTypes::GeometryType::LineGeometry:
7099 if ( minInscribedCircleRadius != -1 )
7105 const bool testResult { testLinestring( intersection, overlapValue ) };
7107 if ( ! testResult && overlapOrRadiusFilter )
7115 case QgsWkbTypes::GeometryType::PointGeometry:
7120 if ( minInscribedCircleRadius != -1 )
7125 bool testResult {
false };
7126 if ( minOverlap != -1 || requireMeasures )
7134 if ( geometry.
type() == QgsWkbTypes::GeometryType::PointGeometry )
7138 case QgsWkbTypes::GeometryType::UnknownGeometry:
7139 case QgsWkbTypes::GeometryType::NullGeometry:
7140 case QgsWkbTypes::GeometryType::PointGeometry:
7144 case QgsWkbTypes::GeometryType::LineGeometry:
7146 testResult = testLinestring( feat2.
geometry(), overlapValue );
7149 case QgsWkbTypes::GeometryType::PolygonGeometry:
7151 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
7157 if ( ! testResult && overlapOrRadiusFilter )
7166 case QgsWkbTypes::GeometryType::NullGeometry:
7167 case QgsWkbTypes::GeometryType::UnknownGeometry:
7185 const QVariant expResult = subExpression.
evaluate( &subContext );
7187 if ( requireMeasures )
7189 QVariantMap resultRecord;
7190 resultRecord.insert( QStringLiteral(
"id" ), feat2.
id() );
7191 resultRecord.insert( QStringLiteral(
"result" ), expResult );
7193 resultRecord.insert( QStringLiteral(
"overlap" ), overlapValue );
7195 if ( radiusValue != -1 )
7197 resultRecord.insert( QStringLiteral(
"radius" ), radiusValue );
7199 results.append( resultRecord );
7203 results.append( expResult );
7209 results.append( feat2.
id() );
7223 if ( requireMeasures )
7225 if ( sortByMeasure )
7227 std::sort( results.begin(), results.end(), [ sortAscending ](
const QVariant & recordA,
const QVariant & recordB ) ->
bool
7229 return sortAscending ?
7230 recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble()
7231 : recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble();
7235 if ( limit > 0 && results.size() > limit )
7237 results.erase( results.begin() + limit );
7240 if ( ! returnDetails )
7242 QVariantList expResults;
7243 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
7245 expResults.append( it->toMap().value( QStringLiteral(
"result" ) ) );
7255 QVariantList disjoint_results;
7264 if ( !results.contains( feat2.
id() ) )
7267 disjoint_results.append( subExpression.
evaluate( &subContext ) );
7270 return disjoint_results;
7313 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
7322 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
7323 static QMutex sFunctionsMutex( QMutex::Recursive );
7324 QMutexLocker locker( &sFunctionsMutex );
7326 static QRecursiveMutex sFunctionsMutex;
7327 QMutexLocker locker( &sFunctionsMutex );
7330 QList<QgsExpressionFunction *> &functions = *sFunctions();
7332 if ( functions.isEmpty() )
7369 functions << randFunc;
7373 functions << randfFunc;
7376 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max" ), -1, fcnMax, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7377 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min" ), -1, fcnMin, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7383 <<
new QgsStaticExpressionFunction( QStringLiteral(
"pi" ), 0, fcnPi, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$pi" ) )
7387 <<
new QgsStaticExpressionFunction( QStringLiteral(
"to_datetime" ),
QgsExpressionFunction::ParameterList() <<
QgsExpressionFunction::Parameter( QStringLiteral(
"value" ) ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"format" ),
true, QVariant() ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"language" ),
true, QVariant() ), fcnToDateTime, QStringList() << QStringLiteral(
"Conversions" ) << QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"todatetime" ) )
7388 <<
new QgsStaticExpressionFunction( QStringLiteral(
"to_date" ),
QgsExpressionFunction::ParameterList() <<
QgsExpressionFunction::Parameter( QStringLiteral(
"value" ) ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"format" ),
true, QVariant() ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"language" ),
true, QVariant() ), fcnToDate, QStringList() << QStringLiteral(
"Conversions" ) << QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"todate" ) )
7389 <<
new QgsStaticExpressionFunction( QStringLiteral(
"to_time" ),
QgsExpressionFunction::ParameterList() <<
QgsExpressionFunction::Parameter( QStringLiteral(
"value" ) ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"format" ),
true, QVariant() ) <<
QgsExpressionFunction::Parameter( QStringLiteral(
"language" ),
true, QVariant() ), fcnToTime, QStringList() << QStringLiteral(
"Conversions" ) << QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"totime" ) )
7394 <<
new QgsStaticExpressionFunction( QStringLiteral(
"coalesce" ), -1, fcnCoalesce, QStringLiteral(
"Conditionals" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7408 QStringLiteral(
"Aggregates" ),
7417 if ( !node->
args() )
7420 QSet<QString> referencedVars;
7423 QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
7424 referencedVars = subExpressionNode->referencedVariables();
7429 QgsExpressionNode *filterNode = node->args()->at( 3 );
7430 referencedVars.unite( filterNode->referencedVariables() );
7432 return referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() );
7441 if ( !node->
args() )
7442 return QSet<QString>();
7444 QSet<QString> referencedCols;
7445 QSet<QString> referencedVars;
7460 if ( referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() ) )
7463 return referencedCols;
7476 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count" ), aggParams, fcnAggregateCount, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7477 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7478 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7479 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7480 <<
new QgsStaticExpressionFunction( QStringLiteral(
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7481 <<
new QgsStaticExpressionFunction( QStringLiteral(
"sum" ), aggParams, fcnAggregateSum, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7482 <<
new QgsStaticExpressionFunction( QStringLiteral(
"mean" ), aggParams, fcnAggregateMean, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7483 <<
new QgsStaticExpressionFunction( QStringLiteral(
"median" ), aggParams, fcnAggregateMedian, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7484 <<
new QgsStaticExpressionFunction( QStringLiteral(
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7485 <<
new QgsStaticExpressionFunction( QStringLiteral(
"range" ), aggParams, fcnAggregateRange, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7486 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7487 <<
new QgsStaticExpressionFunction( QStringLiteral(
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7488 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7489 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7490 <<
new QgsStaticExpressionFunction( QStringLiteral(
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7491 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7492 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7493 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7494 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7495 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7496 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7501 <<
new QgsStaticExpressionFunction( QStringLiteral(
"now" ), 0, fcnNow, QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$now" ) )
7504 fcnAge, QStringLiteral(
"Date and Time" ) )
7518 fcnMakeDate, QStringLiteral(
"Date and Time" ) )
7522 fcnMakeTime, QStringLiteral(
"Date and Time" ) )
7529 fcnMakeDateTime, QStringLiteral(
"Date and Time" ) )
7537 fcnMakeInterval, QStringLiteral(
"Date and Time" ) )
7556 false, QSet< QString >(),
false, QStringList(), true )
7557 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concat" ), -1, fcnConcat, QStringLiteral(
"String" ), QString(),
false, QSet<QString>(),
false, QStringList(), true )
7570 fcnColorMixRgb, QStringLiteral(
"Color" ) )
7574 fcnColorRgb, QStringLiteral(
"Color" ) )
7579 fncColorRgba, QStringLiteral(
"Color" ) )
7585 fcnCreateRamp, QStringLiteral(
"Color" ) )
7589 fcnColorHsl, QStringLiteral(
"Color" ) )
7594 fncColorHsla, QStringLiteral(
"Color" ) )
7598 fcnColorHsv, QStringLiteral(
"Color" ) )
7603 fncColorHsva, QStringLiteral(
"Color" ) )
7608 fcnColorCmyk, QStringLiteral(
"Color" ) )
7614 fncColorCmyka, QStringLiteral(
"Color" ) )
7617 fncColorPart, QStringLiteral(
"Color" ) )
7620 fncDarker, QStringLiteral(
"Color" ) )
7623 fncLighter, QStringLiteral(
"Color" ) )
7628 fcnBaseFileName, QStringLiteral(
"Files and Paths" ) )
7630 fcnFileSuffix, QStringLiteral(
"Files and Paths" ) )
7632 fcnFileExists, QStringLiteral(
"Files and Paths" ) )
7634 fcnFileName, QStringLiteral(
"Files and Paths" ) )
7636 fcnPathIsFile, QStringLiteral(
"Files and Paths" ) )
7638 fcnPathIsDir, QStringLiteral(
"Files and Paths" ) )
7640 fcnFilePath, QStringLiteral(
"Files and Paths" ) )
7642 fcnFileSize, QStringLiteral(
"Files and Paths" ) )
7645 fcnExif, QStringLiteral(
"Files and Paths" ) )
7647 fcnExifGeoTag, QStringLiteral(
"GeometryGroup" ) )
7651 fcnGenericHash, QStringLiteral(
"Conversions" ) )
7653 fcnHashMd5, QStringLiteral(
"Conversions" ) )
7655 fcnHashSha256, QStringLiteral(
"Conversions" ) )
7659 fcnToBase64, QStringLiteral(
"Conversions" ) )
7661 fcnFromBase64, QStringLiteral(
"Conversions" ) )
7667 geomFunc->setIsStatic(
false );
7668 functions << geomFunc;
7672 functions << areaFunc;
7678 functions << lengthFunc;
7682 functions << perimeterFunc;
7688 fcnRoundness, QStringLiteral(
"GeometryGroup" ) );
7702 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
7704 { QStringLiteral(
"overlay_intersects" ), fcnGeomOverlayIntersects },
7705 { QStringLiteral(
"overlay_contains" ), fcnGeomOverlayContains },
7706 { QStringLiteral(
"overlay_crosses" ), fcnGeomOverlayCrosses },
7707 { QStringLiteral(
"overlay_equals" ), fcnGeomOverlayEquals },
7708 { QStringLiteral(
"overlay_touches" ), fcnGeomOverlayTouches },
7709 { QStringLiteral(
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
7710 { QStringLiteral(
"overlay_within" ), fcnGeomOverlayWithin },
7712 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
7713 while ( i.hasNext() )
7730 functions << fcnGeomOverlayFunc;
7743 functions << fcnGeomOverlayNearestFunc;
7756 fcnNodesToPoints, QStringLiteral(
"GeometryGroup" ) )
7758 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral(
"GeometryGroup" ) )
7763 fcnMakePointM, QStringLiteral(
"GeometryGroup" ) )
7769 fcnMakeTriangle, QStringLiteral(
"GeometryGroup" ) )
7774 fcnMakeCircle, QStringLiteral(
"GeometryGroup" ) )
7781 fcnMakeEllipse, QStringLiteral(
"GeometryGroup" ) )
7787 fcnMakeRegularPolygon, QStringLiteral(
"GeometryGroup" ) )
7791 fcnMakeSquare, QStringLiteral(
"GeometryGroup" ) )
7797 fcnMakeRectangleFrom3Points, QStringLiteral(
"GeometryGroup" ) );
7800 functions << xAtFunc;
7804 functions << yAtFunc;
7820 fcnDisjoint, QStringLiteral(
"GeometryGroup" ) )
7823 fcnIntersects, QStringLiteral(
"GeometryGroup" ) )
7826 fcnTouches, QStringLiteral(
"GeometryGroup" ) )
7829 fcnCrosses, QStringLiteral(
"GeometryGroup" ) )
7832 fcnContains, QStringLiteral(
"GeometryGroup" ) )
7835 fcnOverlaps, QStringLiteral(
"GeometryGroup" ) )
7838 fcnWithin, QStringLiteral(
"GeometryGroup" ) )
7842 fcnTranslate, QStringLiteral(
"GeometryGroup" ) )
7847 fcnRotate, QStringLiteral(
"GeometryGroup" ) )
7852 fcnScale, QStringLiteral(
"GeometryGroup" ) )
7863 fcnAffineTransform, QStringLiteral(
"GeometryGroup" ) )
7870 fcnBuffer, QStringLiteral(
"GeometryGroup" ) )
7872 fcnForceRHR, QStringLiteral(
"GeometryGroup" ) )
7874 fcnForcePolygonCW, QStringLiteral(
"GeometryGroup" ) )
7876 fcnForcePolygonCCW, QStringLiteral(
"GeometryGroup" ) )
7886 , fcnTaperedBuffer, QStringLiteral(
"GeometryGroup" ) )
7889 , fcnBufferByM, QStringLiteral(
"GeometryGroup" ) )
7895 fcnOffsetCurve, QStringLiteral(
"GeometryGroup" ) )
7901 fcnSingleSidedBuffer, QStringLiteral(
"GeometryGroup" ) )
7905 fcnExtend, QStringLiteral(
"GeometryGroup" ) )
7914 fcnInteriorRingN, QStringLiteral(
"GeometryGroup" ) )
7917 fcnGeometryN, QStringLiteral(
"GeometryGroup" ) )
7933 }, fcnTriangularWave, QStringLiteral(
"GeometryGroup" ) )
7942 }, fcnTriangularWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7949 }, fcnSquareWave, QStringLiteral(
"GeometryGroup" ) )
7958 }, fcnSquareWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7965 }, fcnRoundWave, QStringLiteral(
"GeometryGroup" ) )
7974 }, fcnRoundWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7983 }, fcnApplyDashPattern, QStringLiteral(
"GeometryGroup" ) )
7988 }, fcnDensifyByCount, QStringLiteral(
"GeometryGroup" ) )
7993 }, fcnDensifyByDistance, QStringLiteral(
"GeometryGroup" ) )
8007 fcnOrientedBBox, QStringLiteral(
"GeometryGroup" ) )
8010 fcnMainAngle, QStringLiteral(
"GeometryGroup" ) )
8014 fcnMinimalCircle, QStringLiteral(
"GeometryGroup" ) )
8017 fcnDifference, QStringLiteral(
"GeometryGroup" ) )
8020 fcnDistance, QStringLiteral(
"GeometryGroup" ) )
8023 fcnHausdorffDistance, QStringLiteral(
"GeometryGroup" ) )
8026 fcnIntersection, QStringLiteral(
"GeometryGroup" ) )
8029 fcnSymDifference, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"symDifference" ) )
8032 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
8035 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
8038 fcnGeomToWKT, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"geomToWKT" ) )
8040 fcnGeomToWKB, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(), false )
8045 fcnTransformGeometry, QStringLiteral(
"GeometryGroup" ) )
8049 fcnExtrude, QStringLiteral(
"GeometryGroup" ), QString() )
8051 fcnGeomIsMultipart, QStringLiteral(
"GeometryGroup" ) )
8053 fcnZMax, QStringLiteral(
"GeometryGroup" ) )
8055 fcnZMin, QStringLiteral(
"GeometryGroup" ) )
8057 fcnMMax, QStringLiteral(
"GeometryGroup" ) )
8059 fcnMMin, QStringLiteral(
"GeometryGroup" ) )
8061 fcnSinuosity, QStringLiteral(
"GeometryGroup" ) )
8063 fcnStraightDistance2d, QStringLiteral(
"GeometryGroup" ) );
8069 fcnOrderParts, QStringLiteral(
"GeometryGroup" ), QString() );
8071 orderPartsFunc->setIsStaticFunction(
8074 const QList< QgsExpressionNode *> argList = node->
args()->list();
8077 if ( !argNode->isStatic( parent, context ) )
8083 QgsExpressionNode *argNode = node->args()->at( 1 );
8085 QString expString = argNode->eval( parent, context ).toString();
8087 QgsExpression e( expString );
8089 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8100 QgsExpressionNode *argNode = node->args()->at( 1 );
8101 QString expression = argNode->eval( parent, context ).toString();
8102 QgsExpression e( expression );
8103 e.prepare( context );
8104 context->setCachedValue( expression, QVariant::fromValue( e ) );
8109 functions << orderPartsFunc;
8114 fcnClosestPoint, QStringLiteral(
"GeometryGroup" ) )
8117 fcnShortestLine, QStringLiteral(
"GeometryGroup" ) )
8136 functions << idFunc;
8140 functions << currentFeatureFunc;
8142 QgsStaticExpressionFunction *uuidFunc =
new QgsStaticExpressionFunction( QStringLiteral(
"uuid" ),
QgsExpressionFunction::ParameterList() <<
QgsExpressionFunction::Parameter( QStringLiteral(
"format" ),
true, QStringLiteral(
"WithBraces" ) ), fcnUuid, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$uuid" ) );
8144 functions << uuidFunc;
8150 fcnGetFeature, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"QgsExpressionUtils::getFeature" ) )
8153 fcnGetFeatureById, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false );
8158 functions << attributesFunc;
8162 functions << representAttributesFunc;
8165 QStringLiteral(
"maptip" ),
8168 QStringLiteral(
"Record and Attributes" ),
8174 functions << maptipFunc;
8177 QStringLiteral(
"display_expression" ),
8179 fcnFeatureDisplayExpression,
8180 QStringLiteral(
"Record and Attributes" ),
8186 functions << displayFunc;
8189 QStringLiteral(
"is_selected" ),
8192 QStringLiteral(
"Record and Attributes" ),
8198 functions << isSelectedFunc;
8202 QStringLiteral(
"num_selected" ),
8205 QStringLiteral(
"Record and Attributes" ),
8213 QStringLiteral(
"sqlite_fetch_and_increment" ),
8221 fcnSqliteFetchAndIncrement,
8222 QStringLiteral(
"Record and Attributes" )
8240 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
8250 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
8256 functions << representValueFunc;
8262 fcnGetLayerProperty, QStringLiteral(
"Map Layers" ) )
8267 fcnDecodeUri, QStringLiteral(
"Map Layers" ) )
8271 fcnMimeType, QStringLiteral(
"General" ) )
8288 QgsExpressionNode *argNode = node->args()->at( 0 );
8290 if ( !argNode->isStatic( parent, context ) )
8293 QString varName = argNode->eval( parent, context ).toString();
8295 const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
8296 return scope ? scope->isStatic( varName ) : false;
8313 QgsExpressionNode *argNode = node->args()->at( 0 );
8315 if ( argNode->isStatic( parent, context ) )
8317 QString expString = argNode->eval( parent, context ).toString();
8319 QgsExpression e( expString );
8321 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8329 functions << evalFunc;
8335 const QList< QgsExpressionNode *> argList = node->
args()->list();
8338 if ( !argNode->isStatic( parent, context ) )
8350 functions << attributeFunc;
8360 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array" ), -1, fcnArray, QStringLiteral(
"Arrays" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8408 fcnMapPrefixKeys, QStringLiteral(
"Maps" ) )
8410 fcnToFormUrlEncode, QStringLiteral(
"Maps" ) )
8419 *sOwnedFunctions() << func;
8420 *sBuiltinFunctions() << func->name();
8421 sBuiltinFunctions()->append( func->aliases() );
8434 sFunctions()->append(
function );
8435 if ( transferOwnership )
8436 sOwnedFunctions()->append(
function );
8450 sFunctions()->removeAt( fnIdx );
8458 qDeleteAll( *sOwnedFunctions() );
8459 sOwnedFunctions()->clear();
8464 if ( sBuiltinFunctions()->isEmpty() )
8468 return *sBuiltinFunctions();
8476 QStringLiteral(
"Arrays" ) )
8487 if ( args->
count() < 2 )
8490 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8500 QVariantList result;
8502 if ( args->
count() < 2 )
8506 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8509 std::unique_ptr< QgsExpressionContext > tempContext;
8512 tempContext = std::make_unique< QgsExpressionContext >();
8513 subContext = tempContext.get();
8519 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8522 result << args->
at( 1 )->
eval( parent, subContext );
8547 if ( args->
count() < 2 )
8551 args->
at( 0 )->
prepare( parent, context );
8555 subContext = *context;
8561 args->
at( 1 )->
prepare( parent, &subContext );
8571 QStringLiteral(
"Arrays" ) )
8582 if ( args->
count() < 2 )
8585 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8595 QVariantList result;
8597 if ( args->
count() < 2 )
8601 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8604 std::unique_ptr< QgsExpressionContext > tempContext;
8607 tempContext = std::make_unique< QgsExpressionContext >();
8608 subContext = tempContext.get();
8615 if ( args->
count() >= 3 )
8617 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
8619 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
8621 limit = limitVar.toInt();
8629 for (
const QVariant &value : array )
8632 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
8636 if ( limit > 0 && limit == result.size() )
8663 if ( args->
count() < 2 )
8667 args->
at( 0 )->
prepare( parent, context );
8671 subContext = *context;
8677 args->
at( 1 )->
prepare( parent, &subContext );
8686 QStringLiteral(
"General" ) )
8697 if ( args->
count() < 3 )
8701 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8703 QVariant
name = args->
at( 0 )->
eval( parent, context );
8704 QVariant value = args->
at( 1 )->
eval( parent, context );
8707 appendTemporaryVariable( context,
name.toString(), value );
8708 if ( args->
at( 2 )->
isStatic( parent, context ) )
8710 popTemporaryVariable( context );
8721 if ( args->
count() < 3 )
8725 QVariant
name = args->
at( 0 )->
eval( parent, context );
8726 QVariant value = args->
at( 1 )->
eval( parent, context );
8729 std::unique_ptr< QgsExpressionContext > tempContext;
8730 if ( !updatedContext )
8732 tempContext = std::make_unique< QgsExpressionContext >();
8733 updatedContext = tempContext.get();
8736 appendTemporaryVariable( updatedContext,
name.toString(), value );
8737 result = args->
at( 2 )->
eval( parent, updatedContext );
8740 popTemporaryVariable( updatedContext );
8761 if ( args->
count() < 3 )
8766 QVariant value = args->
at( 1 )->
prepare( parent, context );
8769 std::unique_ptr< QgsExpressionContext > tempContext;
8770 if ( !updatedContext )
8772 tempContext = std::make_unique< QgsExpressionContext >();
8773 updatedContext = tempContext.get();
8776 appendTemporaryVariable( updatedContext,
name.toString(), value );
8777 args->
at( 2 )->
prepare( parent, updatedContext );
8780 popTemporaryVariable( updatedContext );
8785 void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
8791 void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const