65 #include <QMimeDatabase>
66 #include <QProcessEnvironment>
67 #include <QCryptographicHash>
68 #include <QRegularExpression>
90 QVariantList argValues;
94 const QList< QgsExpressionNode * > argList = args->
list();
101 v = QVariant::fromValue( n );
105 v = n->eval( parent, context );
107 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
108 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
111 argValues.append( v );
116 return func( argValues, context, parent, node );
127 return QStringList();
154 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
159 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
171 const QString &group,
172 const QString &helpText,
176 const QStringList &aliases,
180 , mAliases( aliases )
181 , mUsesGeometry( false )
182 , mUsesGeometryFunc( usesGeometry )
183 , mReferencedColumnsFunc( referencedColumns )
195 if ( mUsesGeometryFunc )
196 return mUsesGeometryFunc( node );
198 return mUsesGeometry;
203 if ( mReferencedColumnsFunc )
204 return mReferencedColumnsFunc( node );
206 return mReferencedColumns;
212 return mIsStaticFunc( node, parent, context );
220 return mPrepareFunc( node, parent, context );
232 mIsStaticFunc =
nullptr;
238 mPrepareFunc = prepareFunc;
243 if ( node && node->
args() )
245 const QList< QgsExpressionNode * > argList = node->
args()->
list();
248 if ( !argNode->isStatic( parent, context ) )
258 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
259 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
260 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
262 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
269 double current = start + step;
270 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
285 QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
291 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
300 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
302 return expression.evaluate( context );
307 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
308 return QVariant( std::sqrt( x ) );
313 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
314 return QVariant( std::fabs( val ) );
319 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
320 return ( deg * M_PI ) / 180;
324 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
325 return ( 180 * rad ) / M_PI;
329 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
330 return QVariant( std::sin( x ) );
334 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
335 return QVariant( std::cos( x ) );
339 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
340 return QVariant( std::tan( x ) );
344 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
345 return QVariant( std::asin( x ) );
349 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
350 return QVariant( std::acos( x ) );
354 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
355 return QVariant( std::atan( x ) );
359 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
360 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
361 return QVariant( std::atan2( y, x ) );
365 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
366 return QVariant( std::exp( x ) );
370 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
373 return QVariant( std::log( x ) );
377 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
380 return QVariant( log10( x ) );
384 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
385 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
386 if ( x <= 0 || b <= 0 )
388 return QVariant( std::log( x ) / std::log( b ) );
392 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
393 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
397 std::random_device rd;
398 std::mt19937_64 generator( rd() );
400 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
403 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
406 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
411 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
412 std::hash<std::string> hasher;
413 seed = hasher( seedStr.toStdString() );
415 generator.seed( seed );
419 double f =
static_cast< double >( generator() ) /
static_cast< double >( generator.max() );
420 return QVariant( min + f * ( max - min ) );
424 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
425 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
429 std::random_device rd;
430 std::mt19937_64 generator( rd() );
432 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
435 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
438 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
443 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
444 std::hash<std::string> hasher;
445 seed = hasher( seedStr.toStdString() );
447 generator.seed( seed );
450 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
451 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
452 return QVariant( randomInteger );
455 return QVariant(
int( randomInteger ) );
460 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
461 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
462 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
463 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
464 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
466 if ( domainMin >= domainMax )
468 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
473 if ( val >= domainMax )
477 else if ( val <= domainMin )
483 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
484 double c = rangeMin - ( domainMin * m );
487 return QVariant( m * val +
c );
492 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
493 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
494 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
495 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
496 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
497 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
499 if ( domainMin >= domainMax )
501 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
511 if ( val >= domainMax )
515 else if ( val <= domainMin )
521 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
526 QVariant result( QVariant::Double );
527 double maxVal = std::numeric_limits<double>::quiet_NaN();
528 for (
const QVariant &val : values )
530 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
531 if ( std::isnan( maxVal ) )
535 else if ( !std::isnan( testVal ) )
537 maxVal = std::max( maxVal, testVal );
541 if ( !std::isnan( maxVal ) )
543 result = QVariant( maxVal );
550 QVariant result( QVariant::Double );
551 double minVal = std::numeric_limits<double>::quiet_NaN();
552 for (
const QVariant &val : values )
554 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
555 if ( std::isnan( minVal ) )
559 else if ( !std::isnan( testVal ) )
561 minVal = std::min( minVal, testVal );
565 if ( !std::isnan( minVal ) )
567 result = QVariant( minVal );
579 QVariant value = node->
eval( parent, context );
581 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, parent );
584 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
589 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
591 value = node->
eval( parent, context );
597 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
602 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
604 QString subExpression = node->
dump();
608 if ( values.count() > 3 )
610 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
613 if ( !nl || nl->value().isValid() )
618 if ( values.count() > 4 )
620 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
622 value = node->
eval( parent, context );
629 if ( values.count() > 5 )
631 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
634 if ( !nl || nl->value().isValid() )
636 orderBy = node->
dump();
641 QString aggregateError;
649 bool isStatic =
true;
650 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
651 || filterExp.referencedVariables().contains( QString() )
652 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
653 || subExp.referencedVariables().contains( QString() ) )
659 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
660 for (
const QString &varName : refVars )
663 if ( scope && !scope->
isStatic( varName ) )
673 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
674 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
678 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
689 subContext.appendScope( subScope );
690 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
702 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
706 if ( !aggregateError.isEmpty() )
707 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
709 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
720 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
725 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
728 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
737 QVariant value = node->
eval( parent, context );
739 QString relationId = value.toString();
746 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
748 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
753 relation = relations.at( 0 );
760 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
762 value = node->
eval( parent, context );
768 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
773 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
775 QString subExpression = node->
dump();
779 if ( values.count() > 3 )
781 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
783 value = node->
eval( parent, context );
790 if ( values.count() > 4 )
792 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
795 if ( !nl || nl->value().isValid() )
797 orderBy = node->
dump();
808 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->
id(),
809 QString::number(
static_cast< int >( aggregate ) ),
822 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
826 if ( !error.isEmpty() )
827 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
829 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
843 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
848 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
851 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
860 QString subExpression = node->
dump();
864 if ( values.count() > 1 )
866 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
869 if ( !nl || nl->value().isValid() )
870 groupBy = node->
dump();
874 if ( values.count() > 2 )
876 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
879 if ( !nl || nl->value().isValid() )
885 if ( orderByPos >= 0 && values.count() > orderByPos )
887 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
890 if ( !nl || nl->value().isValid() )
892 orderBy = node->
dump();
900 if ( !groupBy.isEmpty() )
903 QVariant groupByValue = groupByExp.evaluate( context );
904 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
905 groupByValue.isNull() ? QStringLiteral(
"is" ) : QStringLiteral(
"=" ),
907 if ( !parameters.
filter.isEmpty() )
908 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
910 parameters.
filter = groupByClause;
916 bool isStatic =
true;
917 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
918 for (
const QString &varName : refVars )
921 if ( scope && !scope->
isStatic( varName ) )
931 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter,
932 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
936 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
948 subContext.appendScope( subScope );
950 result = vl->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
954 if ( !error.isEmpty() )
955 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
957 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1062 if ( values.count() > 3 )
1064 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1066 QVariant value = node->
eval( parent, context );
1068 parameters.
delimiter = value.toString();
1079 if ( values.count() > 3 )
1081 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1083 QVariant value = node->
eval( parent, context );
1085 parameters.
delimiter = value.toString();
1101 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1103 if ( !scale.isValid() || scale.isNull() )
1106 const double v = scale.toDouble( &ok );
1114 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1115 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1116 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1119 if ( testValue <= minValue )
1121 return QVariant( minValue );
1123 else if ( testValue >= maxValue )
1125 return QVariant( maxValue );
1129 return QVariant( testValue );
1135 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1136 return QVariant( std::floor( x ) );
1141 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1142 return QVariant( std::ceil( x ) );
1147 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1151 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1155 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1160 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1161 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1162 if ( format.isEmpty() && !language.isEmpty() )
1164 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1165 return QVariant( QDateTime() );
1168 if ( format.isEmpty() && language.isEmpty() )
1169 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1171 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1172 QLocale locale = QLocale();
1173 if ( !language.isEmpty() )
1175 locale = QLocale( language );
1178 QDateTime datetime = locale.toDateTime( datetimestring, format );
1179 if ( !datetime.isValid() )
1181 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1182 datetime = QDateTime();
1184 return QVariant( datetime );
1189 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1190 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1191 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1193 const QDate date( year, month, day );
1194 if ( !date.isValid() )
1196 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1199 return QVariant( date );
1204 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1205 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1206 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1208 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1209 if ( !time.isValid() )
1211 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1214 return QVariant( time );
1219 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1220 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1221 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1222 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1223 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1224 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1226 const QDate date( year, month, day );
1227 if ( !date.isValid() )
1229 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1232 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1233 if ( !time.isValid() )
1235 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1238 return QVariant( QDateTime( date, time ) );
1243 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1244 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1245 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1246 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1247 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1248 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1249 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1251 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1256 for (
const QVariant &value : values )
1258 if ( value.isNull() )
1267 const QVariant val1 = values.at( 0 );
1268 const QVariant val2 = values.at( 1 );
1278 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1279 return QVariant(
str.toLower() );
1283 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1284 return QVariant(
str.toUpper() );
1288 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1289 QStringList elems =
str.split(
' ' );
1290 for (
int i = 0; i < elems.size(); i++ )
1292 if ( elems[i].size() > 1 )
1293 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1295 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1300 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1301 return QVariant(
str.trimmed() );
1306 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1307 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1313 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1314 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1320 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1321 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1328 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1334 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1335 return QVariant( QString( character ) );
1340 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1342 if ( value.isEmpty() )
1347 int res = value.at( 0 ).unicode();
1348 return QVariant( res );
1353 if ( values.length() == 2 || values.length() == 3 )
1355 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1356 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1358 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1372 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1376 return QVariant( geom.
length() );
1380 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1381 return QVariant(
str.length() );
1386 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1391 double totalLength = 0;
1394 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1396 totalLength += line->length3D();
1400 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1401 totalLength += segmentized->length3D();
1410 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1412 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1413 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1414 QVector< QPair< QString, QString > > mapItems;
1416 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1418 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1422 std::sort( mapItems.begin(),
1424 [](
const QPair< QString, QString > &pair1,
1425 const QPair< QString, QString > &pair2 )
1427 return ( pair1.first.length() > pair2.first.length() );
1430 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1432 str =
str.replace( it->first, it->second );
1435 return QVariant(
str );
1437 else if ( values.count() == 3 )
1439 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1440 QVariantList before;
1442 bool isSingleReplacement =
false;
1444 if ( values.at( 1 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
1446 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1450 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1453 if ( values.at( 2 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
1455 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1456 isSingleReplacement =
true;
1460 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1463 if ( !isSingleReplacement && before.length() != after.length() )
1465 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1469 for (
int i = 0; i < before.length(); i++ )
1471 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1474 return QVariant(
str );
1478 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1485 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1486 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1487 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1489 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1490 if ( !re.isValid() )
1492 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1495 return QVariant(
str.replace( re, after ) );
1500 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1501 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1503 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1504 if ( !re.isValid() )
1506 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1509 return QVariant( (
str.indexOf( re ) + 1 ) );
1514 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1515 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1516 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1518 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1519 if ( !re.isValid() )
1521 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1525 QRegularExpressionMatch matches = re.match(
str );
1526 if ( matches.hasMatch() )
1529 QStringList list = matches.capturedTexts();
1532 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1534 array += ( !( *it ).isEmpty() ) ? *it : empty;
1537 return QVariant( array );
1547 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1548 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1550 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1551 if ( !re.isValid() )
1553 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1558 QRegularExpressionMatch match = re.match(
str );
1559 if ( match.hasMatch() )
1562 if ( match.lastCapturedIndex() > 0 )
1565 return QVariant( match.captured( 1 ) );
1570 return QVariant( match.captured( 0 ) );
1575 return QVariant(
"" );
1581 QString uuid = QUuid::createUuid().toString();
1582 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1583 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1584 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1585 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1591 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1594 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1595 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1598 if ( values.at( 2 ).isValid() )
1599 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1605 from =
str.size() + from;
1611 else if ( from > 0 )
1619 len =
str.size() + len - from;
1626 return QVariant(
str.mid( from, len ) );
1632 return QVariant(
static_cast< int >( f.
id() ) );
1637 QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
1640 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1644 int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1645 if ( bandNb < 1 || bandNb > layer->
bandCount() )
1647 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1651 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1654 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1662 if ( multiPoint.count() == 1 )
1664 point = multiPoint[0];
1674 return std::isnan( value ) ? QVariant() : value;
1689 if ( values.size() == 1 )
1691 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1694 else if ( values.size() == 2 )
1696 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1697 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1701 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %1 given." ).arg( values.length() ) );
1711 if ( values.size() == 0 || values.at( 0 ).isNull() )
1717 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1722 for (
int i = 0; i < fields.
count(); ++i )
1733 bool evaluate =
true;
1735 if ( values.isEmpty() )
1738 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1740 else if ( values.size() == 1 )
1742 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1743 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1745 else if ( values.size() == 2 )
1747 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1748 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1750 else if ( values.size() == 3 )
1752 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1753 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1754 evaluate = values.value( 2 ).toBool();
1760 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %1 given." ).arg( values.length() ) );
1764 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %1 given." ).arg( values.length() ) );
1795 subContext.setFeature( feature );
1804 exp.prepare( &subContext );
1805 return exp.evaluate( &subContext ).toString();
1811 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
1816 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
1824 if ( values.isEmpty() )
1827 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1829 else if ( values.size() == 1 )
1831 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1832 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1834 else if ( values.size() == 2 )
1836 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1837 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1841 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %1 given." ).arg( values.length() ) );
1845 if ( !layer || !feature.
isValid() )
1847 return QVariant( QVariant::Bool );
1857 if ( values.isEmpty() )
1858 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1859 else if ( values.count() == 1 )
1860 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1863 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %1 given." ).arg( values.length() ) );
1869 return QVariant( QVariant::LongLong );
1877 static QMap<QString, qlonglong> counterCache;
1878 QVariant functionResult;
1880 std::function<void()> fetchAndIncrementFunc = [ =, &functionResult ]()
1883 const QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1888 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
1889 if ( database.isEmpty() )
1891 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
1896 database = values.at( 0 ).toString();
1899 const QString table = values.at( 1 ).toString();
1900 const QString idColumn = values.at( 2 ).toString();
1901 const QString filterAttribute = values.at( 3 ).toString();
1902 const QVariant filterValue = values.at( 4 ).toString();
1903 const QVariantMap defaultValues = values.at( 5 ).toMap();
1909 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
1912 functionResult = QVariant();
1916 QString errorMessage;
1917 QString currentValSql;
1919 qlonglong nextId = 0;
1920 bool cachedMode =
false;
1921 bool valueRetrieved =
false;
1923 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
1930 auto cachedCounter = counterCache.find( cacheString );
1932 if ( cachedCounter != counterCache.end() )
1934 qlonglong &cachedValue = cachedCounter.value();
1935 nextId = cachedValue;
1937 cachedValue = nextId;
1938 valueRetrieved =
true;
1943 if ( !cachedMode || !valueRetrieved )
1945 int result = SQLITE_ERROR;
1948 if ( !filterAttribute.isNull() )
1953 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
1955 if ( result == SQLITE_OK )
1958 if ( sqliteStatement.
step() == SQLITE_ROW )
1964 if ( cachedMode && result == SQLITE_OK )
1966 counterCache.insert( cacheString, nextId );
1970 counterCache.remove( cacheString );
1973 valueRetrieved =
true;
1977 if ( valueRetrieved )
1986 if ( !filterAttribute.isNull() )
1992 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
1995 vals << iter.value().toString();
1998 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
1999 upsertSql += QLatin1String(
" VALUES " );
2000 upsertSql +=
'(' + vals.join(
',' ) +
')';
2002 int result = SQLITE_ERROR;
2006 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2013 result = sqliteDb.
exec( upsertSql, errorMessage );
2015 if ( result == SQLITE_OK )
2017 functionResult = QVariant( nextId );
2022 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2023 functionResult = QVariant();
2028 functionResult = QVariant();
2033 return functionResult;
2039 for (
const QVariant &value : values )
2041 if ( !value.isNull() )
2042 concat += QgsExpressionUtils::getStringValue( value, parent );
2049 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2050 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2055 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2056 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2057 return string.right( pos );
2062 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2063 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2064 return string.left( pos );
2069 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2070 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2071 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2072 return string.leftJustified( length, fill.at( 0 ),
true );
2077 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2078 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2079 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2080 return string.rightJustified( length, fill.at( 0 ),
true );
2085 if ( values.size() < 1 )
2087 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2091 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2092 for (
int n = 1; n < values.length(); n++ )
2094 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2102 return QVariant( QDateTime::currentDateTime() );
2107 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2108 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2109 if ( format.isEmpty() && !language.isEmpty() )
2111 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2112 return QVariant( QDate() );
2115 if ( format.isEmpty() && language.isEmpty() )
2116 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2118 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2119 QLocale locale = QLocale();
2120 if ( !language.isEmpty() )
2122 locale = QLocale( language );
2125 QDate date = locale.toDate( datestring, format );
2126 if ( !date.isValid() )
2128 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2131 return QVariant( date );
2136 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2137 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2138 if ( format.isEmpty() && !language.isEmpty() )
2140 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2141 return QVariant( QTime() );
2144 if ( format.isEmpty() && language.isEmpty() )
2145 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2147 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2148 QLocale locale = QLocale();
2149 if ( !language.isEmpty() )
2151 locale = QLocale( language );
2154 QTime time = locale.toTime( timestring, format );
2155 if ( !time.isValid() )
2157 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2160 return QVariant( time );
2165 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2174 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2175 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2176 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2178 QString formatString;
2179 if ( values.count() > 3 )
2180 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2182 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2183 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2187 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2191 else if ( ! formatString.isEmpty() )
2193 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2197 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2201 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2207 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2215 return floatToDegreeFormat( format, values, context, parent, node );
2222 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2224 return ok ? QVariant( value ) : QVariant();
2230 return floatToDegreeFormat( format, values, context, parent, node );
2235 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2236 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2237 qint64 seconds = d2.secsTo( d1 );
2238 return QVariant::fromValue(
QgsInterval( seconds ) );
2243 if ( !values.at( 0 ).canConvert<QDate>() )
2246 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2247 if ( !date.isValid() )
2252 return date.dayOfWeek() % 7;
2257 QVariant value = values.at( 0 );
2258 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2261 return QVariant( inter.
days() );
2265 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2266 return QVariant( d1.date().day() );
2272 QVariant value = values.at( 0 );
2273 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2276 return QVariant( inter.
years() );
2280 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2281 return QVariant( d1.date().year() );
2287 QVariant value = values.at( 0 );
2288 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2291 return QVariant( inter.
months() );
2295 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2296 return QVariant( d1.date().month() );
2302 QVariant value = values.at( 0 );
2303 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2306 return QVariant( inter.
weeks() );
2310 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2311 return QVariant( d1.date().weekNumber() );
2317 QVariant value = values.at( 0 );
2318 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2321 return QVariant( inter.
hours() );
2325 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2326 return QVariant( t1.hour() );
2332 QVariant value = values.at( 0 );
2333 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2336 return QVariant( inter.
minutes() );
2340 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2341 return QVariant( t1.minute() );
2347 QVariant value = values.at( 0 );
2348 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2351 return QVariant( inter.
seconds() );
2355 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2356 return QVariant( t1.second() );
2362 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2365 return QVariant( dt.toMSecsSinceEpoch() );
2375 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2377 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2382 QString filepath = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2383 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2389 QString filepath = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2394 #define ENSURE_GEOM_TYPE(f, g, geomtype) \
2395 if ( !(f).hasGeometry() ) \
2396 return QVariant(); \
2397 QgsGeometry g = (f).geometry(); \
2398 if ( (g).type() != (geomtype) ) \
2405 if ( g.isMultipart() )
2407 return g.asMultiPoint().at( 0 ).x();
2411 return g.asPoint().x();
2419 if ( g.isMultipart() )
2421 return g.asMultiPoint().at( 0 ).y();
2425 return g.asPoint().y();
2439 if ( g.isEmpty() || !abGeom->
is3D() )
2444 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2450 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2452 if ( collection->numGeometries() > 0 )
2454 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2465 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2471 return QVariant( isValid );
2476 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2488 QVariant result(
centroid.asPoint().
x() );
2494 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2506 QVariant result(
centroid.asPoint().
y() );
2512 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2522 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2530 if ( collection->numGeometries() == 1 )
2532 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2543 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2553 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2561 if ( collection->numGeometries() == 1 )
2563 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2574 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2579 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2606 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2623 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2640 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2645 bool ignoreClosing =
false;
2646 if ( values.length() > 1 )
2648 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
2658 bool skipLast =
false;
2659 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
2664 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
2676 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2687 for (
int i = 0; i < line->numPoints() - 1; ++i )
2691 << line->pointN( i )
2692 << line->pointN( i + 1 ) );
2703 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2713 if ( collection->numGeometries() == 1 )
2715 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
2720 if ( !curvePolygon )
2724 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2730 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
2736 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2746 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2752 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
2758 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2767 return QVariant::fromValue(
QgsGeometry( boundary ) );
2772 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2781 return QVariant::fromValue( merged );
2786 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2791 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2794 if ( simplified.
isNull() )
2802 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2807 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2812 if ( simplified.
isNull() )
2820 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2825 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
2826 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
2827 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2828 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
2830 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
2840 if ( values.size() == 1 && ( values.at( 0 ).type() == QVariant::List || values.at( 0 ).type() == QVariant::StringList ) )
2842 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
2849 QVector< QgsGeometry > parts;
2850 parts.reserve( list.size() );
2851 for (
const QVariant &value : std::as_const( list ) )
2869 if ( values.count() < 2 || values.count() > 4 )
2871 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
2875 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2876 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2877 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
2878 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
2879 switch ( values.count() )
2893 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2894 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2895 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2901 if ( values.empty() )
2906 QVector<QgsPoint> points;
2907 points.reserve( values.count() );
2909 auto addPoint = [&points](
const QgsGeometry & geom )
2917 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2924 for (
const QVariant &value : values )
2926 if ( value.type() == QVariant::List )
2928 const QVariantList list = value.toList();
2929 for (
const QVariant &v : list )
2931 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
2936 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
2940 if ( points.count() < 2 )
2948 if ( values.count() < 1 )
2950 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
2954 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2962 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
2964 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
2971 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
2976 if ( !exteriorRing )
2979 polygon->setExteriorRing( exteriorRing->
segmentize() );
2982 for (
int i = 1; i < values.count(); ++i )
2984 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
2991 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
2998 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3006 polygon->addInteriorRing( ring->
segmentize() );
3009 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3014 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3015 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3016 lineString->clear();
3018 for (
const QVariant &value : values )
3020 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3027 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3034 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3042 lineString->addVertex( *point );
3045 tr->setExteriorRing( lineString.release() );
3047 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3052 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3059 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3060 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3067 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3074 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3082 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3087 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3094 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3095 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3096 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3097 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3103 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3110 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3117 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3118 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3124 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3131 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3138 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3141 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3148 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3152 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3159 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3166 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3173 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3188 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3194 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3200 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3201 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3209 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3215 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3221 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3230 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3233 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3234 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3235 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
3243 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
3259 return QVariant( QPointF( p.
x(), p.
y() ) );
3264 QVariant v = pointAt( values, f, parent );
3265 if ( v.type() == QVariant::PointF )
3266 return QVariant( v.toPointF().x() );
3272 QVariant v = pointAt( values, f, parent );
3273 if ( v.type() == QVariant::PointF )
3274 return QVariant( v.toPointF().y() );
3283 return QVariant::fromValue( geom );
3290 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3292 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3298 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
3304 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3309 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3316 ogcContext.
layer = mapLayerPtr.data();
3317 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
3321 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3334 return QVariant( area );
3338 return QVariant( f.geometry().area() );
3344 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3349 return QVariant( geom.
area() );
3361 return QVariant( len );
3365 return QVariant( f.geometry().length() );
3378 return QVariant( len );
3382 return f.geometry().isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
3388 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3394 return QVariant( geom.
length() );
3399 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3405 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3414 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3423 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3438 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
3439 if ( !curvePolygon )
3451 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3458 return QVariant( curvePolygon->
ringCount() );
3460 bool foundPoly =
false;
3468 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
3469 if ( !curvePolygon )
3480 return QVariant( ringCount );
3485 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3487 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
3493 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3499 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3505 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3514 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3520 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3526 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3532 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3538 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3546 double max = std::numeric_limits< double >::lowest();
3550 double z = ( *it ).z();
3556 if ( max == std::numeric_limits< double >::lowest() )
3557 return QVariant( QVariant::Double );
3559 return QVariant( max );
3564 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3572 double min = std::numeric_limits< double >::max();
3576 double z = ( *it ).z();
3582 if ( min == std::numeric_limits< double >::max() )
3583 return QVariant( QVariant::Double );
3585 return QVariant( min );
3590 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3598 double min = std::numeric_limits< double >::max();
3602 double m = ( *it ).m();
3608 if ( min == std::numeric_limits< double >::max() )
3609 return QVariant( QVariant::Double );
3611 return QVariant( min );
3616 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3624 double max = std::numeric_limits< double >::lowest();
3628 double m = ( *it ).m();
3634 if ( max == std::numeric_limits< double >::lowest() )
3635 return QVariant( QVariant::Double );
3637 return QVariant( max );
3642 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3643 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
3646 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
3655 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3659 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
3670 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3674 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
3676 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
3681 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3685 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
3692 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
3700 return QVariant::fromValue( curve->
isClosed() );
3705 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3718 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
3719 closedLine->close();
3721 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
3731 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
3733 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
3734 closedLine->close();
3736 closed->addGeometry( closedLine.release() );
3739 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
3747 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3751 return QVariant::fromValue( fGeom.
isEmpty() );
3756 if ( values.at( 0 ).isNull() )
3757 return QVariant::fromValue(
true );
3759 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3760 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
3765 if ( values.length() < 2 || values.length() > 3 )
3768 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3769 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3776 if ( values.length() == 2 )
3779 QString result = engine->relate( sGeom.
constGet() );
3780 return QVariant::fromValue( result );
3785 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
3786 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
3787 return QVariant::fromValue( result );
3793 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3794 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3799 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3800 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3801 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
3805 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3806 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3807 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
3811 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3812 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3813 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
3817 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3818 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3819 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
3823 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3824 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3825 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
3829 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3830 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3831 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
3835 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3836 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3837 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
3842 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3843 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3844 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3845 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3846 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3847 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3850 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
3851 capStyle = Qgis::EndCapStyle::Flat;
3852 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
3853 capStyle = Qgis::EndCapStyle::Square;
3856 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
3857 joinStyle = Qgis::JoinStyle::Miter;
3858 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
3859 joinStyle = Qgis::JoinStyle::Bevel;
3862 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3868 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3870 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
3875 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3876 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
3883 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3890 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
3894 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3895 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3896 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3897 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3900 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3906 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3909 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
3913 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3914 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3915 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
3918 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3924 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3927 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
3931 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
3934 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3940 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3941 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3942 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3943 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3944 if ( joinInt < 1 || joinInt > 3 )
3948 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3951 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3957 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3958 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3959 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3961 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3962 if ( joinInt < 1 || joinInt > 3 )
3966 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3969 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3975 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3976 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3977 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3980 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3986 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3987 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3988 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3990 return QVariant::fromValue( fGeom );
3995 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3996 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3997 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4008 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4014 if ( multiPoint.count() == 1 )
4020 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4029 fGeom.
rotate( rotation, pt );
4030 return QVariant::fromValue( fGeom );
4035 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4041 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4042 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4044 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4046 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4047 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4049 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
4050 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
4051 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
4052 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
4063 QTransform transform;
4064 transform.translate( deltaX, deltaY );
4065 transform.rotate( rotationZ );
4066 transform.scale( scaleX, scaleY );
4067 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
4069 return QVariant::fromValue( fGeom );
4075 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4077 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4082 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4084 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4090 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4091 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4093 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4099 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4101 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4108 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4110 if ( values.length() == 2 )
4111 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4119 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4125 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4127 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4133 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4139 double area,
angle, width, height;
4152 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4153 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4155 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4161 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4168 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
4173 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
4181 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
4183 reversed->addGeometry( curve->
reversed() );
4190 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
4197 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4208 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
4217 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
4223 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4224 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4225 return QVariant( fGeom.
distance( sGeom ) );
4230 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4231 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4234 if ( values.length() == 3 && values.at( 2 ).isValid() )
4236 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4237 densify = std::clamp( densify, 0.0, 1.0 );
4245 return res > -1 ? QVariant( res ) : QVariant();
4250 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4251 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4253 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4258 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4259 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4261 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4266 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4267 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4269 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4275 if ( values.length() < 1 || values.length() > 2 )
4278 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4280 if ( values.length() == 2 )
4281 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4282 QString wkt = fGeom.
asWkt( prec );
4283 return QVariant( wkt );
4288 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4289 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
4294 if ( values.length() != 2 )
4296 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %1 given." ).arg( values.length() ) );
4300 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4301 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4303 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4310 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4315 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4322 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4329 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
4336 if ( pt1->
y() < pt2->
y() )
4338 else if ( pt1->
y() > pt2->
y() )
4346 if ( pt1->
x() < pt2->
x() )
4348 else if ( pt1->
x() > pt2->
x() )
4349 return M_PI + ( M_PI_2 );
4354 if ( pt1->
x() < pt2->
x() )
4356 if ( pt1->
y() < pt2->
y() )
4358 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
4362 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4369 if ( pt1->
y() > pt2->
y() )
4371 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
4376 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4377 + ( M_PI + ( M_PI_2 ) );
4384 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4388 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
4392 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4393 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4394 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4397 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
4404 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4405 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4407 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4414 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4418 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4425 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4433 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
4443 if ( values.length() != 3 )
4446 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4447 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4448 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4452 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
4458 if ( values.length() < 2 )
4461 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4464 return values.at( 0 );
4466 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4467 QVariant cachedExpression;
4472 if ( cachedExpression.isValid() )
4479 bool asc = values.value( 2 ).toBool();
4497 Q_ASSERT( collection );
4501 QgsExpressionSorter sorter( orderBy );
4503 QList<QgsFeature> partFeatures;
4504 partFeatures.reserve( collection->
partCount() );
4505 for (
int i = 0; i < collection->
partCount(); ++i )
4511 sorter.sortFeatures( partFeatures, unconstedContext );
4515 Q_ASSERT( orderedGeom );
4520 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
4525 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
4528 delete unconstedContext;
4535 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4536 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4540 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4546 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4547 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4551 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4557 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4558 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4562 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4568 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4571 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
4577 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
4584 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4591 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4592 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4594 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
4596 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
4601 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4602 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4609 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4610 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4615 vertex = count + vertex;
4623 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4624 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4629 vertex = count + vertex;
4637 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4638 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4642 return distance >= 0 ? distance : QVariant();
4647 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
4649 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4650 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
4653 if ( values.length() >= 1 )
4655 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4656 return QVariant( qlonglong( std::round( number ) ) );
4671 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
4672 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4673 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4680 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
4681 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
4682 return locale.toString( value,
'f', places );
4687 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
4688 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4689 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4691 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
4692 return locale.toString( datetime, format );
4698 int avg = ( color.red() + color.green() + color.blue() ) / 3;
4699 int alpha = color.alpha();
4701 color.setRgb( avg, avg, avg, alpha );
4710 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4715 else if ( ratio < 0 )
4720 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
4721 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
4722 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
4723 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
4725 QColor newColor( red, green, blue, alpha );
4732 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4733 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4734 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4735 QColor color = QColor( red, green, blue );
4736 if ( ! color.isValid() )
4738 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
4739 color = QColor( 0, 0, 0 );
4742 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4747 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
4748 QVariant value = node->
eval( parent, context );
4752 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
4754 value = node->
eval( parent, context );
4762 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
4764 QVariant value = node->
eval( parent, context );
4766 if ( value.toBool() )
4768 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
4770 value = node->
eval( parent, context );
4775 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
4777 value = node->
eval( parent, context );
4785 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
4786 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4787 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4788 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
4789 QColor color = QColor( red, green, blue, alpha );
4790 if ( ! color.isValid() )
4792 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
4793 color = QColor( 0, 0, 0 );
4804 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
4809 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
4813 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
4818 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4819 QColor color = ramp->
color( value );
4826 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4828 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4830 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4832 QColor color = QColor::fromHslF( hue, saturation, lightness );
4834 if ( ! color.isValid() )
4836 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
4837 color = QColor( 0, 0, 0 );
4840 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4846 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4848 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4850 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4852 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
4854 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
4855 if ( ! color.isValid() )
4857 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
4858 color = QColor( 0, 0, 0 );
4866 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4868 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4870 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4872 QColor color = QColor::fromHsvF( hue, saturation, value );
4874 if ( ! color.isValid() )
4876 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
4877 color = QColor( 0, 0, 0 );
4880 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4886 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
4888 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4890 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4892 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
4894 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
4895 if ( ! color.isValid() )
4897 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
4898 color = QColor( 0, 0, 0 );
4906 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
4908 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4910 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4912 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
4914 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
4916 if ( ! color.isValid() )
4918 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
4919 color = QColor( 0, 0, 0 );
4922 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
4928 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
4930 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
4932 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
4934 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
4936 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
4938 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
4939 if ( ! color.isValid() )
4941 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
4942 color = QColor( 0, 0, 0 );
4950 if ( ! color.isValid() )
4952 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
4956 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4957 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
4959 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
4960 return color.green();
4961 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
4962 return color.blue();
4963 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
4964 return color.alpha();
4965 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
4966 return color.hsvHueF() * 360;
4967 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
4968 return color.hsvSaturationF() * 100;
4969 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
4970 return color.valueF() * 100;
4971 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
4972 return color.hslHueF() * 360;
4973 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
4974 return color.hslSaturationF() * 100;
4975 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
4976 return color.lightnessF() * 100;
4977 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
4978 return color.cyanF() * 100;
4979 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
4980 return color.magentaF() * 100;
4981 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
4982 return color.yellowF() * 100;
4983 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
4984 return color.blackF() * 100;
4986 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
4992 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
4993 if ( map.count() < 1 )
4995 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
4999 QList< QColor > colors;
5001 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5004 if ( !colors.last().isValid() )
5006 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
5010 double step = it.key().toDouble();
5011 if ( it == map.constBegin() )
5016 else if ( it == map.constEnd() )
5026 bool discrete = values.at( 1 ).toBool();
5028 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
5034 if ( ! color.isValid() )
5036 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5040 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5041 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5042 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5043 color.setRed( value );
5044 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5045 color.setGreen( value );
5046 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5047 color.setBlue( value );
5048 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5049 color.setAlpha( value );
5050 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5051 color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
5052 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5053 color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
5054 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5055 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
5056 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5057 color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
5058 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5059 color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
5060 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5061 color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
5062 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5063 color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
5064 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5065 color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
5066 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5067 color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
5068 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5069 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
5072 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5081 if ( ! color.isValid() )
5083 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5087 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5095 if ( ! color.isValid() )
5097 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5101 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5108 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
5111 return QVariant::fromValue( geom );
5117 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5118 QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5119 QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5123 return QVariant::fromValue( fGeom );
5126 return QVariant::fromValue( fGeom );
5135 return QVariant::fromValue( fGeom );
5149 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
5152 QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
5164 result = QVariant::fromValue( fet );
5174 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), parent );
5177 if ( !featureSource )
5182 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5183 int attributeId = featureSource->fields().lookupField( attribute );
5184 if ( attributeId == -1 )
5189 const QVariant &attVal = values.at( 2 );
5191 const QString cacheValueKey = QStringLiteral(
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
5215 res = QVariant::fromValue( fet );
5230 if ( !values.isEmpty() )
5233 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
5234 fieldName = col->
name();
5235 else if ( values.size() == 2 )
5236 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5239 QVariant value = values.at( 0 );
5244 if ( fieldIndex == -1 )
5246 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5250 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
5252 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName, value.toString() );
5261 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName );
5272 result =
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
5279 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5287 const QVariant data = values.at( 0 );
5288 const QMimeDatabase db;
5289 return db.mimeTypeForData( data.toByteArray() ).name();
5294 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5300 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5301 if ( QString::compare( layerProperty, QStringLiteral(
"name" ), Qt::CaseInsensitive ) == 0 )
5302 return layer->
name();
5303 else if ( QString::compare( layerProperty, QStringLiteral(
"id" ), Qt::CaseInsensitive ) == 0 )
5305 else if ( QString::compare( layerProperty, QStringLiteral(
"title" ), Qt::CaseInsensitive ) == 0 )
5307 else if ( QString::compare( layerProperty, QStringLiteral(
"abstract" ), Qt::CaseInsensitive ) == 0 )
5309 else if ( QString::compare( layerProperty, QStringLiteral(
"keywords" ), Qt::CaseInsensitive ) == 0 )
5311 QStringList keywords;
5313 for (
auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
5315 keywords.append( it.value() );
5317 if ( !keywords.isEmpty() )
5321 else if ( QString::compare( layerProperty, QStringLiteral(
"data_url" ), Qt::CaseInsensitive ) == 0 )
5323 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution" ), Qt::CaseInsensitive ) == 0 )
5327 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
5329 else if ( QString::compare( layerProperty, QStringLiteral(
"source" ), Qt::CaseInsensitive ) == 0 )
5331 else if ( QString::compare( layerProperty, QStringLiteral(
"min_scale" ), Qt::CaseInsensitive ) == 0 )
5333 else if ( QString::compare( layerProperty, QStringLiteral(
"max_scale" ), Qt::CaseInsensitive ) == 0 )
5335 else if ( QString::compare( layerProperty, QStringLiteral(
"is_editable" ), Qt::CaseInsensitive ) == 0 )
5337 else if ( QString::compare( layerProperty, QStringLiteral(
"crs" ), Qt::CaseInsensitive ) == 0 )
5339 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
5341 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_description" ), Qt::CaseInsensitive ) == 0 )
5343 else if ( QString::compare( layerProperty, QStringLiteral(
"extent" ), Qt::CaseInsensitive ) == 0 )
5346 QVariant result = QVariant::fromValue( extentGeom );
5349 else if ( QString::compare( layerProperty, QStringLiteral(
"distance_units" ), Qt::CaseInsensitive ) == 0 )
5351 else if ( QString::compare( layerProperty, QStringLiteral(
"type" ), Qt::CaseInsensitive ) == 0 )
5353 switch ( layer->
type() )
5356 return QCoreApplication::translate(
"expressions",
"Vector" );
5358 return QCoreApplication::translate(
"expressions",
"Raster" );
5360 return QCoreApplication::translate(
"expressions",
"Mesh" );
5362 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
5364 return QCoreApplication::translate(
"expressions",
"Plugin" );
5366 return QCoreApplication::translate(
"expressions",
"Annotation" );
5368 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
5374 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
5377 if ( QString::compare( layerProperty, QStringLiteral(
"storage_type" ), Qt::CaseInsensitive ) == 0 )
5379 else if ( QString::compare( layerProperty, QStringLiteral(
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
5381 else if ( QString::compare( layerProperty, QStringLiteral(
"feature_count" ), Qt::CaseInsensitive ) == 0 )
5383 else if ( QString::compare( layerProperty, QStringLiteral(
"path" ), Qt::CaseInsensitive ) == 0 )
5388 return decodedUri.value( QStringLiteral(
"path" ) );
5399 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5402 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
5412 const QString uriPart = values.at( 1 ).toString();
5416 if ( !uriPart.isNull() )
5418 return decodedUri.value( values.at( 1 ).toString() );
5428 QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5435 if ( !layersByName.isEmpty() )
5437 layer = layersByName.at( 0 );
5448 int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5449 if ( band < 1 || band > rl->
bandCount() )
5451 parent->
setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer %2" ).arg( band ).arg( layerIdOrName ) );
5455 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5458 if ( QString::compare( layerProperty, QStringLiteral(
"avg" ), Qt::CaseInsensitive ) == 0 )
5460 else if ( QString::compare( layerProperty, QStringLiteral(
"stdev" ), Qt::CaseInsensitive ) == 0 )
5462 else if ( QString::compare( layerProperty, QStringLiteral(
"min" ), Qt::CaseInsensitive ) == 0 )
5464 else if ( QString::compare( layerProperty, QStringLiteral(
"max" ), Qt::CaseInsensitive ) == 0 )
5466 else if ( QString::compare( layerProperty, QStringLiteral(
"range" ), Qt::CaseInsensitive ) == 0 )
5468 else if ( QString::compare( layerProperty, QStringLiteral(
"sum" ), Qt::CaseInsensitive ) == 0 )
5472 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
5502 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5503 bool ascending = values.value( 1 ).toBool();
5504 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
5510 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
5515 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
5520 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
5525 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5526 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5528 for (
const auto &item : listB )
5530 if ( listA.contains( item ) )
5534 return QVariant( match == listB.count() );
5539 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
5544 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5545 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5546 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
5547 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
5548 return list.at( list.length() + pos );
5554 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5555 return list.value( 0 );
5560 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5561 return list.value( list.size() - 1 );
5566 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5567 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
5572 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5573 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
5578 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5581 for (
const QVariant &item : list )
5583 switch ( item.userType() )
5585 case QMetaType::Int:
5586 case QMetaType::UInt:
5587 case QMetaType::LongLong:
5588 case QMetaType::ULongLong:
5589 case QMetaType::Float:
5590 case QMetaType::Double:
5591 total += item.toDouble();
5596 return i == 0 ? QVariant() : total / i;
5601 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5602 QVariantList numbers;
5603 for (
const auto &item : list )
5605 switch ( item.userType() )
5607 case QMetaType::Int:
5608 case QMetaType::UInt:
5609 case QMetaType::LongLong:
5610 case QMetaType::ULongLong:
5611 case QMetaType::Float:
5612 case QMetaType::Double:
5613 numbers.append( item );
5617 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
5618 const int count = numbers.count();
5623 else if ( count % 2 )
5625 return numbers.at( count / 2 );
5629 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
5635 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5638 for (
const QVariant &item : list )
5640 switch ( item.userType() )
5642 case QMetaType::Int:
5643 case QMetaType::UInt:
5644 case QMetaType::LongLong:
5645 case QMetaType::ULongLong:
5646 case QMetaType::Float:
5647 case QMetaType::Double:
5648 total += item.toDouble();
5653 return i == 0 ? QVariant() : total;
5656 static QVariant convertToSameType(
const QVariant &value, QVariant::Type type )
5658 QVariant result = value;
5659 result.convert(
static_cast<int>( type ) );
5665 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5666 QHash< QVariant, int > hash;
5667 for (
const auto &item : list )
5671 const QList< int > occurrences = hash.values();
5672 if ( occurrences.empty() )
5673 return QVariantList();
5675 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
5677 const QString option = values.at( 1 ).toString();
5678 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
5680 return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
5682 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
5684 if ( hash.isEmpty() )
5687 return QVariant( hash.keys( maxValue ).first() );
5689 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
5691 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
5693 else if ( option.compare( QLatin1String(
"real_majority" ), Qt::CaseInsensitive ) == 0 )
5695 if ( maxValue * 2 <= list.size() )
5698 return QVariant( hash.keys( maxValue ).first() );
5709 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5710 QHash< QVariant, int > hash;
5711 for (
const auto &item : list )
5715 const QList< int > occurrences = hash.values();
5716 if ( occurrences.empty() )
5717 return QVariantList();
5719 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
5721 const QString option = values.at( 1 ).toString();
5722 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
5724 return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
5726 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
5728 if ( hash.isEmpty() )
5731 return QVariant( hash.keys( minValue ).first() );
5733 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
5735 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
5737 else if ( option.compare( QLatin1String(
"real_minority" ), Qt::CaseInsensitive ) == 0 )
5739 if ( hash.keys().isEmpty() )
5743 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
5744 if ( maxValue * 2 > list.size() )
5745 hash.remove( hash.key( maxValue ) );
5747 return convertToSameType( hash.keys(), values.at( 0 ).type() );
5758 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5759 list.append( values.at( 1 ) );
5760 return convertToSameType( list, values.at( 0 ).type() );
5765 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5766 list.prepend( values.at( 1 ) );
5767 return convertToSameType( list, values.at( 0 ).type() );
5772 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5773 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
5774 return convertToSameType( list, values.at( 0 ).type() );
5779 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5780 list.removeAt( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5781 return convertToSameType( list, values.at( 0 ).type() );
5786 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5787 list.removeAll( values.at( 1 ) );
5788 return convertToSameType( list, values.at( 0 ).type() );
5793 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
5795 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
5797 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5798 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5800 int index = list.indexOf( it.key() );
5801 while ( index >= 0 )
5803 list.replace( index, it.value() );
5804 index = list.indexOf( it.key() );
5808 return convertToSameType( list, values.at( 0 ).type() );
5810 else if ( values.count() == 3 )
5812 QVariantList before;
5814 bool isSingleReplacement =
false;
5816 if ( values.at( 1 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
5818 before = QVariantList() << values.at( 1 );
5822 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5825 if ( values.at( 2 ).type() != QVariant::List && values.at( 2 ).type() != QVariant::StringList )
5827 after = QVariantList() << values.at( 2 );
5828 isSingleReplacement =
true;
5832 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
5835 if ( !isSingleReplacement && before.length() != after.length() )
5837 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
5841 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5842 for (
int i = 0; i < before.length(); i++ )
5844 int index = list.indexOf( before.at( i ) );
5845 while ( index >= 0 )
5847 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
5848 index = list.indexOf( before.at( i ) );
5852 return convertToSameType( list, values.at( 0 ).type() );
5856 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
5863 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5864 QVariantList list_new;
5866 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
5868 while ( list.removeOne( cur ) )
5870 list_new.append( cur );
5874 list_new.append( list );
5876 return convertToSameType( list_new, values.at( 0 ).type() );
5882 for (
const QVariant &cur : values )
5884 list += QgsExpressionUtils::getListValue( cur, parent );
5886 return convertToSameType( list, values.at( 0 ).type() );
5891 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5892 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5893 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5894 int slice_length = 0;
5896 if ( start_pos < 0 )
5898 start_pos = list.length() + start_pos;
5902 slice_length = end_pos - start_pos + 1;
5906 slice_length = list.length() + end_pos - start_pos + 1;
5909 if ( slice_length < 0 )
5913 list = list.mid( start_pos, slice_length );
5919 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5920 std::reverse( list.begin(), list.end() );
5926 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5927 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5928 for (
const QVariant &cur : array2 )
5930 if ( array1.contains( cur ) )
5931 return QVariant(
true );
5933 return QVariant(
false );
5938 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5940 QVariantList distinct;
5942 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
5944 if ( !distinct.contains( *it ) )
5946 distinct += ( *it );
5955 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5956 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5957 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5961 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
5963 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
5964 if ( it != ( array.constEnd() - 1 ) )
5970 return QVariant(
str );
5975 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5976 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5977 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5979 QStringList list =
str.split( delimiter );
5982 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
5984 array += ( !( *it ).isEmpty() ) ? *it : empty;
5992 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5993 QJsonDocument document = QJsonDocument::fromJson(
str.toUtf8() );
5994 if ( document.isNull() )
5997 return document.toVariant();
6003 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
6004 return document.toJson( QJsonDocument::Compact );
6009 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6010 if (
str.isEmpty() )
6011 return QVariantMap();
6019 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6026 for (
int i = 0; i + 1 < values.length(); i += 2 )
6028 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
6035 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
6040 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
6045 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6046 map.remove( values.at( 1 ).toString() );
6052 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6053 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
6060 for (
const QVariant &cur : values )
6062 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
6063 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
6064 result.insert( it.key(), it.value() );
6071 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
6076 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
6081 QString envVarName = values.at( 0 ).toString();
6082 return QProcessEnvironment::systemEnvironment().value( envVarName );
6087 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6088 return QFileInfo( file ).completeBaseName();
6093 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6094 return QFileInfo( file ).completeSuffix();
6099 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6100 return QFileInfo::exists( file );
6105 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6106 return QFileInfo( file ).fileName();
6111 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6112 return QFileInfo( file ).isFile();
6117 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6118 return QFileInfo( file ).isDir();
6123 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6124 return QDir::toNativeSeparators( QFileInfo( file ).path() );
6129 const QString file = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6130 return QFileInfo( file ).size();
6133 static QVariant fcnHash(
const QString
str,
const QCryptographicHash::Algorithm
algorithm )
6135 return QString( QCryptographicHash::hash(
str.toUtf8(),
algorithm ).toHex() );
6141 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6142 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
6144 if ( method == QLatin1String(
"md4" ) )
6146 hash = fcnHash(
str, QCryptographicHash::Md4 );
6148 else if ( method == QLatin1String(
"md5" ) )
6150 hash = fcnHash(
str, QCryptographicHash::Md5 );
6152 else if ( method == QLatin1String(
"sha1" ) )
6154 hash = fcnHash(
str, QCryptographicHash::Sha1 );
6156 else if ( method == QLatin1String(
"sha224" ) )
6158 hash = fcnHash(
str, QCryptographicHash::Sha224 );
6160 else if ( method == QLatin1String(
"sha256" ) )
6162 hash = fcnHash(
str, QCryptographicHash::Sha256 );
6164 else if ( method == QLatin1String(
"sha384" ) )
6166 hash = fcnHash(
str, QCryptographicHash::Sha384 );
6168 else if ( method == QLatin1String(
"sha512" ) )
6170 hash = fcnHash(
str, QCryptographicHash::Sha512 );
6172 else if ( method == QLatin1String(
"sha3_224" ) )
6174 hash = fcnHash(
str, QCryptographicHash::Sha3_224 );
6176 else if ( method == QLatin1String(
"sha3_256" ) )
6178 hash = fcnHash(
str, QCryptographicHash::Sha3_256 );
6180 else if ( method == QLatin1String(
"sha3_384" ) )
6182 hash = fcnHash(
str, QCryptographicHash::Sha3_384 );
6184 else if ( method == QLatin1String(
"sha3_512" ) )
6186 hash = fcnHash(
str, QCryptographicHash::Sha3_512 );
6188 else if ( method == QLatin1String(
"keccak_224" ) )
6190 hash = fcnHash(
str, QCryptographicHash::Keccak_224 );
6192 else if ( method == QLatin1String(
"keccak_256" ) )
6194 hash = fcnHash(
str, QCryptographicHash::Keccak_256 );
6196 else if ( method == QLatin1String(
"keccak_384" ) )
6198 hash = fcnHash(
str, QCryptographicHash::Keccak_384 );
6200 else if ( method == QLatin1String(
"keccak_512" ) )
6202 hash = fcnHash(
str, QCryptographicHash::Keccak_512 );
6206 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg(
str ) );
6213 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
6218 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
6223 const QByteArray input = values.at( 0 ).toByteArray();
6224 return QVariant( QString( input.toBase64() ) );
6229 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6230 const QByteArray base64 = value.toLocal8Bit();
6231 const QByteArray decoded = QByteArray::fromBase64( base64 );
6232 return QVariant( decoded );
6240 const QVariant sourceLayerRef = context->
variable( QStringLiteral(
"layer" ) );
6241 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, parent );
6249 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6252 const bool layerCanBeCached = node->
isStatic( parent, context );
6253 QVariant targetLayerValue = node->
eval( parent, context );
6257 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6259 QString subExpString = node->
dump();
6261 bool testOnly = ( subExpString ==
"NULL" );
6262 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, parent );
6265 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
6270 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6272 QString filterString = node->
dump();
6273 if ( filterString !=
"NULL" )
6279 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
6281 QVariant limitValue = node->
eval( parent, context );
6283 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
6286 double max_distance = 0;
6287 if ( isNearestFunc )
6289 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
6291 QVariant distanceValue = node->
eval( parent, context );
6293 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
6297 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
6299 QVariant cacheValue = node->
eval( parent, context );
6301 bool cacheEnabled = cacheValue.toBool();
6307 if ( sourceLayer && targetLayer->
crs() != sourceLayer->
crs() )
6313 bool sameLayers = ( sourceLayer && sourceLayer->
id() == targetLayer->
id() );
6316 if ( bboxGrow != 0 )
6318 intDomain.
grow( bboxGrow );
6321 const QString cacheBase { QStringLiteral(
"%1:%2:%3" ).arg( targetLayer->
id(), subExpString, filterString ) };
6327 QList<QgsFeature> features;
6328 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
6332 const QString cacheLayer { QStringLiteral(
"ovrlaylyr:%1" ).arg( cacheBase ) };
6333 const QString cacheIndex { QStringLiteral(
"ovrlayidx:%1" ).arg( cacheBase ) };
6337 cachedTarget = targetLayer->
materialize( request );
6338 if ( layerCanBeCached )
6339 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
6349 if ( layerCanBeCached )
6350 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
6357 QList<QgsFeatureId> fidsList;
6358 if ( isNearestFunc )
6360 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
6364 fidsList = spatialIndex.
intersects( intDomain );
6367 QListIterator<QgsFeatureId> i( fidsList );
6368 while ( i.hasNext() )
6371 if ( sameLayers && feat.
id() == fId2 )
6373 features.append( cachedTarget->
getFeature( fId2 ) );
6386 if ( sameLayers && feat.
id() == feat2.
id() )
6388 features.append( feat2 );
6396 const QString expCacheKey { QStringLiteral(
"exp:%1" ).arg( cacheBase ) };
6397 const QString ctxCacheKey { QStringLiteral(
"ctx:%1" ).arg( cacheBase ) };
6403 subExpression.
prepare( &subContext );
6415 QVariantList results;
6417 QListIterator<QgsFeature> i( features );
6418 while ( i.hasNext() && ( limit == -1 || foundCount < limit ) )
6422 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
6435 results.append( subExpression.
evaluate( &subContext ) );
6440 results.append( feat2.
id() );
6456 QVariantList disjoint_results;
6465 if ( !results.contains( feat2.
id() ) )
6468 disjoint_results.append( subExpression.
evaluate( &subContext ) );
6471 return disjoint_results;
6514 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
6523 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
6524 static QMutex sFunctionsMutex( QMutex::Recursive );
6525 QMutexLocker locker( &sFunctionsMutex );
6527 static QRecursiveMutex sFunctionsMutex;
6528 QMutexLocker locker( &sFunctionsMutex );
6531 QList<QgsExpressionFunction *> &functions = *sFunctions();
6533 if ( functions.isEmpty() )
6570 functions << randFunc;
6574 functions << randfFunc;
6577 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max" ), -1, fcnMax, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6578 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min" ), -1, fcnMin, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6584 <<
new QgsStaticExpressionFunction( QStringLiteral(
"pi" ), 0, fcnPi, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$pi" ) )
6588 <<
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" ) )
6589 <<
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" ) )
6590 <<
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" ) )
6595 <<
new QgsStaticExpressionFunction( QStringLiteral(
"coalesce" ), -1, fcnCoalesce, QStringLiteral(
"Conditionals" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
6609 QStringLiteral(
"Aggregates" ),
6618 if ( !node->
args() )
6621 QSet<QString> referencedVars;
6624 QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
6625 referencedVars = subExpressionNode->referencedVariables();
6630 QgsExpressionNode *filterNode = node->args()->at( 3 );
6631 referencedVars.unite( filterNode->referencedVariables() );
6633 return referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() );
6642 if ( !node->
args() )
6643 return QSet<QString>();
6645 QSet<QString> referencedCols;
6646 QSet<QString> referencedVars;
6661 if ( referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() ) )
6664 return referencedCols;
6677 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count" ), aggParams, fcnAggregateCount, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6678 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6679 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6680 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6681 <<
new QgsStaticExpressionFunction( QStringLiteral(
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6682 <<
new QgsStaticExpressionFunction( QStringLiteral(
"sum" ), aggParams, fcnAggregateSum, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6683 <<
new QgsStaticExpressionFunction( QStringLiteral(
"mean" ), aggParams, fcnAggregateMean, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6684 <<
new QgsStaticExpressionFunction( QStringLiteral(
"median" ), aggParams, fcnAggregateMedian, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6685 <<
new QgsStaticExpressionFunction( QStringLiteral(
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6686 <<
new QgsStaticExpressionFunction( QStringLiteral(
"range" ), aggParams, fcnAggregateRange, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6687 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6688 <<
new QgsStaticExpressionFunction( QStringLiteral(
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6689 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6690 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6691 <<
new QgsStaticExpressionFunction( QStringLiteral(
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6692 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6693 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6694 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6695 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6696 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6697 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
6702 <<
new QgsStaticExpressionFunction( QStringLiteral(
"now" ), 0, fcnNow, QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$now" ) )
6705 fcnAge, QStringLiteral(
"Date and Time" ) )
6719 fcnMakeDate, QStringLiteral(
"Date and Time" ) )
6723 fcnMakeTime, QStringLiteral(
"Date and Time" ) )
6730 fcnMakeDateTime, QStringLiteral(
"Date and Time" ) )
6738 fcnMakeInterval, QStringLiteral(
"Date and Time" ) )
6757 false, QSet< QString >(),
false, QStringList(), true )
6758 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concat" ), -1, fcnConcat, QStringLiteral(
"String" ), QString(),
false, QSet<QString>(),
false, QStringList(), true )
6771 fcnColorMixRgb, QStringLiteral(
"Color" ) )
6775 fcnColorRgb, QStringLiteral(
"Color" ) )
6780 fncColorRgba, QStringLiteral(
"Color" ) )
6786 fcnCreateRamp, QStringLiteral(
"Color" ) )
6790 fcnColorHsl, QStringLiteral(
"Color" ) )
6795 fncColorHsla, QStringLiteral(
"Color" ) )
6799 fcnColorHsv, QStringLiteral(
"Color" ) )
6804 fncColorHsva, QStringLiteral(
"Color" ) )
6809 fcnColorCmyk, QStringLiteral(
"Color" ) )
6815 fncColorCmyka, QStringLiteral(
"Color" ) )
6818 fncColorPart, QStringLiteral(
"Color" ) )
6821 fncDarker, QStringLiteral(
"Color" ) )
6824 fncLighter, QStringLiteral(
"Color" ) )
6829 fcnBaseFileName, QStringLiteral(
"Files and Paths" ) )
6831 fcnFileSuffix, QStringLiteral(
"Files and Paths" ) )
6833 fcnFileExists, QStringLiteral(
"Files and Paths" ) )
6835 fcnFileName, QStringLiteral(
"Files and Paths" ) )
6837 fcnPathIsFile, QStringLiteral(
"Files and Paths" ) )
6839 fcnPathIsDir, QStringLiteral(
"Files and Paths" ) )
6841 fcnFilePath, QStringLiteral(
"Files and Paths" ) )
6843 fcnFileSize, QStringLiteral(
"Files and Paths" ) )
6846 fcnExif, QStringLiteral(
"Files and Paths" ) )
6848 fcnExifGeoTag, QStringLiteral(
"GeometryGroup" ) )
6852 fcnGenericHash, QStringLiteral(
"Conversions" ) )
6854 fcnHashMd5, QStringLiteral(
"Conversions" ) )
6856 fcnHashSha256, QStringLiteral(
"Conversions" ) )
6860 fcnToBase64, QStringLiteral(
"Conversions" ) )
6862 fcnFromBase64, QStringLiteral(
"Conversions" ) )
6868 geomFunc->setIsStatic(
false );
6869 functions << geomFunc;
6873 functions << areaFunc;
6879 functions << lengthFunc;
6883 functions << perimeterFunc;
6899 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
6901 { QStringLiteral(
"overlay_intersects" ), fcnGeomOverlayIntersects },
6902 { QStringLiteral(
"overlay_contains" ), fcnGeomOverlayContains },
6903 { QStringLiteral(
"overlay_crosses" ), fcnGeomOverlayCrosses },
6904 { QStringLiteral(
"overlay_equals" ), fcnGeomOverlayEquals },
6905 { QStringLiteral(
"overlay_touches" ), fcnGeomOverlayTouches },
6906 { QStringLiteral(
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
6907 { QStringLiteral(
"overlay_within" ), fcnGeomOverlayWithin },
6909 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
6910 while ( i.hasNext() )
6923 functions << fcnGeomOverlayFunc;
6936 functions << fcnGeomOverlayNearestFunc;
6949 fcnNodesToPoints, QStringLiteral(
"GeometryGroup" ) )
6951 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral(
"GeometryGroup" ) )
6956 fcnMakePointM, QStringLiteral(
"GeometryGroup" ) )
6962 fcnMakeTriangle, QStringLiteral(
"GeometryGroup" ) )
6967 fcnMakeCircle, QStringLiteral(
"GeometryGroup" ) )
6974 fcnMakeEllipse, QStringLiteral(
"GeometryGroup" ) )
6980 fcnMakeRegularPolygon, QStringLiteral(
"GeometryGroup" ) )
6984 fcnMakeSquare, QStringLiteral(
"GeometryGroup" ) )
6990 fcnMakeRectangleFrom3Points, QStringLiteral(
"GeometryGroup" ) );
6993 functions << xAtFunc;
6997 functions << yAtFunc;
7013 fcnDisjoint, QStringLiteral(
"GeometryGroup" ) )
7016 fcnIntersects, QStringLiteral(
"GeometryGroup" ) )
7019 fcnTouches, QStringLiteral(
"GeometryGroup" ) )
7022 fcnCrosses, QStringLiteral(
"GeometryGroup" ) )
7025 fcnContains, QStringLiteral(
"GeometryGroup" ) )
7028 fcnOverlaps, QStringLiteral(
"GeometryGroup" ) )
7031 fcnWithin, QStringLiteral(
"GeometryGroup" ) )
7035 fcnTranslate, QStringLiteral(
"GeometryGroup" ) )
7039 fcnRotate, QStringLiteral(
"GeometryGroup" ) )
7050 fcnAffineTransform, QStringLiteral(
"GeometryGroup" ) )
7057 fcnBuffer, QStringLiteral(
"GeometryGroup" ) )
7059 fcnForceRHR, QStringLiteral(
"GeometryGroup" ) )
7069 , fcnTaperedBuffer, QStringLiteral(
"GeometryGroup" ) )
7072 , fcnBufferByM, QStringLiteral(
"GeometryGroup" ) )
7078 fcnOffsetCurve, QStringLiteral(
"GeometryGroup" ) )
7084 fcnSingleSidedBuffer, QStringLiteral(
"GeometryGroup" ) )
7088 fcnExtend, QStringLiteral(
"GeometryGroup" ) )
7097 fcnInteriorRingN, QStringLiteral(
"GeometryGroup" ) )
7100 fcnGeometryN, QStringLiteral(
"GeometryGroup" ) )
7123 fcnOrientedBBox, QStringLiteral(
"GeometryGroup" ) )
7126 fcnMainAngle, QStringLiteral(
"GeometryGroup" ) )
7130 fcnMinimalCircle, QStringLiteral(
"GeometryGroup" ) )
7133 fcnDifference, QStringLiteral(
"GeometryGroup" ) )
7136 fcnDistance, QStringLiteral(
"GeometryGroup" ) )
7139 fcnHausdorffDistance, QStringLiteral(
"GeometryGroup" ) )
7142 fcnIntersection, QStringLiteral(
"GeometryGroup" ) )
7145 fcnSymDifference, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"symDifference" ) )
7148 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
7151 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
7154 fcnGeomToWKT, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"geomToWKT" ) )
7156 fcnGeomToWKB, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false )
7161 fcnTransformGeometry, QStringLiteral(
"GeometryGroup" ) )
7165 fcnExtrude, QStringLiteral(
"GeometryGroup" ), QString() )
7167 fcnGeomIsMultipart, QStringLiteral(
"GeometryGroup" ) )
7169 fcnZMax, QStringLiteral(
"GeometryGroup" ) )
7171 fcnZMin, QStringLiteral(
"GeometryGroup" ) )
7173 fcnMMax, QStringLiteral(
"GeometryGroup" ) )
7175 fcnMMin, QStringLiteral(
"GeometryGroup" ) )
7177 fcnSinuosity, QStringLiteral(
"GeometryGroup" ) )
7179 fcnStraightDistance2d, QStringLiteral(
"GeometryGroup" ) );
7185 fcnOrderParts, QStringLiteral(
"GeometryGroup" ), QString() );
7190 const QList< QgsExpressionNode *> argList = node->
args()->list();
7193 if ( !argNode->isStatic( parent, context ) )
7199 QgsExpressionNode *argNode = node->args()->at( 1 );
7201 QString expString = argNode->eval( parent, context ).toString();
7203 QgsExpression e( expString );
7205 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
7216 QgsExpressionNode *argNode = node->args()->at( 1 );
7217 QString expression = argNode->eval( parent, context ).toString();
7218 QgsExpression e( expression );
7219 e.prepare( context );
7220 context->setCachedValue( expression, QVariant::fromValue( e ) );
7225 functions << orderPartsFunc;
7230 fcnClosestPoint, QStringLiteral(
"GeometryGroup" ) )
7233 fcnShortestLine, QStringLiteral(
"GeometryGroup" ) )
7252 functions << idFunc;
7256 functions << currentFeatureFunc;
7258 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" ) );
7260 functions << uuidFunc;
7266 fcnGetFeature, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"QgsExpressionUtils::getFeature" ) )
7269 fcnGetFeatureById, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false );
7274 functions << attributesFunc;
7277 QStringLiteral(
"maptip" ),
7280 QStringLiteral(
"Record and Attributes" ),
7286 functions << maptipFunc;
7289 QStringLiteral(
"display_expression" ),
7291 fcnFeatureDisplayExpression,
7292 QStringLiteral(
"Record and Attributes" ),
7298 functions << displayFunc;
7301 QStringLiteral(
"is_selected" ),
7304 QStringLiteral(
"Record and Attributes" ),
7310 functions << isSelectedFunc;
7314 QStringLiteral(
"num_selected" ),
7317 QStringLiteral(
"Record and Attributes" ),
7325 QStringLiteral(
"sqlite_fetch_and_increment" ),
7333 fcnSqliteFetchAndIncrement,
7334 QStringLiteral(
"Record and Attributes" )
7352 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
7362 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
7368 functions << representValueFunc;
7374 fcnGetLayerProperty, QStringLiteral(
"Map Layers" ) )
7379 fcnDecodeUri, QStringLiteral(
"Map Layers" ) )
7383 fcnMimeType, QStringLiteral(
"General" ) )
7400 QgsExpressionNode *argNode = node->args()->at( 0 );
7402 if ( !argNode->isStatic( parent, context ) )
7405 QString varName = argNode->eval( parent, context ).toString();
7407 const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
7408 return scope ? scope->isStatic( varName ) : false;
7425 QgsExpressionNode *argNode = node->args()->at( 0 );
7427 if ( argNode->isStatic( parent, context ) )
7429 QString expString = argNode->eval( parent, context ).toString();
7431 QgsExpression e( expString );
7433 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
7441 functions << evalFunc;
7447 const QList< QgsExpressionNode *> argList = node->
args()->list();
7450 if ( !argNode->isStatic( parent, context ) )
7462 functions << attributeFunc;
7472 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array" ), -1, fcnArray, QStringLiteral(
"Arrays" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7525 *sOwnedFunctions() << func;
7526 *sBuiltinFunctions() << func->name();
7527 sBuiltinFunctions()->append( func->aliases() );
7540 sFunctions()->append(
function );
7541 if ( transferOwnership )
7542 sOwnedFunctions()->append(
function );
7556 sFunctions()->removeAt( fnIdx );
7564 qDeleteAll( *sOwnedFunctions() );
7565 sOwnedFunctions()->clear();
7570 if ( sBuiltinFunctions()->isEmpty() )
7574 return *sBuiltinFunctions();
7582 QStringLiteral(
"Arrays" ) )
7593 if ( args->
count() < 2 )
7596 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7606 QVariantList result;
7608 if ( args->
count() < 2 )
7612 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
7615 std::unique_ptr< QgsExpressionContext > tempContext;
7618 tempContext = std::make_unique< QgsExpressionContext >();
7619 subContext = tempContext.get();
7625 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
7628 result << args->
at( 1 )->
eval( parent, subContext );
7653 if ( args->
count() < 2 )
7657 args->
at( 0 )->
prepare( parent, context );
7661 subContext = *context;
7667 args->
at( 1 )->
prepare( parent, &subContext );
7677 QStringLiteral(
"Arrays" ) )
7688 if ( args->
count() < 2 )
7691 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7701 QVariantList result;
7703 if ( args->
count() < 2 )
7707 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
7710 std::unique_ptr< QgsExpressionContext > tempContext;
7713 tempContext = std::make_unique< QgsExpressionContext >();
7714 subContext = tempContext.get();
7721 if ( args->
count() >= 3 )
7723 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
7725 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
7727 limit = limitVar.toInt();
7735 for (
const QVariant &value : array )
7738 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
7742 if ( limit > 0 && limit == result.size() )
7769 if ( args->
count() < 2 )
7773 args->
at( 0 )->
prepare( parent, context );
7777 subContext = *context;
7783 args->
at( 1 )->
prepare( parent, &subContext );
7792 QStringLiteral(
"General" ) )
7803 if ( args->
count() < 3 )
7807 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
7809 QVariant
name = args->
at( 0 )->
eval( parent, context );
7810 QVariant value = args->
at( 1 )->
eval( parent, context );
7813 appendTemporaryVariable( context,
name.toString(), value );
7814 if ( args->
at( 2 )->
isStatic( parent, context ) )
7816 popTemporaryVariable( context );
7827 if ( args->
count() < 3 )
7831 QVariant
name = args->
at( 0 )->
eval( parent, context );
7832 QVariant value = args->
at( 1 )->
eval( parent, context );
7835 std::unique_ptr< QgsExpressionContext > tempContext;
7836 if ( !updatedContext )
7838 tempContext = std::make_unique< QgsExpressionContext >();
7839 updatedContext = tempContext.get();
7842 appendTemporaryVariable( updatedContext,
name.toString(), value );
7843 result = args->
at( 2 )->
eval( parent, updatedContext );
7846 popTemporaryVariable( updatedContext );
7867 if ( args->
count() < 3 )
7872 QVariant value = args->
at( 1 )->
prepare( parent, context );
7875 std::unique_ptr< QgsExpressionContext > tempContext;
7876 if ( !updatedContext )
7878 tempContext = std::make_unique< QgsExpressionContext >();
7879 updatedContext = tempContext.get();
7882 appendTemporaryVariable( updatedContext,
name.toString(), value );
7883 args->
at( 2 )->
prepare( parent, updatedContext );
7886 popTemporaryVariable( updatedContext );
7891 void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
7897 void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
@ Success
Operation succeeded.
JoinStyle
Join styles for buffers.
EndCapStyle
End cap styles for buffers.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
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 bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
virtual const QgsAbstractGeometry * simplifiedTypeRef() const SIP_HOLDGIL
Returns a reference to the simplest lossless representation of this geometry, e.g.
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.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of 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.
double sinuosity() const
Returns the curve sinuosity, which is the ratio of the curve length() to curve straightDistance2d().
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.
double straightDistance2d() const
Returns the straight distance of the curve, i.e.
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.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
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.
A set of expression-related functions.
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.
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the iterator to check if it should be cance...
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the 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.
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 offsetCurve(double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
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.
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.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
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.
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.
QgsGeometry singleSidedBuffer(double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle=Qgis::JoinStyle::Round, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
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.
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.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
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.
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 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.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
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.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override SIP_HOLDGIL
Checks validity of the geometry, and returns true if the geometry is valid.
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 ...
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 perpendicular 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, QgsFeedback *feedback=nullptr, QString *error=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.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB 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.
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
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.