64 #include <QMimeDatabase>
65 #include <QProcessEnvironment>
66 #include <QCryptographicHash>
67 #include <QRegularExpression>
89 QVariantList argValues;
93 const QList< QgsExpressionNode * > argList = args->
list();
100 v = QVariant::fromValue( n );
104 v = n->eval( parent, context );
106 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
107 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
110 argValues.append( v );
115 return func( argValues, context, parent, node );
126 return QStringList();
153 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
158 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
170 const QString &group,
171 const QString &helpText,
175 const QStringList &aliases,
179 , mAliases( aliases )
180 , mUsesGeometry( false )
181 , mUsesGeometryFunc( usesGeometry )
182 , mReferencedColumnsFunc( referencedColumns )
194 if ( mUsesGeometryFunc )
195 return mUsesGeometryFunc( node );
197 return mUsesGeometry;
202 if ( mReferencedColumnsFunc )
203 return mReferencedColumnsFunc( node );
205 return mReferencedColumns;
211 return mIsStaticFunc( node, parent, context );
219 return mPrepareFunc( node, parent, context );
231 mIsStaticFunc =
nullptr;
237 mPrepareFunc = prepareFunc;
242 if ( node && node->
args() )
244 const QList< QgsExpressionNode * > argList = node->
args()->
list();
247 if ( !argNode->isStatic( parent, context ) )
257 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
258 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
259 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
261 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
268 double current = start + step;
269 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
284 QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
290 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
299 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
301 return expression.evaluate( context );
306 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
307 return QVariant( std::sqrt( x ) );
312 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
313 return QVariant( std::fabs( val ) );
318 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
319 return ( deg * M_PI ) / 180;
323 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
324 return ( 180 * rad ) / M_PI;
328 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
329 return QVariant( std::sin( x ) );
333 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
334 return QVariant( std::cos( x ) );
338 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
339 return QVariant( std::tan( x ) );
343 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
344 return QVariant( std::asin( x ) );
348 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
349 return QVariant( std::acos( x ) );
353 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
354 return QVariant( std::atan( x ) );
358 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
359 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
360 return QVariant( std::atan2( y, x ) );
364 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
365 return QVariant( std::exp( x ) );
369 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
372 return QVariant( std::log( x ) );
376 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
379 return QVariant( log10( x ) );
383 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
384 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
385 if ( x <= 0 || b <= 0 )
387 return QVariant( std::log( x ) / std::log( b ) );
391 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
392 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
396 std::random_device rd;
397 std::mt19937_64 generator( rd() );
399 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
402 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
405 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
410 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
411 std::hash<std::string> hasher;
412 seed = hasher( seedStr.toStdString() );
414 generator.seed( seed );
418 double f =
static_cast< double >( generator() ) /
static_cast< double >( generator.max() );
419 return QVariant( min + f * ( max - min ) );
423 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
424 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
428 std::random_device rd;
429 std::mt19937_64 generator( rd() );
431 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
434 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
437 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
442 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
443 std::hash<std::string> hasher;
444 seed = hasher( seedStr.toStdString() );
446 generator.seed( seed );
449 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
450 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
451 return QVariant( randomInteger );
454 return QVariant(
int( randomInteger ) );
459 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
460 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
461 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
462 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
463 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
465 if ( domainMin >= domainMax )
467 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
472 if ( val >= domainMax )
476 else if ( val <= domainMin )
482 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
483 double c = rangeMin - ( domainMin * m );
486 return QVariant( m * val +
c );
491 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
492 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
493 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
494 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
495 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
496 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
498 if ( domainMin >= domainMax )
500 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
510 if ( val >= domainMax )
514 else if ( val <= domainMin )
520 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
525 QVariant result( QVariant::Double );
526 double maxVal = std::numeric_limits<double>::quiet_NaN();
527 for (
const QVariant &val : values )
529 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() : QgsExpressionUtils::getDoubleValue( val, parent );
530 if ( std::isnan( maxVal ) )
534 else if ( !std::isnan( testVal ) )
536 maxVal = std::max( maxVal, testVal );
540 if ( !std::isnan( maxVal ) )
542 result = QVariant( maxVal );
549 QVariant result( QVariant::Double );
550 double minVal = std::numeric_limits<double>::quiet_NaN();
551 for (
const QVariant &val : values )
553 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() : QgsExpressionUtils::getDoubleValue( val, parent );
554 if ( std::isnan( minVal ) )
558 else if ( !std::isnan( testVal ) )
560 minVal = std::min( minVal, testVal );
564 if ( !std::isnan( minVal ) )
566 result = QVariant( minVal );
578 QVariant value = node->
eval( parent, context );
580 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, parent );
583 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
588 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
590 value = node->
eval( parent, context );
596 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
601 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
603 QString subExpression = node->
dump();
607 if ( values.count() > 3 )
609 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
612 if ( !nl || nl->value().isValid() )
617 if ( values.count() > 4 )
619 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
621 value = node->
eval( parent, context );
628 if ( values.count() > 5 )
630 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
633 if ( !nl || nl->value().isValid() )
635 orderBy = node->
dump();
647 bool isStatic =
true;
648 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
649 || filterExp.referencedVariables().contains( QString() )
650 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
651 || subExp.referencedVariables().contains( QString() ) )
657 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
658 for (
const QString &varName : refVars )
661 if ( scope && !scope->
isStatic( varName ) )
671 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
672 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
676 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
687 subContext.appendScope( subScope );
688 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok );
694 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok );
698 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
709 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
714 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
717 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
726 QVariant value = node->
eval( parent, context );
728 QString relationId = value.toString();
735 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
737 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
742 relation = relations.at( 0 );
749 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
751 value = node->
eval( parent, context );
757 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
762 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
764 QString subExpression = node->
dump();
768 if ( values.count() > 3 )
770 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
772 value = node->
eval( parent, context );
779 if ( values.count() > 4 )
781 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
784 if ( !nl || nl->value().isValid() )
786 orderBy = node->
dump();
797 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->
id(),
798 QString::number(
static_cast< int >( aggregate ) ),
810 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok );
814 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
828 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
833 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
836 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
845 QString subExpression = node->
dump();
849 if ( values.count() > 1 )
851 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
854 if ( !nl || nl->value().isValid() )
855 groupBy = node->
dump();
859 if ( values.count() > 2 )
861 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
864 if ( !nl || nl->value().isValid() )
870 if ( orderByPos >= 0 && values.count() > orderByPos )
872 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
875 if ( !nl || nl->value().isValid() )
877 orderBy = node->
dump();
885 if ( !groupBy.isEmpty() )
888 QVariant groupByValue = groupByExp.evaluate( context );
889 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
890 groupByValue.isNull() ? QStringLiteral(
"is" ) : QStringLiteral(
"=" ),
892 if ( !parameters.
filter.isEmpty() )
893 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
895 parameters.
filter = groupByClause;
901 bool isStatic =
true;
902 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
903 for (
const QString &varName : refVars )
906 if ( scope && !scope->
isStatic( varName ) )
916 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter,
917 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
921 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
933 subContext.appendScope( subScope );
934 result = vl->
aggregate( aggregate, subExpression, parameters, &subContext, &ok );
938 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1043 if ( values.count() > 3 )
1045 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1047 QVariant value = node->
eval( parent, context );
1049 parameters.
delimiter = value.toString();
1060 if ( values.count() > 3 )
1062 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1064 QVariant value = node->
eval( parent, context );
1066 parameters.
delimiter = value.toString();
1082 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1084 if ( !scale.isValid() || scale.isNull() )
1087 const double v = scale.toDouble( &ok );
1095 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1096 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1097 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1100 if ( testValue <= minValue )
1102 return QVariant( minValue );
1104 else if ( testValue >= maxValue )
1106 return QVariant( maxValue );
1110 return QVariant( testValue );
1116 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1117 return QVariant( std::floor( x ) );
1122 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1123 return QVariant( std::ceil( x ) );
1128 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1132 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1136 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1141 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1142 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1143 if ( format.isEmpty() && !language.isEmpty() )
1145 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1146 return QVariant( QDateTime() );
1149 if ( format.isEmpty() && language.isEmpty() )
1150 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1152 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1153 QLocale locale = QLocale();
1154 if ( !language.isEmpty() )
1156 locale = QLocale( language );
1159 QDateTime datetime = locale.toDateTime( datetimestring, format );
1160 if ( !datetime.isValid() )
1162 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1163 datetime = QDateTime();
1165 return QVariant( datetime );
1170 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1171 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1172 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1174 const QDate date( year, month, day );
1175 if ( !date.isValid() )
1177 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1180 return QVariant( date );
1185 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1186 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1187 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1189 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1190 if ( !time.isValid() )
1192 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1195 return QVariant( time );
1200 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1201 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1202 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1203 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1204 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1205 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1207 const QDate date( year, month, day );
1208 if ( !date.isValid() )
1210 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1213 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1214 if ( !time.isValid() )
1216 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1219 return QVariant( QDateTime( date, time ) );
1224 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1225 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1226 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1227 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1228 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1229 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1230 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1232 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1237 for (
const QVariant &value : values )
1239 if ( value.isNull() )
1248 const QVariant val1 = values.at( 0 );
1249 const QVariant val2 = values.at( 1 );
1259 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1260 return QVariant(
str.toLower() );
1264 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1265 return QVariant(
str.toUpper() );
1269 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1270 QStringList elems =
str.split(
' ' );
1271 for (
int i = 0; i < elems.size(); i++ )
1273 if ( elems[i].size() > 1 )
1274 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1276 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1281 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1282 return QVariant(
str.trimmed() );
1287 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1288 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1294 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1295 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1301 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1302 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1309 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1315 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1316 return QVariant( QString( character ) );
1321 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1323 if ( value.isEmpty() )
1328 int res = value.at( 0 ).unicode();
1329 return QVariant( res );
1334 if ( values.length() == 2 || values.length() == 3 )
1336 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1337 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1339 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1353 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1357 return QVariant( geom.
length() );
1361 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1362 return QVariant(
str.length() );
1367 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1372 double totalLength = 0;
1375 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1377 totalLength += line->length3D();
1381 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1382 totalLength += segmentized->length3D();
1391 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1393 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1394 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1395 QVector< QPair< QString, QString > > mapItems;
1397 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1399 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1403 std::sort( mapItems.begin(),
1405 [](
const QPair< QString, QString > &pair1,
1406 const QPair< QString, QString > &pair2 )
1408 return ( pair1.first.length() > pair2.first.length() );
1411 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1413 str =
str.replace( it->first, it->second );
1416 return QVariant(
str );
1418 else if ( values.count() == 3 )
1420 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1421 QVariantList before;
1423 bool isSingleReplacement =
false;
1425 if ( values.at( 1 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
1427 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1431 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1434 if ( values.at( 2 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
1436 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1437 isSingleReplacement =
true;
1441 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1444 if ( !isSingleReplacement && before.length() != after.length() )
1446 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1450 for (
int i = 0; i < before.length(); i++ )
1452 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1455 return QVariant(
str );
1459 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1466 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1467 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1468 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1470 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1471 if ( !re.isValid() )
1473 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1476 return QVariant(
str.replace( re, after ) );
1481 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1482 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1484 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1485 if ( !re.isValid() )
1487 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1490 return QVariant( (
str.indexOf( re ) + 1 ) );
1495 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1496 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1497 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1499 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1500 if ( !re.isValid() )
1502 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1506 QRegularExpressionMatch matches = re.match(
str );
1507 if ( matches.hasMatch() )
1510 QStringList list = matches.capturedTexts();
1513 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1515 array += ( !( *it ).isEmpty() ) ? *it : empty;
1518 return QVariant( array );
1528 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1529 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1531 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1532 if ( !re.isValid() )
1534 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1539 QRegularExpressionMatch match = re.match(
str );
1540 if ( match.hasMatch() )
1543 if ( match.lastCapturedIndex() > 0 )
1546 return QVariant( match.captured( 1 ) );
1551 return QVariant( match.captured( 0 ) );
1556 return QVariant(
"" );
1562 QString uuid = QUuid::createUuid().toString();
1563 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1564 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1565 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1566 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1572 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1575 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1576 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1579 if ( values.at( 2 ).isValid() )
1580 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1586 from =
str.size() + from;
1592 else if ( from > 0 )
1600 len =
str.size() + len - from;
1607 return QVariant(
str.mid( from, len ) );
1613 return QVariant(
static_cast< int >( f.
id() ) );
1618 QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
1621 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1625 int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1626 if ( bandNb < 1 || bandNb > layer->
bandCount() )
1628 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1632 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1635 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1643 if ( multiPoint.count() == 1 )
1645 point = multiPoint[0];
1655 return std::isnan( value ) ? QVariant() : value;
1670 if ( values.size() == 1 )
1672 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1675 else if ( values.size() == 2 )
1677 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1678 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1682 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %1 given." ).arg( values.length() ) );
1692 if ( values.size() == 0 || values.at( 0 ).isNull() )
1698 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1703 for (
int i = 0; i < fields.
count(); ++i )
1714 bool evaluate =
true;
1716 if ( values.isEmpty() )
1719 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1721 else if ( values.size() == 1 )
1723 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1724 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1726 else if ( values.size() == 2 )
1728 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1729 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1731 else if ( values.size() == 3 )
1733 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1734 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1735 evaluate = values.value( 2 ).toBool();
1741 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %1 given." ).arg( values.length() ) );
1745 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %1 given." ).arg( values.length() ) );
1776 subContext.setFeature( feature );
1785 exp.prepare( &subContext );
1786 return exp.evaluate( &subContext ).toString();
1792 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
1797 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
1805 if ( values.isEmpty() )
1808 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1810 else if ( values.size() == 1 )
1812 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1813 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1815 else if ( values.size() == 2 )
1817 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1818 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1822 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %1 given." ).arg( values.length() ) );
1826 if ( !layer || !feature.
isValid() )
1828 return QVariant( QVariant::Bool );
1838 if ( values.isEmpty() )
1839 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1840 else if ( values.count() == 1 )
1841 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1844 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %1 given." ).arg( values.length() ) );
1850 return QVariant( QVariant::LongLong );
1858 static QMap<QString, qlonglong> counterCache;
1859 QVariant functionResult;
1861 std::function<void()> fetchAndIncrementFunc = [ =, &functionResult ]()
1864 const QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1869 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
1870 if ( database.isEmpty() )
1872 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
1877 database = values.at( 0 ).toString();
1880 const QString table = values.at( 1 ).toString();
1881 const QString idColumn = values.at( 2 ).toString();
1882 const QString filterAttribute = values.at( 3 ).toString();
1883 const QVariant filterValue = values.at( 4 ).toString();
1884 const QVariantMap defaultValues = values.at( 5 ).toMap();
1890 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
1893 functionResult = QVariant();
1897 QString errorMessage;
1898 QString currentValSql;
1900 qlonglong nextId = 0;
1901 bool cachedMode =
false;
1902 bool valueRetrieved =
false;
1904 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
1911 auto cachedCounter = counterCache.find( cacheString );
1913 if ( cachedCounter != counterCache.end() )
1915 qlonglong &cachedValue = cachedCounter.value();
1916 nextId = cachedValue;
1918 cachedValue = nextId;
1919 valueRetrieved =
true;
1924 if ( !cachedMode || !valueRetrieved )
1926 int result = SQLITE_ERROR;
1929 if ( !filterAttribute.isNull() )
1934 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
1936 if ( result == SQLITE_OK )
1939 if ( sqliteStatement.
step() == SQLITE_ROW )
1945 if ( cachedMode && result == SQLITE_OK )
1947 counterCache.insert( cacheString, nextId );
1951 counterCache.remove( cacheString );
1954 valueRetrieved =
true;
1958 if ( valueRetrieved )
1967 if ( !filterAttribute.isNull() )
1973 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
1976 vals << iter.value().toString();
1979 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
1980 upsertSql += QLatin1String(
" VALUES " );
1981 upsertSql +=
'(' + vals.join(
',' ) +
')';
1983 int result = SQLITE_ERROR;
1987 if ( transaction->
executeSql( upsertSql, errorMessage ) )
1994 result = sqliteDb.
exec( upsertSql, errorMessage );
1996 if ( result == SQLITE_OK )
1998 functionResult = QVariant( nextId );
2003 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2004 functionResult = QVariant();
2009 functionResult = QVariant();
2014 return functionResult;
2020 for (
const QVariant &value : values )
2022 if ( !value.isNull() )
2023 concat += QgsExpressionUtils::getStringValue( value, parent );
2030 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2031 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2036 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2037 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2038 return string.right( pos );
2043 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2044 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2045 return string.left( pos );
2050 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2051 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2052 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2053 return string.leftJustified( length, fill.at( 0 ),
true );
2058 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2059 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2060 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2061 return string.rightJustified( length, fill.at( 0 ),
true );
2066 if ( values.size() < 1 )
2068 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2072 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2073 for (
int n = 1; n < values.length(); n++ )
2075 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2083 return QVariant( QDateTime::currentDateTime() );
2088 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2089 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2090 if ( format.isEmpty() && !language.isEmpty() )
2092 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2093 return QVariant( QDate() );
2096 if ( format.isEmpty() && language.isEmpty() )
2097 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2099 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2100 QLocale locale = QLocale();
2101 if ( !language.isEmpty() )
2103 locale = QLocale( language );
2106 QDate date = locale.toDate( datestring, format );
2107 if ( !date.isValid() )
2109 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2112 return QVariant( date );
2117 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2118 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2119 if ( format.isEmpty() && !language.isEmpty() )
2121 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2122 return QVariant( QTime() );
2125 if ( format.isEmpty() && language.isEmpty() )
2126 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2128 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2129 QLocale locale = QLocale();
2130 if ( !language.isEmpty() )
2132 locale = QLocale( language );
2135 QTime time = locale.toTime( timestring, format );
2136 if ( !time.isValid() )
2138 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2141 return QVariant( time );
2146 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2155 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2156 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2157 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2159 QString formatString;
2160 if ( values.count() > 3 )
2161 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2163 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2164 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2168 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2172 else if ( ! formatString.isEmpty() )
2174 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2178 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2182 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2188 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2196 return floatToDegreeFormat( format, values, context, parent, node );
2203 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2205 return ok ? QVariant( value ) : QVariant();
2211 return floatToDegreeFormat( format, values, context, parent, node );
2216 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2217 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2218 qint64 seconds = d2.secsTo( d1 );
2219 return QVariant::fromValue(
QgsInterval( seconds ) );
2224 if ( !values.at( 0 ).canConvert<QDate>() )
2227 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2228 if ( !date.isValid() )
2233 return date.dayOfWeek() % 7;
2238 QVariant value = values.at( 0 );
2239 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2242 return QVariant( inter.
days() );
2246 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2247 return QVariant( d1.date().day() );
2253 QVariant value = values.at( 0 );
2254 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2257 return QVariant( inter.
years() );
2261 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2262 return QVariant( d1.date().year() );
2268 QVariant value = values.at( 0 );
2269 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2272 return QVariant( inter.
months() );
2276 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2277 return QVariant( d1.date().month() );
2283 QVariant value = values.at( 0 );
2284 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2287 return QVariant( inter.
weeks() );
2291 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2292 return QVariant( d1.date().weekNumber() );
2298 QVariant value = values.at( 0 );
2299 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2302 return QVariant( inter.
hours() );
2306 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2307 return QVariant( t1.hour() );
2313 QVariant value = values.at( 0 );
2314 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2317 return QVariant( inter.
minutes() );
2321 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2322 return QVariant( t1.minute() );
2328 QVariant value = values.at( 0 );
2329 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2332 return QVariant( inter.
seconds() );
2336 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2337 return QVariant( t1.second() );
2343 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2346 return QVariant( dt.toMSecsSinceEpoch() );
2356 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2358 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2361 #define ENSURE_GEOM_TYPE(f, g, geomtype) \
2362 if ( !(f).hasGeometry() ) \
2363 return QVariant(); \
2364 QgsGeometry g = (f).geometry(); \
2365 if ( (g).type() != (geomtype) ) \
2372 if ( g.isMultipart() )
2374 return g.asMultiPoint().at( 0 ).x();
2378 return g.asPoint().x();
2386 if ( g.isMultipart() )
2388 return g.asMultiPoint().at( 0 ).y();
2392 return g.asPoint().y();
2398 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2404 return QVariant( isValid );
2409 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2421 QVariant result( centroid.
asPoint().
x() );
2427 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2439 QVariant result( centroid.
asPoint().
y() );
2445 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2455 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2463 if ( collection->numGeometries() == 1 )
2465 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2476 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2486 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2494 if ( collection->numGeometries() == 1 )
2496 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2507 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2512 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2539 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2556 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2573 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2578 bool ignoreClosing =
false;
2579 if ( values.length() > 1 )
2581 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
2591 bool skipLast =
false;
2592 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
2597 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
2609 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2620 for (
int i = 0; i < line->numPoints() - 1; ++i )
2624 << line->pointN( i )
2625 << line->pointN( i + 1 ) );
2636 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2646 if ( collection->numGeometries() == 1 )
2648 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
2653 if ( !curvePolygon )
2657 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2663 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
2669 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2679 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2685 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
2691 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2700 return QVariant::fromValue(
QgsGeometry( boundary ) );
2705 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2714 return QVariant::fromValue( merged );
2719 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2724 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2727 if ( simplified.
isNull() )
2735 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2740 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2745 if ( simplified.
isNull() )
2753 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2758 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
2759 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
2760 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2761 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
2763 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
2773 if ( values.size() == 1 && ( values.at( 0 ).type() == QVariant::List || values.at( 0 ).type() == QVariant::StringList ) )
2775 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
2782 QVector< QgsGeometry > parts;
2783 parts.reserve( list.size() );
2784 for (
const QVariant &value : std::as_const( list ) )
2802 if ( values.count() < 2 || values.count() > 4 )
2804 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
2808 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2809 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2810 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
2811 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
2812 switch ( values.count() )
2826 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2827 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2828 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2834 if ( values.empty() )
2839 QVector<QgsPoint> points;
2840 points.reserve( values.count() );
2842 auto addPoint = [&points](
const QgsGeometry & geom )
2850 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2857 for (
const QVariant &value : values )
2859 if ( value.type() == QVariant::List )
2861 const QVariantList list = value.toList();
2862 for (
const QVariant &v : list )
2864 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
2869 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
2873 if ( points.count() < 2 )
2881 if ( values.count() < 1 )
2883 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
2887 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2891 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
2893 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
2900 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
2905 if ( !exteriorRing )
2908 polygon->setExteriorRing( exteriorRing->
segmentize() );
2911 for (
int i = 1; i < values.count(); ++i )
2913 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
2920 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
2927 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
2935 polygon->addInteriorRing( ring->
segmentize() );
2938 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
2943 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
2944 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
2945 lineString->clear();
2947 for (
const QVariant &value : values )
2949 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
2956 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2963 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
2971 lineString->addVertex( *point );
2974 tr->setExteriorRing( lineString.release() );
2976 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
2981 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2988 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2989 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2996 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3003 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3011 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3016 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3023 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3024 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3025 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3026 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3032 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3039 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3046 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3047 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3053 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3060 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3067 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3070 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3077 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3081 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3088 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3095 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3102 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3117 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3123 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3129 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3130 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3138 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3144 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3150 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3159 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3162 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3163 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3164 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
3172 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
3188 return QVariant( QPointF( p.
x(), p.
y() ) );
3193 QVariant v = pointAt( values, f, parent );
3194 if ( v.type() == QVariant::PointF )
3195 return QVariant( v.toPointF().x() );
3201 QVariant v = pointAt( values, f, parent );
3202 if ( v.type() == QVariant::PointF )
3203 return QVariant( v.toPointF().y() );
3212 return QVariant::fromValue( geom );
3219 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3221 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3227 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
3233 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3238 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3245 ogcContext.
layer = mapLayerPtr.data();
3246 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
3250 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3263 return QVariant( area );
3267 return QVariant( f.geometry().area() );
3273 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3278 return QVariant( geom.
area() );
3290 return QVariant( len );
3294 return QVariant( f.geometry().length() );
3307 return QVariant( len );
3311 return f.geometry().isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
3317 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3323 return QVariant( geom.
length() );
3328 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3334 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3343 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3352 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3367 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
3368 if ( !curvePolygon )
3380 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3387 return QVariant( curvePolygon->
ringCount() );
3389 bool foundPoly =
false;
3397 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
3398 if ( !curvePolygon )
3409 return QVariant( ringCount );
3414 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3416 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
3422 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3428 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3434 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3440 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3446 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3452 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3458 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3466 double max = std::numeric_limits< double >::lowest();
3470 double z = ( *it ).z();
3476 if ( max == std::numeric_limits< double >::lowest() )
3477 return QVariant( QVariant::Double );
3479 return QVariant( max );
3484 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3492 double min = std::numeric_limits< double >::max();
3496 double z = ( *it ).z();
3502 if ( min == std::numeric_limits< double >::max() )
3503 return QVariant( QVariant::Double );
3505 return QVariant( min );
3510 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3518 double min = std::numeric_limits< double >::max();
3522 double m = ( *it ).m();
3528 if ( min == std::numeric_limits< double >::max() )
3529 return QVariant( QVariant::Double );
3531 return QVariant( min );
3536 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3544 double max = std::numeric_limits< double >::lowest();
3548 double m = ( *it ).m();
3554 if ( max == std::numeric_limits< double >::lowest() )
3555 return QVariant( QVariant::Double );
3557 return QVariant( max );
3562 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3566 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
3568 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
3573 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3577 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
3584 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
3592 return QVariant::fromValue( curve->
isClosed() );
3597 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3610 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
3611 closedLine->close();
3613 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
3623 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
3625 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
3626 closedLine->close();
3628 closed->addGeometry( closedLine.release() );
3631 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
3639 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3643 return QVariant::fromValue( fGeom.
isEmpty() );
3648 if ( values.at( 0 ).isNull() )
3649 return QVariant::fromValue(
true );
3651 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3652 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
3657 if ( values.length() < 2 || values.length() > 3 )
3660 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3661 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3668 if ( values.length() == 2 )
3671 QString result = engine->relate( sGeom.
constGet() );
3672 return QVariant::fromValue( result );
3677 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3678 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
3679 return QVariant::fromValue( result );
3685 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3686 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3691 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3692 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3693 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
3697 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3698 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3699 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
3703 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3704 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3705 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
3709 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3710 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3711 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
3715 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3716 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3717 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
3721 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3722 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3723 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
3727 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3728 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3729 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
3733 if ( values.length() < 2 || values.length() > 3 )
3736 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3737 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3739 if ( values.length() == 3 )
3740 seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3743 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3749 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3751 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
3756 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3757 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
3764 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3771 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
3775 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3776 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3777 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3778 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3781 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3787 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3790 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
3794 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3795 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3796 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
3799 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3805 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3808 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
3812 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
3815 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3821 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3822 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3823 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3827 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3830 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3836 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3837 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3838 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3842 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3845 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3851 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3852 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3853 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3856 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3862 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3863 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3864 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3866 return QVariant::fromValue( fGeom );
3871 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3872 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3873 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
3884 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
3890 if ( multiPoint.count() == 1 )
3896 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
3905 fGeom.
rotate( rotation, pt );
3906 return QVariant::fromValue( fGeom );
3911 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3913 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3918 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3920 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3926 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3927 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3929 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3935 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3937 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3944 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3946 if ( values.length() == 2 )
3947 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
3955 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3961 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3963 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3969 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3975 double area,
angle, width, height;
3988 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3989 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3991 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3997 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4004 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
4009 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
4017 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
4019 reversed->addGeometry( curve->
reversed() );
4026 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
4033 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4044 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
4053 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
4059 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4060 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4061 return QVariant( fGeom.
distance( sGeom ) );
4066 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4067 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4070 if ( values.length() == 3 && values.at( 2 ).isValid() )
4072 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4073 densify = std::clamp( densify, 0.0, 1.0 );
4081 return res > -1 ? QVariant( res ) : QVariant();
4086 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4087 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4089 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4094 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4095 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4097 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4102 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4103 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4105 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4111 if ( values.length() < 1 || values.length() > 2 )
4114 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4116 if ( values.length() == 2 )
4117 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4118 QString wkt = fGeom.
asWkt( prec );
4119 return QVariant( wkt );
4124 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4125 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
4130 if ( values.length() != 2 )
4132 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %1 given." ).arg( values.length() ) );
4136 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4137 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4139 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4146 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4151 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4158 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4165 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
4172 if ( pt1->
y() < pt2->
y() )
4174 else if ( pt1->
y() > pt2->
y() )
4182 if ( pt1->
x() < pt2->
x() )
4184 else if ( pt1->
x() > pt2->
x() )
4185 return M_PI + ( M_PI_2 );
4190 if ( pt1->
x() < pt2->
x() )
4192 if ( pt1->
y() < pt2->
y() )
4194 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
4198 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4205 if ( pt1->
y() > pt2->
y() )
4207 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
4212 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4213 + ( M_PI + ( M_PI_2 ) );
4220 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4224 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
4228 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4229 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4230 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4233 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
4240 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4241 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4243 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4250 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4254 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4261 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4269 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
4279 if ( values.length() != 3 )
4282 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4283 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4284 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4288 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
4294 if ( values.length() < 2 )
4297 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4300 return values.at( 0 );
4302 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4303 QVariant cachedExpression;
4308 if ( cachedExpression.isValid() )
4315 bool asc = values.value( 2 ).toBool();
4333 Q_ASSERT( collection );
4337 QgsExpressionSorter sorter( orderBy );
4339 QList<QgsFeature> partFeatures;
4340 partFeatures.reserve( collection->
partCount() );
4341 for (
int i = 0; i < collection->
partCount(); ++i )
4347 sorter.sortFeatures( partFeatures, unconstedContext );
4351 Q_ASSERT( orderedGeom );
4356 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
4361 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
4364 delete unconstedContext;
4371 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4372 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4376 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4382 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4383 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4387 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4393 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4394 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4398 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4404 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4407 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
4413 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
4420 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4427 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4428 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4430 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
4432 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
4437 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4438 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4445 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4446 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4451 vertex = count + vertex;
4459 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4460 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4465 vertex = count + vertex;
4473 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4474 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4478 return distance >= 0 ? distance : QVariant();
4483 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
4485 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4486 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
4489 if ( values.length() >= 1 )
4491 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4492 return QVariant( qlonglong( std::round( number ) ) );
4507 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4508 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4509 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4516 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
4517 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
4518 return locale.toString( value,
'f', places );
4523 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
4524 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4525 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4527 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
4528 return locale.toString( datetime, format );
4534 int avg = ( color.red() + color.green() + color.blue() ) / 3;
4535 int alpha = color.alpha();
4537 color.setRgb( avg, avg, avg, alpha );
4546 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4551 else if ( ratio < 0 )
4556 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
4557 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
4558 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
4559 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
4561 QColor newColor( red, green, blue, alpha );
4568 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4569 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4570 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4571 QColor color = QColor( red, green, blue );
4572 if ( ! color.isValid() )
4574 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
4575 color = QColor( 0, 0, 0 );
4578 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4583 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
4584 QVariant value = node->
eval( parent, context );
4588 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
4590 value = node->
eval( parent, context );
4598 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
4600 QVariant value = node->
eval( parent, context );
4602 if ( value.toBool() )
4604 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
4606 value = node->
eval( parent, context );
4611 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
4613 value = node->
eval( parent, context );
4621 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4622 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4623 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4624 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
4625 QColor color = QColor( red, green, blue, alpha );
4626 if ( ! color.isValid() )
4628 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
4629 color = QColor( 0, 0, 0 );
4640 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
4645 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4649 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
4654 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4655 QColor color = ramp->
color( value );
4662 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4664 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4666 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4668 QColor color = QColor::fromHslF( hue, saturation, lightness );
4670 if ( ! color.isValid() )
4672 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
4673 color = QColor( 0, 0, 0 );
4676 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4682 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4684 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4686 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4688 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
4690 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
4691 if ( ! color.isValid() )
4693 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
4694 color = QColor( 0, 0, 0 );
4702 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4704 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4706 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4708 QColor color = QColor::fromHsvF( hue, saturation, value );
4710 if ( ! color.isValid() )
4712 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
4713 color = QColor( 0, 0, 0 );
4716 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4722 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4724 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4726 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4728 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
4730 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
4731 if ( ! color.isValid() )
4733 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
4734 color = QColor( 0, 0, 0 );
4742 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
4744 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4746 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4748 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
4750 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
4752 if ( ! color.isValid() )
4754 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
4755 color = QColor( 0, 0, 0 );
4758 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4764 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
4766 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4768 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4770 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
4772 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
4774 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
4775 if ( ! color.isValid() )
4777 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
4778 color = QColor( 0, 0, 0 );
4786 if ( ! color.isValid() )
4788 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
4792 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4793 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
4795 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
4796 return color.green();
4797 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
4798 return color.blue();
4799 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
4800 return color.alpha();
4801 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
4802 return color.hsvHueF() * 360;
4803 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
4804 return color.hsvSaturationF() * 100;
4805 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
4806 return color.valueF() * 100;
4807 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
4808 return color.hslHueF() * 360;
4809 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
4810 return color.hslSaturationF() * 100;
4811 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
4812 return color.lightnessF() * 100;
4813 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
4814 return color.cyanF() * 100;
4815 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
4816 return color.magentaF() * 100;
4817 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
4818 return color.yellowF() * 100;
4819 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
4820 return color.blackF() * 100;
4822 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
4828 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
4829 if ( map.count() < 1 )
4831 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
4835 QList< QColor > colors;
4837 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
4840 if ( !colors.last().isValid() )
4842 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
4846 double step = it.key().toDouble();
4847 if ( it == map.constBegin() )
4852 else if ( it == map.constEnd() )
4862 bool discrete = values.at( 1 ).toBool();
4864 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
4870 if ( ! color.isValid() )
4872 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
4876 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4877 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4878 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
4879 color.setRed( value );
4880 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
4881 color.setGreen( value );
4882 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
4883 color.setBlue( value );
4884 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
4885 color.setAlpha( value );
4886 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
4887 color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
4888 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
4889 color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
4890 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
4891 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
4892 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
4893 color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
4894 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
4895 color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
4896 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
4897 color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
4898 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
4899 color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
4900 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
4901 color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
4902 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
4903 color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
4904 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
4905 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
4908 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
4917 if ( ! color.isValid() )
4919 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
4923 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
4931 if ( ! color.isValid() )
4933 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
4937 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
4944 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
4947 return QVariant::fromValue( geom );
4953 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4954 QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4955 QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4959 return QVariant::fromValue( fGeom );
4962 return QVariant::fromValue( fGeom );
4971 return QVariant::fromValue( fGeom );
4985 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
4988 QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
4998 result = QVariant::fromValue( fet );
5008 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), parent );
5011 if ( !featureSource )
5016 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5017 int attributeId = featureSource->fields().lookupField( attribute );
5018 if ( attributeId == -1 )
5023 const QVariant &attVal = values.at( 2 );
5025 const QString cacheValueKey = QStringLiteral(
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
5047 res = QVariant::fromValue( fet );
5062 if ( !values.isEmpty() )
5065 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
5066 fieldName = col->
name();
5067 else if ( values.size() == 2 )
5068 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5071 QVariant value = values.at( 0 );
5076 if ( fieldIndex == -1 )
5078 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5082 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
5084 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName, value.toString() );
5093 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName );
5104 result =
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
5111 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5119 const QVariant data = values.at( 0 );
5120 const QMimeDatabase db;
5121 return db.mimeTypeForData( data.toByteArray() ).name();
5126 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5132 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5133 if ( QString::compare( layerProperty, QStringLiteral(
"name" ), Qt::CaseInsensitive ) == 0 )
5134 return layer->
name();
5135 else if ( QString::compare( layerProperty, QStringLiteral(
"id" ), Qt::CaseInsensitive ) == 0 )
5137 else if ( QString::compare( layerProperty, QStringLiteral(
"title" ), Qt::CaseInsensitive ) == 0 )
5139 else if ( QString::compare( layerProperty, QStringLiteral(
"abstract" ), Qt::CaseInsensitive ) == 0 )
5141 else if ( QString::compare( layerProperty, QStringLiteral(
"keywords" ), Qt::CaseInsensitive ) == 0 )
5143 QStringList keywords;
5145 for (
auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
5147 keywords.append( it.value() );
5149 if ( !keywords.isEmpty() )
5153 else if ( QString::compare( layerProperty, QStringLiteral(
"data_url" ), Qt::CaseInsensitive ) == 0 )
5155 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution" ), Qt::CaseInsensitive ) == 0 )
5159 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
5161 else if ( QString::compare( layerProperty, QStringLiteral(
"source" ), Qt::CaseInsensitive ) == 0 )
5163 else if ( QString::compare( layerProperty, QStringLiteral(
"min_scale" ), Qt::CaseInsensitive ) == 0 )
5165 else if ( QString::compare( layerProperty, QStringLiteral(
"max_scale" ), Qt::CaseInsensitive ) == 0 )
5167 else if ( QString::compare( layerProperty, QStringLiteral(
"is_editable" ), Qt::CaseInsensitive ) == 0 )
5169 else if ( QString::compare( layerProperty, QStringLiteral(
"crs" ), Qt::CaseInsensitive ) == 0 )
5171 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
5173 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_description" ), Qt::CaseInsensitive ) == 0 )
5175 else if ( QString::compare( layerProperty, QStringLiteral(
"extent" ), Qt::CaseInsensitive ) == 0 )
5178 QVariant result = QVariant::fromValue( extentGeom );
5181 else if ( QString::compare( layerProperty, QStringLiteral(
"distance_units" ), Qt::CaseInsensitive ) == 0 )
5183 else if ( QString::compare( layerProperty, QStringLiteral(
"type" ), Qt::CaseInsensitive ) == 0 )
5185 switch ( layer->
type() )
5188 return QCoreApplication::translate(
"expressions",
"Vector" );
5190 return QCoreApplication::translate(
"expressions",
"Raster" );
5192 return QCoreApplication::translate(
"expressions",
"Mesh" );
5194 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
5196 return QCoreApplication::translate(
"expressions",
"Plugin" );
5198 return QCoreApplication::translate(
"expressions",
"Annotation" );
5200 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
5206 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
5209 if ( QString::compare( layerProperty, QStringLiteral(
"storage_type" ), Qt::CaseInsensitive ) == 0 )
5211 else if ( QString::compare( layerProperty, QStringLiteral(
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
5213 else if ( QString::compare( layerProperty, QStringLiteral(
"feature_count" ), Qt::CaseInsensitive ) == 0 )
5215 else if ( QString::compare( layerProperty, QStringLiteral(
"path" ), Qt::CaseInsensitive ) == 0 )
5220 return decodedUri.value( QStringLiteral(
"path" ) );
5231 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5234 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
5244 const QString uriPart = values.at( 1 ).toString();
5248 if ( !uriPart.isNull() )
5250 return decodedUri.value( values.at( 1 ).toString() );
5260 QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5267 if ( !layersByName.isEmpty() )
5269 layer = layersByName.at( 0 );
5280 int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5281 if ( band < 1 || band > rl->
bandCount() )
5283 parent->
setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer %2" ).arg( band ).arg( layerIdOrName ) );
5287 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5290 if ( QString::compare( layerProperty, QStringLiteral(
"avg" ), Qt::CaseInsensitive ) == 0 )
5292 else if ( QString::compare( layerProperty, QStringLiteral(
"stdev" ), Qt::CaseInsensitive ) == 0 )
5294 else if ( QString::compare( layerProperty, QStringLiteral(
"min" ), Qt::CaseInsensitive ) == 0 )
5296 else if ( QString::compare( layerProperty, QStringLiteral(
"max" ), Qt::CaseInsensitive ) == 0 )
5298 else if ( QString::compare( layerProperty, QStringLiteral(
"range" ), Qt::CaseInsensitive ) == 0 )
5300 else if ( QString::compare( layerProperty, QStringLiteral(
"sum" ), Qt::CaseInsensitive ) == 0 )
5304 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
5334 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5335 bool ascending = values.value( 1 ).toBool();
5336 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
5342 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
5347 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
5352 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
5357 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5358 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5360 for (
const auto &item : listB )
5362 if ( listA.contains( item ) )
5366 return QVariant( match == listB.count() );
5371 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
5376 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5377 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5378 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
5379 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
5380 return list.at( list.length() + pos );
5386 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5387 return list.value( 0 );
5392 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5393 return list.value( list.size() - 1 );
5398 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5399 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
5404 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5405 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
5410 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5413 for (
const QVariant &item : list )
5415 switch ( item.userType() )
5417 case QMetaType::Int:
5418 case QMetaType::UInt:
5419 case QMetaType::LongLong:
5420 case QMetaType::ULongLong:
5421 case QMetaType::Float:
5422 case QMetaType::Double:
5423 total += item.toDouble();
5428 return i == 0 ? QVariant() : total / i;
5433 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5434 QVariantList numbers;
5435 for (
const auto &item : list )
5437 switch ( item.userType() )
5439 case QMetaType::Int:
5440 case QMetaType::UInt:
5441 case QMetaType::LongLong:
5442 case QMetaType::ULongLong:
5443 case QMetaType::Float:
5444 case QMetaType::Double:
5445 numbers.append( item );
5449 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
5450 const int count = numbers.count();
5455 else if ( count % 2 )
5457 return numbers.at( count / 2 );
5461 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
5467 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5470 for (
const QVariant &item : list )
5472 switch ( item.userType() )
5474 case QMetaType::Int:
5475 case QMetaType::UInt:
5476 case QMetaType::LongLong:
5477 case QMetaType::ULongLong:
5478 case QMetaType::Float:
5479 case QMetaType::Double:
5480 total += item.toDouble();
5485 return i == 0 ? QVariant() : total;
5488 static QVariant convertToSameType(
const QVariant &value, QVariant::Type type )
5490 QVariant result = value;
5491 result.convert(
static_cast<int>( type ) );
5497 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5498 QHash< QVariant, int > hash;
5499 for (
const auto &item : list )
5503 const QList< int > occurrences = hash.values();
5504 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
5506 const QString option = values.at( 1 ).toString();
5507 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
5509 return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
5511 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
5513 if ( hash.isEmpty() )
5516 return QVariant( hash.keys( maxValue ).first() );
5518 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
5520 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
5522 else if ( option.compare( QLatin1String(
"real_majority" ), Qt::CaseInsensitive ) == 0 )
5524 if ( maxValue * 2 <= list.size() )
5527 return QVariant( hash.keys( maxValue ).first() );
5538 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5539 QHash< QVariant, int > hash;
5540 for (
const auto &item : list )
5544 const QList< int > occurrences = hash.values();
5545 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
5547 const QString option = values.at( 1 ).toString();
5548 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
5550 return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
5552 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
5554 if ( hash.isEmpty() )
5557 return QVariant( hash.keys( minValue ).first() );
5559 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
5561 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
5563 else if ( option.compare( QLatin1String(
"real_minority" ), Qt::CaseInsensitive ) == 0 )
5565 if ( hash.keys().isEmpty() )
5569 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
5570 if ( maxValue * 2 > list.size() )
5571 hash.remove( hash.key( maxValue ) );
5573 return convertToSameType( hash.keys(), values.at( 0 ).type() );
5584 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5585 list.append( values.at( 1 ) );
5586 return convertToSameType( list, values.at( 0 ).type() );
5591 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5592 list.prepend( values.at( 1 ) );
5593 return convertToSameType( list, values.at( 0 ).type() );
5598 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5599 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
5600 return convertToSameType( list, values.at( 0 ).type() );
5605 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5606 list.removeAt( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5607 return convertToSameType( list, values.at( 0 ).type() );
5612 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5613 list.removeAll( values.at( 1 ) );
5614 return convertToSameType( list, values.at( 0 ).type() );
5619 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
5621 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
5623 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5624 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5626 int index = list.indexOf( it.key() );
5627 while ( index >= 0 )
5629 list.replace( index, it.value() );
5630 index = list.indexOf( it.key() );
5634 return convertToSameType( list, values.at( 0 ).type() );
5636 else if ( values.count() == 3 )
5638 QVariantList before;
5640 bool isSingleReplacement =
false;
5642 if ( values.at( 1 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
5644 before = QVariantList() << values.at( 1 );
5648 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5651 if ( values.at( 2 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
5653 after = QVariantList() << values.at( 2 );
5654 isSingleReplacement =
true;
5658 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
5661 if ( !isSingleReplacement && before.length() != after.length() )
5663 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
5667 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5668 for (
int i = 0; i < before.length(); i++ )
5670 int index = list.indexOf( before.at( i ) );
5671 while ( index >= 0 )
5673 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
5674 index = list.indexOf( before.at( i ) );
5678 return convertToSameType( list, values.at( 0 ).type() );
5682 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
5689 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5690 QVariantList list_new;
5692 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
5694 while ( list.removeOne( cur ) )
5696 list_new.append( cur );
5700 list_new.append( list );
5702 return convertToSameType( list_new, values.at( 0 ).type() );
5708 for (
const QVariant &cur : values )
5710 list += QgsExpressionUtils::getListValue( cur, parent );
5712 return convertToSameType( list, values.at( 0 ).type() );
5717 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5718 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5719 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5720 int slice_length = 0;
5722 if ( start_pos < 0 )
5724 start_pos = list.length() + start_pos;
5728 slice_length = end_pos - start_pos + 1;
5732 slice_length = list.length() + end_pos - start_pos + 1;
5735 if ( slice_length < 0 )
5739 list = list.mid( start_pos, slice_length );
5745 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5746 std::reverse( list.begin(), list.end() );
5752 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5753 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5754 for (
const QVariant &cur : array2 )
5756 if ( array1.contains( cur ) )
5757 return QVariant(
true );
5759 return QVariant(
false );
5764 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5766 QVariantList distinct;
5768 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
5770 if ( !distinct.contains( *it ) )
5772 distinct += ( *it );
5781 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5782 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5783 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5787 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
5789 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
5790 if ( it != ( array.constEnd() - 1 ) )
5796 return QVariant(
str );
5801 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5802 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5803 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5805 QStringList list =
str.split( delimiter );
5808 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
5810 array += ( !( *it ).isEmpty() ) ? *it : empty;
5818 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5819 QJsonDocument document = QJsonDocument::fromJson(
str.toUtf8() );
5820 if ( document.isNull() )
5823 return document.toVariant();
5829 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
5830 return document.toJson( QJsonDocument::Compact );
5835 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5836 if (
str.isEmpty() )
5837 return QVariantMap();
5845 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5852 for (
int i = 0; i + 1 < values.length(); i += 2 )
5854 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
5861 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
5866 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
5871 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5872 map.remove( values.at( 1 ).toString() );
5878 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5879 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
5886 for (
const QVariant &cur : values )
5888 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
5889 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
5890 result.insert( it.key(), it.value() );
5897 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
5902 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
5907 QString envVarName = values.at( 0 ).toString();
5908 return QProcessEnvironment::systemEnvironment().value( envVarName );
5913 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5914 return QFileInfo( file ).completeBaseName();
5919 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5920 return QFileInfo( file ).completeSuffix();
5925 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5926 return QFileInfo::exists( file );
5931 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5932 return QFileInfo( file ).fileName();
5937 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5938 return QFileInfo( file ).isFile();
5943 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5944 return QFileInfo( file ).isDir();
5949 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5950 return QDir::toNativeSeparators( QFileInfo( file ).path() );
5955 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5956 return QFileInfo( file ).size();
5959 static QVariant fcnHash(
const QString
str,
const QCryptographicHash::Algorithm
algorithm )
5961 return QString( QCryptographicHash::hash(
str.toUtf8(),
algorithm ).toHex() );
5967 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5968 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
5970 if ( method == QLatin1String(
"md4" ) )
5972 hash = fcnHash(
str, QCryptographicHash::Md4 );
5974 else if ( method == QLatin1String(
"md5" ) )
5976 hash = fcnHash(
str, QCryptographicHash::Md5 );
5978 else if ( method == QLatin1String(
"sha1" ) )
5980 hash = fcnHash(
str, QCryptographicHash::Sha1 );
5982 else if ( method == QLatin1String(
"sha224" ) )
5984 hash = fcnHash(
str, QCryptographicHash::Sha224 );
5986 else if ( method == QLatin1String(
"sha256" ) )
5988 hash = fcnHash(
str, QCryptographicHash::Sha256 );
5990 else if ( method == QLatin1String(
"sha384" ) )
5992 hash = fcnHash(
str, QCryptographicHash::Sha384 );
5994 else if ( method == QLatin1String(
"sha512" ) )
5996 hash = fcnHash(
str, QCryptographicHash::Sha512 );
5998 else if ( method == QLatin1String(
"sha3_224" ) )
6000 hash = fcnHash(
str, QCryptographicHash::Sha3_224 );
6002 else if ( method == QLatin1String(
"sha3_256" ) )
6004 hash = fcnHash(
str, QCryptographicHash::Sha3_256 );
6006 else if ( method == QLatin1String(
"sha3_384" ) )
6008 hash = fcnHash(
str, QCryptographicHash::Sha3_384 );
6010 else if ( method == QLatin1String(
"sha3_512" ) )
6012 hash = fcnHash(
str, QCryptographicHash::Sha3_512 );
6014 else if ( method == QLatin1String(
"keccak_224" ) )
6016 hash = fcnHash(
str, QCryptographicHash::Keccak_224 );
6018 else if ( method == QLatin1String(
"keccak_256" ) )
6020 hash = fcnHash(
str, QCryptographicHash::Keccak_256 );
6022 else if ( method == QLatin1String(
"keccak_384" ) )
6024 hash = fcnHash(
str, QCryptographicHash::Keccak_384 );
6026 else if ( method == QLatin1String(
"keccak_512" ) )
6028 hash = fcnHash(
str, QCryptographicHash::Keccak_512 );
6032 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg(
str ) );
6039 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
6044 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
6049 const QByteArray input = values.at( 0 ).toByteArray();
6050 return QVariant( QString( input.toBase64() ) );
6055 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6056 const QByteArray base64 = value.toLocal8Bit();
6057 const QByteArray decoded = QByteArray::fromBase64( base64 );
6058 return QVariant( decoded );
6066 const QVariant sourceLayerRef = context->
variable( QStringLiteral(
"layer" ) );
6067 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, parent );
6074 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6077 const bool layerCanBeCached = node->
isStatic( parent, context );
6078 QVariant targetLayerValue = node->
eval( parent, context );
6082 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6084 QString subExpString = node->
dump();
6086 bool testOnly = ( subExpString ==
"NULL" );
6087 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, parent );
6090 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
6095 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6097 QString filterString = node->
dump();
6098 if ( filterString !=
"NULL" )
6104 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
6106 QVariant limitValue = node->
eval( parent, context );
6108 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
6111 double max_distance = 0;
6112 if ( isNearestFunc )
6114 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
6116 QVariant distanceValue = node->
eval( parent, context );
6118 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
6122 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
6124 QVariant cacheValue = node->
eval( parent, context );
6126 bool cacheEnabled = cacheValue.toBool();
6132 if ( sourceLayer && targetLayer->
crs() != sourceLayer->
crs() )
6138 bool sameLayers = ( sourceLayer && sourceLayer->
id() == targetLayer->
id() );
6141 if ( bboxGrow != 0 )
6143 intDomain.
grow( bboxGrow );
6146 const QString cacheBase { QStringLiteral(
"%1:%2" ).arg( targetLayer->
id(), subExpString ) };
6152 QList<QgsFeature> features;
6153 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
6157 const QString cacheLayer { QStringLiteral(
"ovrlaylyr:%1" ).arg( cacheBase ) };
6158 const QString cacheIndex { QStringLiteral(
"ovrlayidx:%1" ).arg( cacheBase ) };
6162 cachedTarget = targetLayer->
materialize( request );
6163 if ( layerCanBeCached )
6164 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
6174 if ( layerCanBeCached )
6175 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
6182 QList<QgsFeatureId> fidsList;
6183 if ( isNearestFunc )
6185 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
6189 fidsList = spatialIndex.
intersects( intDomain );
6192 QListIterator<QgsFeatureId> i( fidsList );
6193 while ( i.hasNext() )
6196 if ( sameLayers && feat.
id() == fId2 )
6198 features.append( cachedTarget->
getFeature( fId2 ) );
6211 if ( sameLayers && feat.
id() == feat2.
id() )
6213 features.append( feat2 );
6221 const QString expCacheKey { QStringLiteral(
"exp:%1" ).arg( cacheBase ) };
6222 const QString ctxCacheKey { QStringLiteral(
"ctx:%1" ).arg( cacheBase ) };
6228 subExpression.
prepare( &subContext );
6240 QVariantList results;
6242 QListIterator<QgsFeature> i( features );
6243 while ( i.hasNext() && ( limit == -1 || foundCount < limit ) )
6247 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
6260 results.append( subExpression.
evaluate( &subContext ) );
6265 results.append( feat2.
id() );
6281 QVariantList disjoint_results;
6288 if ( !results.contains( feat2.
id() ) )
6291 disjoint_results.append( subExpression.
evaluate( &subContext ) );
6294 return disjoint_results;
6337 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
6346 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
6347 static QMutex sFunctionsMutex( QMutex::Recursive );
6348 QMutexLocker locker( &sFunctionsMutex );
6350 static QRecursiveMutex sFunctionsMutex;
6351 QMutexLocker locker( &sFunctionsMutex );
6354 QList<QgsExpressionFunction *> &functions = *sFunctions();
6356 if ( functions.isEmpty() )
6393 functions << randFunc;
6397 functions << randfFunc;
6400 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max" ), -1, fcnMax, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6401 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min" ), -1, fcnMin, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6407 <<
new QgsStaticExpressionFunction( QStringLiteral(
"pi" ), 0, fcnPi, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$pi" ) )
6411 <<
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" ) )
6412 <<
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" ) )
6413 <<
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" ) )
6418 <<
new QgsStaticExpressionFunction( QStringLiteral(
"coalesce" ), -1, fcnCoalesce, QStringLiteral(
"Conditionals" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6432 QStringLiteral(
"Aggregates" ),
6441 if ( !node->
args() )
6444 QSet<QString> referencedVars;
6447 QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
6448 referencedVars = subExpressionNode->referencedVariables();
6453 QgsExpressionNode *filterNode = node->args()->at( 3 );
6454 referencedVars.unite( filterNode->referencedVariables() );
6456 return referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() );
6465 if ( !node->
args() )
6466 return QSet<QString>();
6468 QSet<QString> referencedCols;
6469 QSet<QString> referencedVars;
6484 if ( referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() ) )
6487 return referencedCols;
6500 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count" ), aggParams, fcnAggregateCount, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6501 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6502 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6503 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6504 <<
new QgsStaticExpressionFunction( QStringLiteral(
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6505 <<
new QgsStaticExpressionFunction( QStringLiteral(
"sum" ), aggParams, fcnAggregateSum, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6506 <<
new QgsStaticExpressionFunction( QStringLiteral(
"mean" ), aggParams, fcnAggregateMean, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6507 <<
new QgsStaticExpressionFunction( QStringLiteral(
"median" ), aggParams, fcnAggregateMedian, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6508 <<
new QgsStaticExpressionFunction( QStringLiteral(
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6509 <<
new QgsStaticExpressionFunction( QStringLiteral(
"range" ), aggParams, fcnAggregateRange, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6510 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6511 <<
new QgsStaticExpressionFunction( QStringLiteral(
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6512 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6513 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6514 <<
new QgsStaticExpressionFunction( QStringLiteral(
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6515 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6516 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6517 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6518 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6519 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6520 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6525 <<
new QgsStaticExpressionFunction( QStringLiteral(
"now" ), 0, fcnNow, QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$now" ) )
6528 fcnAge, QStringLiteral(
"Date and Time" ) )
6542 fcnMakeDate, QStringLiteral(
"Date and Time" ) )
6546 fcnMakeTime, QStringLiteral(
"Date and Time" ) )
6553 fcnMakeDateTime, QStringLiteral(
"Date and Time" ) )
6561 fcnMakeInterval, QStringLiteral(
"Date and Time" ) )
6580 false, QSet< QString >(),
false, QStringList(), true )
6581 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concat" ), -1, fcnConcat, QStringLiteral(
"String" ), QString(),
false, QSet<QString>(),
false, QStringList(), true )
6594 fcnColorMixRgb, QStringLiteral(
"Color" ) )
6598 fcnColorRgb, QStringLiteral(
"Color" ) )
6603 fncColorRgba, QStringLiteral(
"Color" ) )
6609 fcnCreateRamp, QStringLiteral(
"Color" ) )
6613 fcnColorHsl, QStringLiteral(
"Color" ) )
6618 fncColorHsla, QStringLiteral(
"Color" ) )
6622 fcnColorHsv, QStringLiteral(
"Color" ) )
6627 fncColorHsva, QStringLiteral(
"Color" ) )
6632 fcnColorCmyk, QStringLiteral(
"Color" ) )
6638 fncColorCmyka, QStringLiteral(
"Color" ) )
6641 fncColorPart, QStringLiteral(
"Color" ) )
6644 fncDarker, QStringLiteral(
"Color" ) )
6647 fncLighter, QStringLiteral(
"Color" ) )
6652 fcnBaseFileName, QStringLiteral(
"Files and Paths" ) )
6654 fcnFileSuffix, QStringLiteral(
"Files and Paths" ) )
6656 fcnFileExists, QStringLiteral(
"Files and Paths" ) )
6658 fcnFileName, QStringLiteral(
"Files and Paths" ) )
6660 fcnPathIsFile, QStringLiteral(
"Files and Paths" ) )
6662 fcnPathIsDir, QStringLiteral(
"Files and Paths" ) )
6664 fcnFilePath, QStringLiteral(
"Files and Paths" ) )
6666 fcnFileSize, QStringLiteral(
"Files and Paths" ) )
6670 fcnGenericHash, QStringLiteral(
"Conversions" ) )
6672 fcnHashMd5, QStringLiteral(
"Conversions" ) )
6674 fcnHashSha256, QStringLiteral(
"Conversions" ) )
6678 fcnToBase64, QStringLiteral(
"Conversions" ) )
6680 fcnFromBase64, QStringLiteral(
"Conversions" ) )
6686 geomFunc->setIsStatic(
false );
6687 functions << geomFunc;
6691 functions << areaFunc;
6697 functions << lengthFunc;
6701 functions << perimeterFunc;
6713 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
6715 { QStringLiteral(
"overlay_intersects" ), fcnGeomOverlayIntersects },
6716 { QStringLiteral(
"overlay_contains" ), fcnGeomOverlayContains },
6717 { QStringLiteral(
"overlay_crosses" ), fcnGeomOverlayCrosses },
6718 { QStringLiteral(
"overlay_equals" ), fcnGeomOverlayEquals },
6719 { QStringLiteral(
"overlay_touches" ), fcnGeomOverlayTouches },
6720 { QStringLiteral(
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
6721 { QStringLiteral(
"overlay_within" ), fcnGeomOverlayWithin },
6723 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
6724 while ( i.hasNext() )
6737 functions << fcnGeomOverlayFunc;
6750 functions << fcnGeomOverlayNearestFunc;
6763 fcnNodesToPoints, QStringLiteral(
"GeometryGroup" ) )
6765 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral(
"GeometryGroup" ) )
6770 fcnMakePointM, QStringLiteral(
"GeometryGroup" ) )
6776 fcnMakeTriangle, QStringLiteral(
"GeometryGroup" ) )
6781 fcnMakeCircle, QStringLiteral(
"GeometryGroup" ) )
6788 fcnMakeEllipse, QStringLiteral(
"GeometryGroup" ) )
6794 fcnMakeRegularPolygon, QStringLiteral(
"GeometryGroup" ) )
6798 fcnMakeSquare, QStringLiteral(
"GeometryGroup" ) )
6804 fcnMakeRectangleFrom3Points, QStringLiteral(
"GeometryGroup" ) );
6807 functions << xAtFunc;
6811 functions << yAtFunc;
6826 fcnDisjoint, QStringLiteral(
"GeometryGroup" ) )
6829 fcnIntersects, QStringLiteral(
"GeometryGroup" ) )
6832 fcnTouches, QStringLiteral(
"GeometryGroup" ) )
6835 fcnCrosses, QStringLiteral(
"GeometryGroup" ) )
6838 fcnContains, QStringLiteral(
"GeometryGroup" ) )
6841 fcnOverlaps, QStringLiteral(
"GeometryGroup" ) )
6844 fcnWithin, QStringLiteral(
"GeometryGroup" ) )
6848 fcnTranslate, QStringLiteral(
"GeometryGroup" ) )
6852 fcnRotate, QStringLiteral(
"GeometryGroup" ) )
6856 fcnBuffer, QStringLiteral(
"GeometryGroup" ) )
6858 fcnForceRHR, QStringLiteral(
"GeometryGroup" ) )
6868 , fcnTaperedBuffer, QStringLiteral(
"GeometryGroup" ) )
6871 , fcnBufferByM, QStringLiteral(
"GeometryGroup" ) )
6877 fcnOffsetCurve, QStringLiteral(
"GeometryGroup" ) )
6883 fcnSingleSidedBuffer, QStringLiteral(
"GeometryGroup" ) )
6887 fcnExtend, QStringLiteral(
"GeometryGroup" ) )
6896 fcnInteriorRingN, QStringLiteral(
"GeometryGroup" ) )
6899 fcnGeometryN, QStringLiteral(
"GeometryGroup" ) )
6922 fcnOrientedBBox, QStringLiteral(
"GeometryGroup" ) )
6925 fcnMainAngle, QStringLiteral(
"GeometryGroup" ) )
6929 fcnMinimalCircle, QStringLiteral(
"GeometryGroup" ) )
6932 fcnDifference, QStringLiteral(
"GeometryGroup" ) )
6935 fcnDistance, QStringLiteral(
"GeometryGroup" ) )
6938 fcnHausdorffDistance, QStringLiteral(
"GeometryGroup" ) )
6941 fcnIntersection, QStringLiteral(
"GeometryGroup" ) )
6944 fcnSymDifference, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"symDifference" ) )
6947 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
6950 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
6953 fcnGeomToWKT, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"geomToWKT" ) )
6955 fcnGeomToWKB, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false )
6960 fcnTransformGeometry, QStringLiteral(
"GeometryGroup" ) )
6964 fcnExtrude, QStringLiteral(
"GeometryGroup" ), QString() )
6966 fcnGeomIsMultipart, QStringLiteral(
"GeometryGroup" ) )
6968 fcnZMax, QStringLiteral(
"GeometryGroup" ) )
6970 fcnZMin, QStringLiteral(
"GeometryGroup" ) )
6972 fcnMMax, QStringLiteral(
"GeometryGroup" ) )
6974 fcnMMin, QStringLiteral(
"GeometryGroup" ) );
6980 fcnOrderParts, QStringLiteral(
"GeometryGroup" ), QString() );
6985 const QList< QgsExpressionNode *> argList = node->
args()->list();
6988 if ( !argNode->isStatic( parent, context ) )
6994 QgsExpressionNode *argNode = node->args()->at( 1 );
6996 QString expString = argNode->eval( parent, context ).toString();
6998 QgsExpression e( expString );
7000 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
7011 QgsExpressionNode *argNode = node->args()->at( 1 );
7012 QString expression = argNode->eval( parent, context ).toString();
7013 QgsExpression e( expression );
7014 e.prepare( context );
7015 context->setCachedValue( expression, QVariant::fromValue( e ) );
7020 functions << orderPartsFunc;
7025 fcnClosestPoint, QStringLiteral(
"GeometryGroup" ) )
7028 fcnShortestLine, QStringLiteral(
"GeometryGroup" ) )
7047 functions << idFunc;
7051 functions << currentFeatureFunc;
7053 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" ) );
7055 functions << uuidFunc;
7061 fcnGetFeature, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"QgsExpressionUtils::getFeature" ) )
7064 fcnGetFeatureById, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false );
7069 functions << attributesFunc;
7072 QStringLiteral(
"maptip" ),
7075 QStringLiteral(
"Record and Attributes" ),
7081 functions << maptipFunc;
7084 QStringLiteral(
"display_expression" ),
7086 fcnFeatureDisplayExpression,
7087 QStringLiteral(
"Record and Attributes" ),
7093 functions << displayFunc;
7096 QStringLiteral(
"is_selected" ),
7099 QStringLiteral(
"Record and Attributes" ),
7105 functions << isSelectedFunc;
7109 QStringLiteral(
"num_selected" ),
7112 QStringLiteral(
"Record and Attributes" ),
7120 QStringLiteral(
"sqlite_fetch_and_increment" ),
7128 fcnSqliteFetchAndIncrement,
7129 QStringLiteral(
"Record and Attributes" )
7147 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
7157 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
7163 functions << representValueFunc;
7169 fcnGetLayerProperty, QStringLiteral(
"Map Layers" ) )
7174 fcnDecodeUri, QStringLiteral(
"Map Layers" ) )
7178 fcnMimeType, QStringLiteral(
"General" ) )
7195 QgsExpressionNode *argNode = node->args()->at( 0 );
7197 if ( !argNode->isStatic( parent, context ) )
7200 QString varName = argNode->eval( parent, context ).toString();
7202 const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
7203 return scope ? scope->isStatic( varName ) : false;
7220 QgsExpressionNode *argNode = node->args()->at( 0 );
7222 if ( argNode->isStatic( parent, context ) )
7224 QString expString = argNode->eval( parent, context ).toString();
7226 QgsExpression e( expString );
7228 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
7236 functions << evalFunc;
7242 const QList< QgsExpressionNode *> argList = node->
args()->list();
7245 if ( !argNode->isStatic( parent, context ) )
7257 functions << attributeFunc;
7267 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array" ), -1, fcnArray, QStringLiteral(
"Arrays" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7320 *sOwnedFunctions() << func;
7321 *sBuiltinFunctions() << func->name();
7322 sBuiltinFunctions()->append( func->aliases() );
7335 sFunctions()->append(
function );
7336 if ( transferOwnership )
7337 sOwnedFunctions()->append(
function );
7351 sFunctions()->removeAt( fnIdx );
7359 qDeleteAll( *sOwnedFunctions() );
7360 sOwnedFunctions()->clear();
7365 if ( sBuiltinFunctions()->isEmpty() )
7369 return *sBuiltinFunctions();
7377 QStringLiteral(
"Arrays" ) )
7388 if ( args->
count() < 2 )
7391 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7401 QVariantList result;
7403 if ( args->
count() < 2 )
7407 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
7410 std::unique_ptr< QgsExpressionContext > tempContext;
7413 tempContext = std::make_unique< QgsExpressionContext >();
7414 subContext = tempContext.get();
7420 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7423 result << args->
at( 1 )->
eval( parent, subContext );
7448 if ( args->
count() < 2 )
7452 args->
at( 0 )->
prepare( parent, context );
7456 subContext = *context;
7462 args->
at( 1 )->
prepare( parent, &subContext );
7472 QStringLiteral(
"Arrays" ) )
7483 if ( args->
count() < 2 )
7486 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7496 QVariantList result;
7498 if ( args->
count() < 2 )
7502 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
7505 std::unique_ptr< QgsExpressionContext > tempContext;
7508 tempContext = std::make_unique< QgsExpressionContext >();
7509 subContext = tempContext.get();
7516 if ( args->
count() >= 3 )
7518 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
7520 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
7522 limit = limitVar.toInt();
7530 for (
const QVariant &value : array )
7533 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
7537 if ( limit > 0 && limit == result.size() )
7564 if ( args->
count() < 2 )
7568 args->
at( 0 )->
prepare( parent, context );
7572 subContext = *context;
7578 args->
at( 1 )->
prepare( parent, &subContext );
7587 QStringLiteral(
"General" ) )
7598 if ( args->
count() < 3 )
7602 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7604 QVariant
name = args->
at( 0 )->
eval( parent, context );
7605 QVariant value = args->
at( 1 )->
eval( parent, context );
7608 appendTemporaryVariable( context,
name.toString(), value );
7609 if ( args->
at( 2 )->
isStatic( parent, context ) )
7611 popTemporaryVariable( context );
7622 if ( args->
count() < 3 )
7626 QVariant
name = args->
at( 0 )->
eval( parent, context );
7627 QVariant value = args->
at( 1 )->
eval( parent, context );
7630 std::unique_ptr< QgsExpressionContext > tempContext;
7631 if ( !updatedContext )
7633 tempContext = std::make_unique< QgsExpressionContext >();
7634 updatedContext = tempContext.get();
7637 appendTemporaryVariable( updatedContext,
name.toString(), value );
7638 result = args->
at( 2 )->
eval( parent, updatedContext );
7641 popTemporaryVariable( updatedContext );
7662 if ( args->
count() < 3 )
7667 QVariant value = args->
at( 1 )->
prepare( parent, context );
7670 std::unique_ptr< QgsExpressionContext > tempContext;
7671 if ( !updatedContext )
7673 tempContext = std::make_unique< QgsExpressionContext >();
7674 updatedContext = tempContext.get();
7677 appendTemporaryVariable( updatedContext,
name.toString(), value );
7678 args->
at( 2 )->
prepare( parent, updatedContext );
7681 popTemporaryVariable( updatedContext );
7686 void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
7692 void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
Abstract base class for all geometries.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
virtual QgsCoordinateSequence coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
virtual int partCount() const =0
Returns count of parts contained in the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Aggregate
Available aggregates to calculate.
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
@ StringMaximumLength
Maximum length of string (string fields only)
@ ThirdQuartile
Third quartile (numeric fields only)
@ Range
Range of values (max - min) (numeric and datetime fields only)
@ ArrayAggregate
Create an array of values.
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only)
@ FirstQuartile
First quartile (numeric fields only)
@ Median
Median of values (numeric fields only)
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
@ CountMissing
Number of missing (null) values.
@ StDevSample
Sample standard deviation of values (numeric fields only)
@ Majority
Majority of values.
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
@ Mean
Mean of values (numeric fields only)
@ StringMinimumLength
Minimum length of string (string fields only)
@ CountDistinct
Number of distinct values.
@ Minority
Minority of values.
static Aggregate stringToAggregate(const QString &string, bool *ok=nullptr)
Converts a string to a aggregate type.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
Handles the array_filter(array, expression) expression function.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QgsArrayFilterExpressionFunction()
Handles the array loopingarray_Foreach(array, expression) expression function.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
QgsArrayForeachExpressionFunction()
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QString authid() const
Returns the authority identifier for the CRS.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
int ringCount(int part=0) const override SIP_HOLDGIL
Returns the number of rings of which this geometry is built.
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
Abstract base class for curved geometry type.
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
double convertAreaMeasurement(double area, QgsUnitTypes::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
double convertLengthMeasurement(double length, QgsUnitTypes::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
Represents a single parameter passed to a function.
A abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
bool operator==(const QgsExpressionFunction &other) const
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
virtual bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
Will be called during prepare to determine if the function is static.
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
bool lazyEval() const
true if this function should use lazy evaluation.
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
QString name() const
The name of the function.
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)=0
Returns result of evaluating the function.
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
virtual bool handlesNull() const
Returns true if the function handles NULL values in arguments by itself, and the default NULL value h...
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
virtual bool usesGeometry(const QgsExpressionNodeFunction *node) const
Does this function use a geometry object.
An expression node which takes it value from a feature's field.
QString name() const
The name of the column.
An expression node for expression functions.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
An expression node for literal values.
A list of expression nodes.
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
int count() const
Returns the number of nodes in the list.
Abstract base class for all nodes that can appear in an expression.
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static const QStringList & BuiltinFunctions()
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
QgsUnitTypes::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
static QString helpText(QString name)
Returns the help text for a specified function.
static bool unregisterFunction(const QString &name)
Unregisters a function from the expression engine.
QgsUnitTypes::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Represents a list of OrderByClauses, with the most important first and the least important last.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsFeatureRequest & setRequestMayBeNested(bool requestMayBeNested)
In case this request may be run nested within another already running iteration on the same connectio...
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setTimeout(int timeout)
Sets the timeout (in milliseconds) for the maximum time we should wait during feature requests before...
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets feature ID that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsVectorLayer * materialize(const QgsFeatureRequest &request, QgsFeedback *feedback=nullptr)
Materializes a request (query) made against this feature source, by running it over the source and re...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
int partCount() const override
Returns count of parts contained in the geometry.
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
A geometry is the spatial representation of a feature.
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
JoinStyle
Join styles for buffers.
@ JoinStyleBevel
Use beveled joins.
@ JoinStyleRound
Use rounded joins.
double lineLocatePoint(const QgsGeometry &point) const
Returns a distance representing the location along this linestring of the closest point on this lines...
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
double length() const
Returns the planar, 2-dimensional length of geometry.
QgsGeometry poleOfInaccessibility(double precision, double *distanceToBoundary=nullptr) const
Calculates the approximate pole of inaccessibility for a surface, which is the most distant internal ...
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsGeometry difference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other.
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
OperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
bool touches(const QgsGeometry &geometry) const
Returns true if the geometry touches another geometry.
QgsGeometry nearestPoint(const QgsGeometry &other) const
Returns the nearest (closest) point on this geometry to another geometry.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
OperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
QgsMultiPointXY asMultiPoint() const
Returns the contents of the geometry as a multi-point.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
@ SideLeft
Buffer to left of line.
bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QgsGeometry combine(const QgsGeometry &geometry) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
bool isGeosValid(QgsGeometry::ValidityFlags flags=QgsGeometry::ValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool equals(const QgsGeometry &geometry) const
Test if this geometry is exactly equal to another geometry.
QgsWkbTypes::GeometryType type
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QString lastError() const SIP_HOLDGIL
Returns an error string referring to the last error encountered either when this geometry was created...
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
QgsGeometry mergeLines() const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsGeometry symDifference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other.
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsGeometry singleSidedBuffer(double distance, int segments, BufferSide side, JoinStyle joinStyle=JoinStyleRound, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry extendLine(double startDistance, double endDistance) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
QgsGeometry offsetCurve(double distance, int segments, JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
QgsGeometry simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
bool overlaps(const QgsGeometry &geometry) const
Returns true if the geometry overlaps another geometry.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Represents a color stop within a QgsGradientColorRamp color ramp.
A representation of the interval between two datetime values.
bool isValid() const
Returns true if the interval is valid.
double days() const
Returns the interval duration in days.
double weeks() const
Returns the interval duration in weeks.
double months() const
Returns the interval duration in months (based on a 30 day month).
double seconds() const
Returns the interval duration in seconds.
double years() const
Returns the interval duration in years (based on an average year length)
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
Line string geometry type, with support for z-dimension and m-values.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QgsLayerMetadata metadata
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
virtual bool isEditable() const
Returns true if the layer can be edited.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
Implementation of GeometrySimplifier using the "MapToPixel" algorithm.
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
double inclination(const QgsPoint &other) const SIP_HOLDGIL
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
bool isValid(QString &error, int flags=0) const override SIP_HOLDGIL
Checks validity of the geometry, and returns true if the geometry is valid.
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Quadrilateral geometry type.
static QgsQuadrilateral squareFromDiagonal(const QgsPoint &p1, const QgsPoint &p2) SIP_HOLDGIL
Construct a QgsQuadrilateral as a square from a diagonal.
QgsPolygon * toPolygon(bool force2D=false) const
Returns the quadrilateral as a new polygon.
ConstructionOption
A quadrilateral can be constructed from 3 points where the second distance can be determined by the t...
@ Distance
Second distance is equal to the distance between 2nd and 3rd point.
@ Projected
Second distance is equal to the distance of the perpendicualr projection of the 3rd point on the segm...
static QgsQuadrilateral rectangleFrom3Points(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, ConstructionOption mode) SIP_HOLDGIL
Construct a QgsQuadrilateral as a Rectangle from 3 points.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
virtual double sample(const QgsPointXY &point, int band, bool *ok=nullptr, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Samples a raster value from the specified band found at the point position.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
Represents a raster layer.
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void grow(double delta)
Grows the rectangle in place by the specified amount.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Regular Polygon geometry type.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices)
QgsPolygon * toPolygon() const
Returns as a polygon.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
c++ helper class for defining QgsExpression functions.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
static QgsStyle * defaultStyle()
Returns default application-wide style.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
This class allows including a set of layers in a database-side transaction, provided the layer data p...
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QString displayExpression
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QVariant aggregate(QgsAggregateCalculator::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters ¶meters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeatureIds *fids=nullptr) const
Calculates an aggregated value from the layer's features.
Handles the with_variable(name, value, node) expression function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QgsWithVariableExpressionFunction()
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
static QString geometryDisplayString(GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
@ PointCloudLayer
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
CORE_EXPORT QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
CORE_EXPORT QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
uint qHash(const QVariant &variant)
Hash for QVariant.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
bool(QgsGeometry::* RelationFunction)(const QgsGeometry &geometry) const
QList< QgsExpressionFunction * > ExpressionFunctionList
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
QLineF segment(int index, QRectF rect, double radius)
A bundle of parameters controlling aggregate calculation.
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
Single variable definition for use within a QgsExpressionContextScope.
The Context struct stores the current layer and coordinate transform context.
const QgsMapLayer * layer
QgsCoordinateTransformContext transformContext
Utility class for identifying a unique vertex within a geometry.