67#include <QMimeDatabase>
68#include <QProcessEnvironment>
69#include <QCryptographicHash>
70#include <QRegularExpression>
93 QVariantList argValues;
97 const QList< QgsExpressionNode * > argList = args->
list();
104 v = QVariant::fromValue( n );
108 v = n->eval( parent, context );
110 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
111 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
114 argValues.append( v );
119 return func( argValues, context, parent, node );
130 return QStringList();
157 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
162 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
174 const QString &group,
175 const QString &helpText,
179 const QStringList &aliases,
183 , mAliases( aliases )
184 , mUsesGeometry( false )
185 , mUsesGeometryFunc( usesGeometry )
186 , mReferencedColumnsFunc( referencedColumns )
198 if ( mUsesGeometryFunc )
199 return mUsesGeometryFunc( node );
201 return mUsesGeometry;
206 if ( mReferencedColumnsFunc )
207 return mReferencedColumnsFunc( node );
209 return mReferencedColumns;
215 return mIsStaticFunc( node, parent, context );
223 return mPrepareFunc( node, parent, context );
235 mIsStaticFunc =
nullptr;
241 mPrepareFunc = prepareFunc;
246 if ( node && node->
args() )
248 const QList< QgsExpressionNode * > argList = node->
args()->
list();
251 if ( !argNode->isStatic( parent, context ) )
261 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
262 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
263 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
265 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
272 double current = start + step;
273 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
288 const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
290 if ( name == QLatin1String(
"feature" ) )
292 return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
294 else if ( name == QLatin1String(
"id" ) )
296 return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
298 else if ( name == QLatin1String(
"geometry" ) )
314 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
323 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
325 return expression.evaluate( context );
330 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
331 return QVariant( std::sqrt( x ) );
336 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
337 return QVariant( std::fabs( val ) );
342 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return ( deg * M_PI ) / 180;
347 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
348 return ( 180 * rad ) / M_PI;
352 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
353 return QVariant( std::sin( x ) );
357 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
358 return QVariant( std::cos( x ) );
362 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
363 return QVariant( std::tan( x ) );
367 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
368 return QVariant( std::asin( x ) );
372 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
373 return QVariant( std::acos( x ) );
377 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
378 return QVariant( std::atan( x ) );
382 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
383 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
384 return QVariant( std::atan2( y, x ) );
388 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
389 return QVariant( std::exp( x ) );
393 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
396 return QVariant( std::log( x ) );
400 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
403 return QVariant( log10( x ) );
407 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
408 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
409 if ( x <= 0 || b <= 0 )
411 return QVariant( std::log( x ) / std::log( b ) );
415 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
416 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
420 std::random_device rd;
421 std::mt19937_64 generator( rd() );
423 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
426 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
429 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
434 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
435 std::hash<std::string> hasher;
436 seed = hasher( seedStr.toStdString() );
438 generator.seed( seed );
442 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
443 return QVariant( min + f * ( max - min ) );
447 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
448 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
452 std::random_device rd;
453 std::mt19937_64 generator( rd() );
455 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
458 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
461 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
466 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
467 std::hash<std::string> hasher;
468 seed = hasher( seedStr.toStdString() );
470 generator.seed( seed );
473 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
474 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
475 return QVariant( randomInteger );
478 return QVariant(
int( randomInteger ) );
483 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
484 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
485 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
486 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
487 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
489 if ( domainMin >= domainMax )
491 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
496 if ( val >= domainMax )
500 else if ( val <= domainMin )
506 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
507 double c = rangeMin - ( domainMin * m );
510 return QVariant( m * val +
c );
515 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
516 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
517 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
518 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
519 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
520 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
522 if ( domainMin >= domainMax )
524 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
534 if ( val >= domainMax )
538 else if ( val <= domainMin )
544 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
549 QVariant result( QVariant::Double );
550 double maxVal = std::numeric_limits<double>::quiet_NaN();
551 for (
const QVariant &val : values )
554 if ( std::isnan( maxVal ) )
558 else if ( !std::isnan( testVal ) )
560 maxVal = std::max( maxVal, testVal );
564 if ( !std::isnan( maxVal ) )
566 result = QVariant( maxVal );
573 QVariant result( QVariant::Double );
574 double minVal = std::numeric_limits<double>::quiet_NaN();
575 for (
const QVariant &val : values )
578 if ( std::isnan( minVal ) )
582 else if ( !std::isnan( testVal ) )
584 minVal = std::min( minVal, testVal );
588 if ( !std::isnan( minVal ) )
590 result = QVariant( minVal );
602 QVariant value = node->
eval( parent, context );
604 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, parent );
607 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
612 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
614 value = node->
eval( parent, context );
620 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
625 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
627 QString subExpression = node->
dump();
631 if ( values.count() > 3 )
633 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
636 if ( !nl || nl->value().isValid() )
641 if ( values.count() > 4 )
643 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
645 value = node->
eval( parent, context );
652 if ( values.count() > 5 )
654 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
657 if ( !nl || nl->value().isValid() )
659 orderBy = node->
dump();
664 QString aggregateError;
672 bool isStatic =
true;
673 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
674 || filterExp.referencedVariables().contains( QString() )
675 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
676 || subExp.referencedVariables().contains( QString() ) )
682 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
683 for (
const QString &varName : refVars )
686 if ( scope && !scope->
isStatic( varName ) )
696 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
697 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
701 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
712 subContext.appendScope( subScope );
713 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
725 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
729 if ( !aggregateError.isEmpty() )
730 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
732 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
743 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
748 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
751 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
760 QVariant value = node->
eval( parent, context );
762 QString relationId = value.toString();
769 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
771 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
776 relation = relations.at( 0 );
783 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
785 value = node->
eval( parent, context );
791 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
796 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
798 QString subExpression = node->
dump();
802 if ( values.count() > 3 )
804 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
806 value = node->
eval( parent, context );
813 if ( values.count() > 4 )
815 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
818 if ( !nl || nl->value().isValid() )
820 orderBy = node->
dump();
831 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->
id(),
832 QString::number(
static_cast< int >( aggregate ) ),
845 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
849 if ( !error.isEmpty() )
850 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
852 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
866 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
871 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
874 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
883 QString subExpression = node->
dump();
887 if ( values.count() > 1 )
889 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
892 if ( !nl || nl->value().isValid() )
893 groupBy = node->
dump();
897 if ( values.count() > 2 )
899 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
902 if ( !nl || nl->value().isValid() )
908 if ( orderByPos >= 0 && values.count() > orderByPos )
910 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
913 if ( !nl || nl->value().isValid() )
915 orderBy = node->
dump();
923 if ( !groupBy.isEmpty() )
926 QVariant groupByValue = groupByExp.evaluate( context );
927 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
930 if ( !parameters.
filter.isEmpty() )
931 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
933 parameters.
filter = groupByClause;
939 bool isStatic =
true;
940 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
941 for (
const QString &varName : refVars )
944 if ( scope && !scope->
isStatic( varName ) )
954 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter,
955 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
959 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
971 subContext.appendScope( subScope );
973 result = vl->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
977 if ( !error.isEmpty() )
978 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
980 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1085 if ( values.count() > 3 )
1087 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1089 QVariant value = node->
eval( parent, context );
1091 parameters.
delimiter = value.toString();
1102 if ( values.count() > 3 )
1104 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1106 QVariant value = node->
eval( parent, context );
1108 parameters.
delimiter = value.toString();
1124 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1129 const double v = scale.toDouble( &ok );
1137 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1138 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1139 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1142 if ( testValue <= minValue )
1144 return QVariant( minValue );
1146 else if ( testValue >= maxValue )
1148 return QVariant( maxValue );
1152 return QVariant( testValue );
1158 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1159 return QVariant( std::floor( x ) );
1164 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1165 return QVariant( std::ceil( x ) );
1170 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1174 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1178 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1183 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1184 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1185 if ( format.isEmpty() && !language.isEmpty() )
1187 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1188 return QVariant( QDateTime() );
1191 if ( format.isEmpty() && language.isEmpty() )
1192 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1194 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1195 QLocale locale = QLocale();
1196 if ( !language.isEmpty() )
1198 locale = QLocale( language );
1201 QDateTime datetime = locale.toDateTime( datetimestring, format );
1202 if ( !datetime.isValid() )
1204 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1205 datetime = QDateTime();
1207 return QVariant( datetime );
1212 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1213 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1214 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1216 const QDate date( year, month, day );
1217 if ( !date.isValid() )
1219 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1222 return QVariant( date );
1227 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1228 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1229 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1231 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1232 if ( !time.isValid() )
1234 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1237 return QVariant( time );
1242 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1243 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1244 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1245 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1246 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1247 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1249 const QDate date( year, month, day );
1250 if ( !date.isValid() )
1252 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1255 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1256 if ( !time.isValid() )
1258 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1261 return QVariant( QDateTime( date, time ) );
1266 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1267 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1268 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1269 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1270 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1271 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1272 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1274 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1279 for (
const QVariant &value : values )
1290 const QVariant val1 = values.at( 0 );
1291 const QVariant val2 = values.at( 1 );
1301 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1302 return QVariant(
str.toLower() );
1306 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1307 return QVariant(
str.toUpper() );
1311 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1312 QStringList elems =
str.split(
' ' );
1313 for (
int i = 0; i < elems.size(); i++ )
1315 if ( elems[i].size() > 1 )
1316 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1318 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1323 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1324 return QVariant(
str.trimmed() );
1329 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1330 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1336 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1337 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1343 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1344 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1351 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1357 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1358 return QVariant( QString( character ) );
1363 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1365 if ( value.isEmpty() )
1370 int res = value.at( 0 ).unicode();
1371 return QVariant( res );
1376 if ( values.length() == 2 || values.length() == 3 )
1378 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1379 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1381 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1392 if ( values.at( 0 ).userType() == QMetaType::type(
"QgsGeometry" ) )
1395 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1399 return QVariant( geom.
length() );
1403 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1404 return QVariant(
str.length() );
1409 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1414 double totalLength = 0;
1417 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1419 totalLength += line->length3D();
1423 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1424 totalLength += segmentized->length3D();
1433 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1435 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1436 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1437 QVector< QPair< QString, QString > > mapItems;
1439 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1441 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1445 std::sort( mapItems.begin(),
1447 [](
const QPair< QString, QString > &pair1,
1448 const QPair< QString, QString > &pair2 )
1450 return ( pair1.first.length() > pair2.first.length() );
1453 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1455 str =
str.replace( it->first, it->second );
1458 return QVariant(
str );
1460 else if ( values.count() == 3 )
1462 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1463 QVariantList before;
1465 bool isSingleReplacement =
false;
1467 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
1469 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1473 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1476 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1478 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1479 isSingleReplacement =
true;
1483 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1486 if ( !isSingleReplacement && before.length() != after.length() )
1488 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1492 for (
int i = 0; i < before.length(); i++ )
1494 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1497 return QVariant(
str );
1501 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1508 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1509 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1510 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1512 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1513 if ( !re.isValid() )
1515 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1518 return QVariant(
str.replace( re, after ) );
1523 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1524 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1526 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1527 if ( !re.isValid() )
1529 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1532 return QVariant( (
str.indexOf( re ) + 1 ) );
1537 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1538 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1539 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1541 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1542 if ( !re.isValid() )
1544 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1548 QRegularExpressionMatch matches = re.match(
str );
1549 if ( matches.hasMatch() )
1552 QStringList list = matches.capturedTexts();
1555 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1557 array += ( !( *it ).isEmpty() ) ? *it : empty;
1560 return QVariant( array );
1570 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1571 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1573 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1574 if ( !re.isValid() )
1576 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1581 QRegularExpressionMatch match = re.match(
str );
1582 if ( match.hasMatch() )
1585 if ( match.lastCapturedIndex() > 0 )
1588 return QVariant( match.captured( 1 ) );
1593 return QVariant( match.captured( 0 ) );
1598 return QVariant(
"" );
1604 QString uuid = QUuid::createUuid().toString();
1605 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1606 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1607 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1608 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1614 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1617 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1618 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1621 if ( values.at( 2 ).isValid() )
1622 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1628 from =
str.size() + from;
1634 else if ( from > 0 )
1642 len =
str.size() + len - from;
1649 return QVariant(
str.mid( from, len ) );
1655 return QVariant(
static_cast< int >( f.
id() ) );
1660 QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
1663 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1667 int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1668 if ( bandNb < 1 || bandNb > layer->
bandCount() )
1670 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1674 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1677 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1685 if ( multiPoint.count() == 1 )
1687 point = multiPoint[0];
1697 return std::isnan( value ) ? QVariant() : value;
1712 if ( values.size() == 1 )
1714 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1717 else if ( values.size() == 2 )
1719 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1720 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1724 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1740 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1745 for (
int i = 0; i < fields.
count(); ++i )
1757 if ( values.isEmpty() )
1760 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1762 else if ( values.size() == 1 )
1764 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1765 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1767 else if ( values.size() == 2 )
1769 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1770 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1774 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1780 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
1786 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
1792 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
1794 const QString fieldName { fields.
at( fieldIndex ).
name() };
1795 const QVariant attributeVal = feature.
attribute( fieldIndex );
1796 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
1799 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
1808 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
1820 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
1822 result.insert( fields.
at( fieldIndex ).
name(), value );
1838 bool evaluate =
true;
1840 if ( values.isEmpty() )
1843 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1845 else if ( values.size() == 1 )
1847 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1848 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1850 else if ( values.size() == 2 )
1852 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1853 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1855 else if ( values.size() == 3 )
1857 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1858 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1859 evaluate = values.value( 2 ).toBool();
1865 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1869 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1900 subContext.setFeature( feature );
1909 exp.prepare( &subContext );
1910 return exp.evaluate( &subContext ).toString();
1916 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
1921 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
1929 if ( values.isEmpty() )
1932 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1934 else if ( values.size() == 1 )
1936 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1937 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1939 else if ( values.size() == 2 )
1941 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1942 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1946 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1950 if ( !layer || !feature.
isValid() )
1952 return QVariant( QVariant::Bool );
1962 if ( values.isEmpty() )
1963 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1964 else if ( values.count() == 1 )
1965 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1968 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
1974 return QVariant( QVariant::LongLong );
1982 static QMap<QString, qlonglong> counterCache;
1983 QVariant functionResult;
1985 std::function<void()> fetchAndIncrementFunc = [ =, &functionResult ]()
1988 const QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1993 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
1994 if ( database.isEmpty() )
1996 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
2001 database = values.at( 0 ).toString();
2004 const QString table = values.at( 1 ).toString();
2005 const QString idColumn = values.at( 2 ).toString();
2006 const QString filterAttribute = values.at( 3 ).toString();
2007 const QVariant filterValue = values.at( 4 ).toString();
2008 const QVariantMap defaultValues = values.at( 5 ).toMap();
2014 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
2017 functionResult = QVariant();
2021 QString errorMessage;
2022 QString currentValSql;
2024 qlonglong nextId = 0;
2025 bool cachedMode =
false;
2026 bool valueRetrieved =
false;
2028 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2035 auto cachedCounter = counterCache.find( cacheString );
2037 if ( cachedCounter != counterCache.end() )
2039 qlonglong &cachedValue = cachedCounter.value();
2040 nextId = cachedValue;
2042 cachedValue = nextId;
2043 valueRetrieved =
true;
2048 if ( !cachedMode || !valueRetrieved )
2050 int result = SQLITE_ERROR;
2053 if ( !filterAttribute.isNull() )
2058 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2060 if ( result == SQLITE_OK )
2063 if ( sqliteStatement.
step() == SQLITE_ROW )
2069 if ( cachedMode && result == SQLITE_OK )
2071 counterCache.insert( cacheString, nextId );
2075 counterCache.remove( cacheString );
2078 valueRetrieved =
true;
2082 if ( valueRetrieved )
2091 if ( !filterAttribute.isNull() )
2097 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2100 vals << iter.value().toString();
2103 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2104 upsertSql += QLatin1String(
" VALUES " );
2105 upsertSql +=
'(' + vals.join(
',' ) +
')';
2107 int result = SQLITE_ERROR;
2111 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2118 result = sqliteDb.
exec( upsertSql, errorMessage );
2120 if ( result == SQLITE_OK )
2122 functionResult = QVariant( nextId );
2127 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2128 functionResult = QVariant();
2133 functionResult = QVariant();
2138 return functionResult;
2144 for (
const QVariant &value : values )
2147 concat += QgsExpressionUtils::getStringValue( value, parent );
2154 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2155 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2160 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2161 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2162 return string.right( pos );
2167 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2168 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2169 return string.left( pos );
2174 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2175 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2176 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2177 return string.leftJustified( length, fill.at( 0 ),
true );
2182 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2183 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2184 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2185 return string.rightJustified( length, fill.at( 0 ),
true );
2190 if ( values.size() < 1 )
2192 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2196 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2197 for (
int n = 1; n < values.length(); n++ )
2199 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2207 return QVariant( QDateTime::currentDateTime() );
2212 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2213 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2214 if ( format.isEmpty() && !language.isEmpty() )
2216 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2217 return QVariant( QDate() );
2220 if ( format.isEmpty() && language.isEmpty() )
2221 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2223 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2224 QLocale locale = QLocale();
2225 if ( !language.isEmpty() )
2227 locale = QLocale( language );
2230 QDate date = locale.toDate( datestring, format );
2231 if ( !date.isValid() )
2233 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2236 return QVariant( date );
2241 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2242 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2243 if ( format.isEmpty() && !language.isEmpty() )
2245 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2246 return QVariant( QTime() );
2249 if ( format.isEmpty() && language.isEmpty() )
2250 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2252 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2253 QLocale locale = QLocale();
2254 if ( !language.isEmpty() )
2256 locale = QLocale( language );
2259 QTime time = locale.toTime( timestring, format );
2260 if ( !time.isValid() )
2262 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2265 return QVariant( time );
2270 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2279 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2280 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2281 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2283 QString formatString;
2284 if ( values.count() > 3 )
2285 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2287 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2288 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2292 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2296 else if ( ! formatString.isEmpty() )
2298 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2302 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2306 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2312 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2320 return floatToDegreeFormat( format, values, context, parent, node );
2327 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2329 return ok ? QVariant( value ) : QVariant();
2335 return floatToDegreeFormat( format, values, context, parent, node );
2340 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2341 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2342 qint64 seconds = d2.secsTo( d1 );
2343 return QVariant::fromValue(
QgsInterval( seconds ) );
2348 if ( !values.at( 0 ).canConvert<QDate>() )
2351 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2352 if ( !date.isValid() )
2357 return date.dayOfWeek() % 7;
2362 QVariant value = values.at( 0 );
2363 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2366 return QVariant( inter.
days() );
2370 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2371 return QVariant( d1.date().day() );
2377 QVariant value = values.at( 0 );
2378 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2381 return QVariant( inter.
years() );
2385 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2386 return QVariant( d1.date().year() );
2392 QVariant value = values.at( 0 );
2393 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2396 return QVariant( inter.
months() );
2400 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2401 return QVariant( d1.date().month() );
2407 QVariant value = values.at( 0 );
2408 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2411 return QVariant( inter.
weeks() );
2415 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2416 return QVariant( d1.date().weekNumber() );
2422 QVariant value = values.at( 0 );
2423 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2426 return QVariant( inter.
hours() );
2430 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2431 return QVariant( t1.hour() );
2437 QVariant value = values.at( 0 );
2438 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2441 return QVariant( inter.
minutes() );
2445 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2446 return QVariant( t1.minute() );
2452 QVariant value = values.at( 0 );
2453 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2456 return QVariant( inter.
seconds() );
2460 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2461 return QVariant( t1.second() );
2467 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2470 return QVariant( dt.toMSecsSinceEpoch() );
2480 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2482 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2487 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2490 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif" ) ) );
2493 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2499 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2502 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"exif_geotag" ) ) );
2509#define ENSURE_GEOM_TYPE(f, g, geomtype) \
2510 if ( !(f).hasGeometry() ) \
2511 return QVariant(); \
2512 QgsGeometry g = (f).geometry(); \
2513 if ( (g).type() != (geomtype) ) \
2520 if ( g.isMultipart() )
2522 return g.asMultiPoint().at( 0 ).x();
2526 return g.asPoint().x();
2534 if ( g.isMultipart() )
2536 return g.asMultiPoint().at( 0 ).y();
2540 return g.asPoint().y();
2554 if ( g.isEmpty() || !abGeom->
is3D() )
2559 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2565 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2567 if ( collection->numGeometries() > 0 )
2569 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2580 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2586 return QVariant( isValid );
2591 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2595 const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
2596#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
2601 if ( methodString.compare( QLatin1String(
"linework" ), Qt::CaseInsensitive ) == 0 )
2603 else if ( methodString.compare( QLatin1String(
"structure" ), Qt::CaseInsensitive ) == 0 )
2606 const bool keepCollapsed = values.value( 2 ).toBool();
2611 valid = geom.
makeValid( method, keepCollapsed );
2615 parent->
setEvalErrorString( QObject::tr(
"The make_valid parameters require a newer GEOS library version" ) );
2619 return QVariant::fromValue( valid );
2624 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2630 for (
int i = 0; i < multiGeom.size(); ++i )
2632 array += QVariant::fromValue( multiGeom.at( i ) );
2640 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2652 QVariant result(
centroid.asPoint().
x() );
2658 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2670 QVariant result(
centroid.asPoint().
y() );
2676 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2686 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2694 if ( collection->numGeometries() == 1 )
2696 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2707 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2717 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2725 if ( collection->numGeometries() == 1 )
2727 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2738 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2743 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2770 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2787 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2804 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2809 bool ignoreClosing =
false;
2810 if ( values.length() > 1 )
2812 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
2822 bool skipLast =
false;
2823 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
2828 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
2840 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2851 for (
int i = 0; i < line->numPoints() - 1; ++i )
2855 << line->pointN( i )
2856 << line->pointN( i + 1 ) );
2867 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2877 if ( collection->numGeometries() == 1 )
2879 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
2884 if ( !curvePolygon )
2888 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2894 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
2900 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2910 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2916 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
2922 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2931 return QVariant::fromValue(
QgsGeometry( boundary ) );
2936 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2945 return QVariant::fromValue( merged );
2950 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2954 const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
2959 if ( sharedPaths.
isNull() )
2962 return QVariant::fromValue( sharedPaths );
2968 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2973 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2976 if ( simplified.
isNull() )
2984 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2989 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2994 if ( simplified.
isNull() )
3002 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3007 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
3008 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
3009 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3010 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
3012 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
3021 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3026 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3027 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3028 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3039 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3044 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3045 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3046 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3047 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3048 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3051 minAmplitude, maxAmplitude, seed );
3060 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3065 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3066 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3067 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3078 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3083 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3084 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3085 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3086 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3087 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3090 minAmplitude, maxAmplitude, seed );
3099 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3104 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3105 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3106 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3117 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3122 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3123 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3124 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3125 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3126 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3129 minAmplitude, maxAmplitude, seed );
3138 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3143 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3144 QVector< double > dashPattern;
3145 dashPattern.reserve( pattern.size() );
3146 for (
const QVariant &value : std::as_const( pattern ) )
3149 double v = value.toDouble( &ok );
3156 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3161 if ( dashPattern.size() % 2 != 0 )
3163 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3167 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3169 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3171 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3173 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3175 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3177 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3181 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3185 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3187 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3189 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3191 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3193 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3195 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3199 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3203 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3205 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3207 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3209 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3213 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3217 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3228 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3233 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3235 if ( densified.
isNull() )
3243 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3248 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3250 if ( densified.
isNull() )
3259 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3261 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3268 QVector< QgsGeometry > parts;
3269 parts.reserve( list.size() );
3270 for (
const QVariant &value : std::as_const( list ) )
3272 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3288 if ( values.count() < 2 || values.count() > 4 )
3290 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3294 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3295 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3296 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3297 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3298 switch ( values.count() )
3312 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3313 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3314 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3320 if ( values.empty() )
3325 QVector<QgsPoint> points;
3326 points.reserve( values.count() );
3328 auto addPoint = [&points](
const QgsGeometry & geom )
3336 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3343 for (
const QVariant &value : values )
3345 if ( value.type() == QVariant::List )
3347 const QVariantList list = value.toList();
3348 for (
const QVariant &v : list )
3350 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3355 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3359 if ( points.count() < 2 )
3367 if ( values.count() < 1 )
3369 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3373 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3381 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3383 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3390 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3395 if ( !exteriorRing )
3398 polygon->setExteriorRing( exteriorRing->
segmentize() );
3401 for (
int i = 1; i < values.count(); ++i )
3403 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3410 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3417 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3425 polygon->addInteriorRing( ring->
segmentize() );
3428 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3433 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3434 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3435 lineString->clear();
3437 for (
const QVariant &value : values )
3439 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3446 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3453 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3461 lineString->addVertex( *point );
3464 tr->setExteriorRing( lineString.release() );
3466 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3471 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3478 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3479 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3486 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3493 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3501 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3506 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3513 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3514 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3515 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3516 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3522 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3529 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3536 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3537 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3543 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3550 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3557 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3560 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3567 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3571 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3578 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3585 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3592 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3607 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3613 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3619 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3620 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3628 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3634 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3640 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3649 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3652 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3653 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3654 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
3662 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
3678 return QVariant( QPointF( p.
x(), p.
y() ) );
3683 QVariant v = pointAt( values, f, parent );
3684 if ( v.type() == QVariant::PointF )
3685 return QVariant( v.toPointF().x() );
3691 QVariant v = pointAt( values, f, parent );
3692 if ( v.type() == QVariant::PointF )
3693 return QVariant( v.toPointF().y() );
3710 return QVariant::fromValue( geom );
3718 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3720 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3726 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
3732 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3737 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3744 ogcContext.
layer = mapLayerPtr.data();
3745 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
3749 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3762 return QVariant( area );
3772 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3777 return QVariant( geom.
area() );
3789 return QVariant( len );
3806 return QVariant( len );
3810 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
3816 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3822 return QVariant( geom.
length() );
3827 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3833 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3842 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3851 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3866 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
3867 if ( !curvePolygon )
3879 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3886 return QVariant( curvePolygon->
ringCount() );
3888 bool foundPoly =
false;
3896 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
3897 if ( !curvePolygon )
3908 return QVariant( ringCount );
3913 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3915 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
3921 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3927 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3933 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3942 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3948 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3954 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3960 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3966 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3974 double max = std::numeric_limits< double >::lowest();
3978 double z = ( *it ).z();
3984 if ( max == std::numeric_limits< double >::lowest() )
3985 return QVariant( QVariant::Double );
3987 return QVariant( max );
3992 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4000 double min = std::numeric_limits< double >::max();
4004 double z = ( *it ).z();
4010 if ( min == std::numeric_limits< double >::max() )
4011 return QVariant( QVariant::Double );
4013 return QVariant( min );
4018 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4026 double min = std::numeric_limits< double >::max();
4030 double m = ( *it ).m();
4036 if ( min == std::numeric_limits< double >::max() )
4037 return QVariant( QVariant::Double );
4039 return QVariant( min );
4044 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4052 double max = std::numeric_limits< double >::lowest();
4056 double m = ( *it ).m();
4062 if ( max == std::numeric_limits< double >::lowest() )
4063 return QVariant( QVariant::Double );
4065 return QVariant( max );
4070 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4071 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
4074 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
4083 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4087 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4096 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4101 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4112 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4116 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4118 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4123 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4127 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4134 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4142 return QVariant::fromValue( curve->
isClosed() );
4147 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4160 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4161 closedLine->close();
4163 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4173 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4175 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4176 closedLine->close();
4178 closed->addGeometry( closedLine.release() );
4181 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4189 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4193 return QVariant::fromValue( fGeom.
isEmpty() );
4199 return QVariant::fromValue(
true );
4201 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4202 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4207 if ( values.length() < 2 || values.length() > 3 )
4210 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4211 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4218 if ( values.length() == 2 )
4221 QString result = engine->relate( sGeom.
constGet() );
4222 return QVariant::fromValue( result );
4227 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4228 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4229 return QVariant::fromValue( result );
4235 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4236 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4241 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4242 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4243 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4247 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4248 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4249 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4253 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4254 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4255 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4259 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4260 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4261 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4265 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4266 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4267 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4271 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4272 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4273 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4277 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4278 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4279 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4284 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4285 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4286 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4287 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4288 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4289 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4292 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4293 capStyle = Qgis::EndCapStyle::Flat;
4294 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4295 capStyle = Qgis::EndCapStyle::Square;
4298 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4299 joinStyle = Qgis::JoinStyle::Miter;
4300 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4301 joinStyle = Qgis::JoinStyle::Bevel;
4304 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4310 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4312 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4317 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4319 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4324 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4326 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4331 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4332 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4339 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4346 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4350 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4351 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4352 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4353 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4356 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4362 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4365 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4369 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4370 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4371 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4374 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4380 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4383 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4387 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4390 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4396 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4397 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4398 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4399 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4400 if ( joinInt < 1 || joinInt > 3 )
4404 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4407 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4413 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4414 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4415 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4417 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4418 if ( joinInt < 1 || joinInt > 3 )
4422 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4425 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4431 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4432 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4433 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4436 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4442 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4443 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4444 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4446 return QVariant::fromValue( fGeom );
4451 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4452 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4453 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4455 const bool perPart = values.value( 3 ).toBool();
4462 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4465 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4466 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4467 t.rotate( -rotation );
4468 t.translate( -partCenter.
x(), -partCenter.
y() );
4469 ( *it )->transform( t );
4471 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4483 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4491 fGeom.
rotate( rotation, pt );
4492 return QVariant::fromValue( fGeom );
4498 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4499 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4500 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4501 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
4512 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
4520 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
4521 t.scale( xScale, yScale );
4522 t.translate( -pt.
x(), -pt.
y() );
4524 return QVariant::fromValue( fGeom );
4529 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4535 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4536 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4538 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4540 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4541 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4543 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
4544 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
4545 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
4546 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
4557 QTransform transform;
4558 transform.translate( deltaX, deltaY );
4559 transform.rotate( rotationZ );
4560 transform.scale( scaleX, scaleY );
4561 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
4563 return QVariant::fromValue( fGeom );
4569 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4571 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4576 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4578 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4584 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4585 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4587 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4593 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4595 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4603 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4604 const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4605 const bool allowHoles = values.value( 2 ).toBool();
4607 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4620 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4622 if ( values.length() == 2 )
4623 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4631 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4637 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4639 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4645 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4651 double area,
angle, width, height;
4664 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4665 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4667 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4673 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4680 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
4685 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
4693 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
4695 reversed->addGeometry( curve->
reversed() );
4702 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
4709 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4720 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
4729 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
4735 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4736 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4737 return QVariant( fGeom.
distance( sGeom ) );
4742 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4743 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4746 if ( values.length() == 3 && values.at( 2 ).isValid() )
4748 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4749 densify = std::clamp( densify, 0.0, 1.0 );
4757 return res > -1 ? QVariant( res ) : QVariant();
4762 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4763 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4765 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4770 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4771 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4773 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4778 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4779 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4781 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4787 if ( values.length() < 1 || values.length() > 2 )
4790 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4792 if ( values.length() == 2 )
4793 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4794 QString wkt = fGeom.
asWkt( prec );
4795 return QVariant( wkt );
4800 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4801 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
4806 if ( values.length() != 2 )
4808 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
4812 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4813 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4815 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4822 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4827 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4834 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4841 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
4848 if ( pt1->
y() < pt2->
y() )
4850 else if ( pt1->
y() > pt2->
y() )
4858 if ( pt1->
x() < pt2->
x() )
4860 else if ( pt1->
x() > pt2->
x() )
4861 return M_PI + ( M_PI_2 );
4866 if ( pt1->
x() < pt2->
x() )
4868 if ( pt1->
y() < pt2->
y() )
4870 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
4874 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4881 if ( pt1->
y() > pt2->
y() )
4883 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
4888 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4889 + ( M_PI + ( M_PI_2 ) );
4896 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4900 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
4904 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4905 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4906 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4909 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
4916 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4917 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4919 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4926 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4930 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4937 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4945 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
4955 if ( values.length() != 3 )
4958 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4959 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4960 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4964 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
4970 if ( values.length() < 2 )
4973 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4976 return values.at( 0 );
4978 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4979 QVariant cachedExpression;
4984 if ( cachedExpression.isValid() )
4991 bool asc = values.value( 2 ).toBool();
5009 Q_ASSERT( collection );
5013 QgsExpressionSorter sorter( orderBy );
5015 QList<QgsFeature> partFeatures;
5016 partFeatures.reserve( collection->
partCount() );
5017 for (
int i = 0; i < collection->
partCount(); ++i )
5023 sorter.sortFeatures( partFeatures, unconstedContext );
5027 Q_ASSERT( orderedGeom );
5032 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
5037 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
5040 delete unconstedContext;
5047 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5048 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5052 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5058 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5059 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5063 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5069 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5070 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5074 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
5080 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5083 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
5089 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
5096 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
5103 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5104 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5106 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
5108 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
5113 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5114 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5121 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5122 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5127 vertex = count + vertex;
5135 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5136 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5141 vertex = count + vertex;
5149 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5150 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5154 return distance >= 0 ? distance : QVariant();
5159 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
5161 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5162 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5165 if ( values.length() >= 1 )
5167 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5168 return QVariant( qlonglong( std::round( number ) ) );
5183 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5184 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5185 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5192 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5193 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5194 return locale.toString( value,
'f', places );
5199 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
5200 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5201 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5203 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5204 return locale.toString( datetime, format );
5210 int avg = ( color.red() + color.green() + color.blue() ) / 3;
5211 int alpha = color.alpha();
5213 color.setRgb( avg, avg, avg, alpha );
5222 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5227 else if ( ratio < 0 )
5232 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
5233 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
5234 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
5235 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
5237 QColor newColor( red, green, blue, alpha );
5244 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5245 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5246 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5247 QColor color = QColor( red, green, blue );
5248 if ( ! color.isValid() )
5250 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
5251 color = QColor( 0, 0, 0 );
5254 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5259 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5260 QVariant value = node->
eval( parent, context );
5264 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5266 value = node->
eval( parent, context );
5274 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5276 QVariant value = node->
eval( parent, context );
5278 if ( value.toBool() )
5280 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5282 value = node->
eval( parent, context );
5287 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
5289 value = node->
eval( parent, context );
5297 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5298 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5299 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5300 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
5301 QColor color = QColor( red, green, blue, alpha );
5302 if ( ! color.isValid() )
5304 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
5305 color = QColor( 0, 0, 0 );
5314 if ( values.at( 0 ).userType() == QMetaType::type(
"QgsGradientColorRamp" ) )
5316 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
5321 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5325 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
5330 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5331 QColor color = ramp->
color( value );
5338 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5340 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5342 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5344 QColor color = QColor::fromHslF( hue, saturation, lightness );
5346 if ( ! color.isValid() )
5348 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
5349 color = QColor( 0, 0, 0 );
5352 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5358 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5360 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5362 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5364 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5366 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
5367 if ( ! color.isValid() )
5369 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
5370 color = QColor( 0, 0, 0 );
5378 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5380 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5382 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5384 QColor color = QColor::fromHsvF( hue, saturation, value );
5386 if ( ! color.isValid() )
5388 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
5389 color = QColor( 0, 0, 0 );
5392 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5398 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5400 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5402 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5404 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5406 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
5407 if ( ! color.isValid() )
5409 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
5410 color = QColor( 0, 0, 0 );
5418 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5420 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5422 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5424 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5426 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
5428 if ( ! color.isValid() )
5430 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
5431 color = QColor( 0, 0, 0 );
5434 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5440 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5442 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5444 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5446 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5448 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
5450 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
5451 if ( ! color.isValid() )
5453 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
5454 color = QColor( 0, 0, 0 );
5462 if ( ! color.isValid() )
5464 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5468 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5469 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5471 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5472 return color.green();
5473 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5474 return color.blue();
5475 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5476 return color.alpha();
5477 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5478 return static_cast< double >( color.hsvHueF() * 360 );
5479 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5480 return static_cast< double >( color.hsvSaturationF() * 100 );
5481 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5482 return static_cast< double >( color.valueF() * 100 );
5483 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5484 return static_cast< double >( color.hslHueF() * 360 );
5485 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5486 return static_cast< double >( color.hslSaturationF() * 100 );
5487 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5488 return static_cast< double >( color.lightnessF() * 100 );
5489 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5490 return static_cast< double >( color.cyanF() * 100 );
5491 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5492 return static_cast< double >( color.magentaF() * 100 );
5493 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5494 return static_cast< double >( color.yellowF() * 100 );
5495 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5496 return static_cast< double >( color.blackF() * 100 );
5498 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5504 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5505 if ( map.count() < 1 )
5507 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
5511 QList< QColor > colors;
5513 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5516 if ( !colors.last().isValid() )
5518 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
5522 double step = it.key().toDouble();
5523 if ( it == map.constBegin() )
5528 else if ( it == map.constEnd() )
5538 bool discrete = values.at( 1 ).toBool();
5540 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
5546 if ( ! color.isValid() )
5548 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5552 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5553 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5554 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5555 color.setRed( value );
5556 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5557 color.setGreen( value );
5558 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5559 color.setBlue( value );
5560 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5561 color.setAlpha( value );
5562 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5563 color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
5564 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5565 color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
5566 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5567 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
5568 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5569 color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
5570 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5571 color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
5572 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5573 color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
5574 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5575 color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
5576 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5577 color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
5578 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5579 color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
5580 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5581 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
5584 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5593 if ( ! color.isValid() )
5595 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5599 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5607 if ( ! color.isValid() )
5609 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5613 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5620 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
5623 return QVariant::fromValue( geom );
5629 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5630 QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5631 QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5635 return QVariant::fromValue( fGeom );
5638 return QVariant::fromValue( fGeom );
5647 return QVariant::fromValue( fGeom );
5661 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
5664 QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
5676 result = QVariant::fromValue( fet );
5686 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), parent );
5689 if ( !featureSource )
5694 QString cacheValueKey;
5695 if ( values.at( 1 ).type() == QVariant::Map )
5697 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
5699 QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
5700 QString filterString;
5701 for ( ; i != attributeMap.constEnd(); ++i )
5703 if ( !filterString.isEmpty() )
5705 filterString.append(
" AND " );
5709 cacheValueKey = QStringLiteral(
"getfeature:%1:%2" ).arg( featureSource->id(), filterString );
5718 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5719 int attributeId = featureSource->fields().lookupField( attribute );
5720 if ( attributeId == -1 )
5725 const QVariant &attVal = values.at( 2 );
5727 cacheValueKey = QStringLiteral(
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
5750 res = QVariant::fromValue( fet );
5765 if ( !values.isEmpty() )
5768 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
5769 fieldName = col->
name();
5770 else if ( values.size() == 2 )
5771 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5774 QVariant value = values.at( 0 );
5779 if ( fieldIndex == -1 )
5781 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5785 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
5787 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName, value.toString() );
5796 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName );
5807 result =
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
5814 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5822 const QVariant data = values.at( 0 );
5823 const QMimeDatabase db;
5824 return db.mimeTypeForData( data.toByteArray() ).name();
5829 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5835 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5836 if ( QString::compare( layerProperty, QStringLiteral(
"name" ), Qt::CaseInsensitive ) == 0 )
5837 return layer->
name();
5838 else if ( QString::compare( layerProperty, QStringLiteral(
"id" ), Qt::CaseInsensitive ) == 0 )
5840 else if ( QString::compare( layerProperty, QStringLiteral(
"title" ), Qt::CaseInsensitive ) == 0 )
5842 else if ( QString::compare( layerProperty, QStringLiteral(
"abstract" ), Qt::CaseInsensitive ) == 0 )
5844 else if ( QString::compare( layerProperty, QStringLiteral(
"keywords" ), Qt::CaseInsensitive ) == 0 )
5846 QStringList keywords;
5848 for (
auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
5850 keywords.append( it.value() );
5852 if ( !keywords.isEmpty() )
5856 else if ( QString::compare( layerProperty, QStringLiteral(
"data_url" ), Qt::CaseInsensitive ) == 0 )
5858 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution" ), Qt::CaseInsensitive ) == 0 )
5862 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
5864 else if ( QString::compare( layerProperty, QStringLiteral(
"source" ), Qt::CaseInsensitive ) == 0 )
5866 else if ( QString::compare( layerProperty, QStringLiteral(
"min_scale" ), Qt::CaseInsensitive ) == 0 )
5868 else if ( QString::compare( layerProperty, QStringLiteral(
"max_scale" ), Qt::CaseInsensitive ) == 0 )
5870 else if ( QString::compare( layerProperty, QStringLiteral(
"is_editable" ), Qt::CaseInsensitive ) == 0 )
5872 else if ( QString::compare( layerProperty, QStringLiteral(
"crs" ), Qt::CaseInsensitive ) == 0 )
5874 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
5876 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_description" ), Qt::CaseInsensitive ) == 0 )
5878 else if ( QString::compare( layerProperty, QStringLiteral(
"extent" ), Qt::CaseInsensitive ) == 0 )
5881 QVariant result = QVariant::fromValue( extentGeom );
5884 else if ( QString::compare( layerProperty, QStringLiteral(
"distance_units" ), Qt::CaseInsensitive ) == 0 )
5886 else if ( QString::compare( layerProperty, QStringLiteral(
"path" ), Qt::CaseInsensitive ) == 0 )
5889 return decodedUri.value( QStringLiteral(
"path" ) );
5891 else if ( QString::compare( layerProperty, QStringLiteral(
"type" ), Qt::CaseInsensitive ) == 0 )
5893 switch ( layer->
type() )
5896 return QCoreApplication::translate(
"expressions",
"Vector" );
5898 return QCoreApplication::translate(
"expressions",
"Raster" );
5900 return QCoreApplication::translate(
"expressions",
"Mesh" );
5902 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
5904 return QCoreApplication::translate(
"expressions",
"Plugin" );
5906 return QCoreApplication::translate(
"expressions",
"Annotation" );
5908 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
5910 return QCoreApplication::translate(
"expressions",
"Group" );
5916 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
5919 if ( QString::compare( layerProperty, QStringLiteral(
"storage_type" ), Qt::CaseInsensitive ) == 0 )
5921 else if ( QString::compare( layerProperty, QStringLiteral(
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
5923 else if ( QString::compare( layerProperty, QStringLiteral(
"feature_count" ), Qt::CaseInsensitive ) == 0 )
5933 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5936 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
5946 const QString uriPart = values.at( 1 ).toString();
5950 if ( !uriPart.isNull() )
5952 return decodedUri.value( values.at( 1 ).toString() );
5962 QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5969 if ( !layersByName.isEmpty() )
5971 layer = layersByName.at( 0 );
5982 int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5983 if ( band < 1 || band > rl->
bandCount() )
5985 parent->
setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer %2" ).arg( band ).arg( layerIdOrName ) );
5989 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5992 if ( QString::compare( layerProperty, QStringLiteral(
"avg" ), Qt::CaseInsensitive ) == 0 )
5994 else if ( QString::compare( layerProperty, QStringLiteral(
"stdev" ), Qt::CaseInsensitive ) == 0 )
5996 else if ( QString::compare( layerProperty, QStringLiteral(
"min" ), Qt::CaseInsensitive ) == 0 )
5998 else if ( QString::compare( layerProperty, QStringLiteral(
"max" ), Qt::CaseInsensitive ) == 0 )
6000 else if ( QString::compare( layerProperty, QStringLiteral(
"range" ), Qt::CaseInsensitive ) == 0 )
6002 else if ( QString::compare( layerProperty, QStringLiteral(
"sum" ), Qt::CaseInsensitive ) == 0 )
6006 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
6036 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6037 bool ascending = values.value( 1 ).toBool();
6038 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
6044 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
6049 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
6054 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
6059 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6060 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6062 for (
const auto &item : listB )
6064 if ( listA.contains( item ) )
6068 return QVariant( match == listB.count() );
6073 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
6078 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6079 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6080 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
6081 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
6082 return list.at( list.length() + pos );
6088 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6089 return list.value( 0 );
6094 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6095 return list.value( list.size() - 1 );
6100 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6101 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
6106 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6107 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
6112 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6115 for (
const QVariant &item : list )
6117 switch ( item.userType() )
6119 case QMetaType::Int:
6120 case QMetaType::UInt:
6121 case QMetaType::LongLong:
6122 case QMetaType::ULongLong:
6123 case QMetaType::Float:
6124 case QMetaType::Double:
6125 total += item.toDouble();
6130 return i == 0 ? QVariant() : total / i;
6135 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6136 QVariantList numbers;
6137 for (
const auto &item : list )
6139 switch ( item.userType() )
6141 case QMetaType::Int:
6142 case QMetaType::UInt:
6143 case QMetaType::LongLong:
6144 case QMetaType::ULongLong:
6145 case QMetaType::Float:
6146 case QMetaType::Double:
6147 numbers.append( item );
6151 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
6152 const int count = numbers.count();
6157 else if ( count % 2 )
6159 return numbers.at( count / 2 );
6163 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
6169 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6172 for (
const QVariant &item : list )
6174 switch ( item.userType() )
6176 case QMetaType::Int:
6177 case QMetaType::UInt:
6178 case QMetaType::LongLong:
6179 case QMetaType::ULongLong:
6180 case QMetaType::Float:
6181 case QMetaType::Double:
6182 total += item.toDouble();
6187 return i == 0 ? QVariant() : total;
6190static QVariant convertToSameType(
const QVariant &value, QVariant::Type type )
6192 QVariant result = value;
6193 result.convert(
static_cast<int>( type ) );
6199 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6200 QHash< QVariant, int > hash;
6201 for (
const auto &item : list )
6205 const QList< int > occurrences = hash.values();
6206 if ( occurrences.empty() )
6207 return QVariantList();
6209 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6211 const QString option = values.at( 1 ).toString();
6212 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6214 return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
6216 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6218 if ( hash.isEmpty() )
6221 return QVariant( hash.keys( maxValue ).first() );
6223 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6225 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
6227 else if ( option.compare( QLatin1String(
"real_majority" ), Qt::CaseInsensitive ) == 0 )
6229 if ( maxValue * 2 <= list.size() )
6232 return QVariant( hash.keys( maxValue ).first() );
6243 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6244 QHash< QVariant, int > hash;
6245 for (
const auto &item : list )
6249 const QList< int > occurrences = hash.values();
6250 if ( occurrences.empty() )
6251 return QVariantList();
6253 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
6255 const QString option = values.at( 1 ).toString();
6256 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6258 return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
6260 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6262 if ( hash.isEmpty() )
6265 return QVariant( hash.keys( minValue ).first() );
6267 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6269 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
6271 else if ( option.compare( QLatin1String(
"real_minority" ), Qt::CaseInsensitive ) == 0 )
6273 if ( hash.keys().isEmpty() )
6277 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6278 if ( maxValue * 2 > list.size() )
6279 hash.remove( hash.key( maxValue ) );
6281 return convertToSameType( hash.keys(), values.at( 0 ).type() );
6292 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6293 list.append( values.at( 1 ) );
6294 return convertToSameType( list, values.at( 0 ).type() );
6299 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6300 list.prepend( values.at( 1 ) );
6301 return convertToSameType( list, values.at( 0 ).type() );
6306 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6307 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
6308 return convertToSameType( list, values.at( 0 ).type() );
6313 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6314 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6316 position = position + list.length();
6317 if ( position >= 0 && position < list.length() )
6318 list.removeAt( position );
6319 return convertToSameType( list, values.at( 0 ).type() );
6324 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6325 list.removeAll( values.at( 1 ) );
6326 return convertToSameType( list, values.at( 0 ).type() );
6331 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
6333 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
6335 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6336 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6338 int index = list.indexOf( it.key() );
6339 while ( index >= 0 )
6341 list.replace( index, it.value() );
6342 index = list.indexOf( it.key() );
6346 return convertToSameType( list, values.at( 0 ).type() );
6348 else if ( values.count() == 3 )
6350 QVariantList before;
6352 bool isSingleReplacement =
false;
6354 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
6356 before = QVariantList() << values.at( 1 );
6360 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6363 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
6365 after = QVariantList() << values.at( 2 );
6366 isSingleReplacement =
true;
6370 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
6373 if ( !isSingleReplacement && before.length() != after.length() )
6375 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
6379 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6380 for (
int i = 0; i < before.length(); i++ )
6382 int index = list.indexOf( before.at( i ) );
6383 while ( index >= 0 )
6385 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
6386 index = list.indexOf( before.at( i ) );
6390 return convertToSameType( list, values.at( 0 ).type() );
6394 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
6401 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6402 QVariantList list_new;
6404 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
6406 while ( list.removeOne( cur ) )
6408 list_new.append( cur );
6412 list_new.append( list );
6414 return convertToSameType( list_new, values.at( 0 ).type() );
6420 for (
const QVariant &cur : values )
6422 list += QgsExpressionUtils::getListValue( cur, parent );
6424 return convertToSameType( list, values.at( 0 ).type() );
6429 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6430 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6431 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6432 int slice_length = 0;
6434 if ( start_pos < 0 )
6436 start_pos = list.length() + start_pos;
6440 slice_length = end_pos - start_pos + 1;
6444 slice_length = list.length() + end_pos - start_pos + 1;
6447 if ( slice_length < 0 )
6451 list = list.mid( start_pos, slice_length );
6457 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6458 std::reverse( list.begin(), list.end() );
6464 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6465 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6466 for (
const QVariant &cur : array2 )
6468 if ( array1.contains( cur ) )
6469 return QVariant(
true );
6471 return QVariant(
false );
6476 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6478 QVariantList distinct;
6480 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6482 if ( !distinct.contains( *it ) )
6484 distinct += ( *it );
6493 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6494 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6495 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6499 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6501 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
6502 if ( it != ( array.constEnd() - 1 ) )
6508 return QVariant(
str );
6513 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6514 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6515 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6517 QStringList list =
str.split( delimiter );
6520 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
6522 array += ( !( *it ).isEmpty() ) ? *it : empty;
6530 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6531 QJsonDocument document = QJsonDocument::fromJson(
str.toUtf8() );
6532 if ( document.isNull() )
6535 return document.toVariant();
6541 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
6542 return QString( document.toJson( QJsonDocument::Compact ) );
6547 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6548 if (
str.isEmpty() )
6549 return QVariantMap();
6557 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6564 for (
int i = 0; i + 1 < values.length(); i += 2 )
6566 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
6573 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6574 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6575 QVariantMap resultMap;
6577 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6579 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
6587 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
6592 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
6597 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6598 map.remove( values.at( 1 ).toString() );
6604 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6605 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
6612 for (
const QVariant &cur : values )
6614 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
6615 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
6616 result.insert( it.key(), it.value() );
6623 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
6628 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
6633 const QString envVarName = values.at( 0 ).toString();
6634 if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
6637 return QProcessEnvironment::systemEnvironment().value( envVarName );
6642 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6645 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"base_file_name" ) ) );
6648 return QFileInfo( file ).completeBaseName();
6653 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6656 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_suffix" ) ) );
6659 return QFileInfo( file ).completeSuffix();
6664 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6667 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_exists" ) ) );
6670 return QFileInfo::exists( file );
6675 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6678 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_name" ) ) );
6681 return QFileInfo( file ).fileName();
6686 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6689 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"is_file" ) ) );
6692 return QFileInfo( file ).isFile();
6697 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6700 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"is_directory" ) ) );
6703 return QFileInfo( file ).isDir();
6708 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6711 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_path" ) ) );
6714 return QDir::toNativeSeparators( QFileInfo( file ).path() );
6719 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6722 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String(
"file_size" ) ) );
6725 return QFileInfo( file ).size();
6728static QVariant fcnHash(
const QString &
str,
const QCryptographicHash::Algorithm
algorithm )
6730 return QString( QCryptographicHash::hash(
str.toUtf8(),
algorithm ).toHex() );
6736 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6737 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
6739 if ( method == QLatin1String(
"md4" ) )
6741 hash = fcnHash(
str, QCryptographicHash::Md4 );
6743 else if ( method == QLatin1String(
"md5" ) )
6745 hash = fcnHash(
str, QCryptographicHash::Md5 );
6747 else if ( method == QLatin1String(
"sha1" ) )
6749 hash = fcnHash(
str, QCryptographicHash::Sha1 );
6751 else if ( method == QLatin1String(
"sha224" ) )
6753 hash = fcnHash(
str, QCryptographicHash::Sha224 );
6755 else if ( method == QLatin1String(
"sha256" ) )
6757 hash = fcnHash(
str, QCryptographicHash::Sha256 );
6759 else if ( method == QLatin1String(
"sha384" ) )
6761 hash = fcnHash(
str, QCryptographicHash::Sha384 );
6763 else if ( method == QLatin1String(
"sha512" ) )
6765 hash = fcnHash(
str, QCryptographicHash::Sha512 );
6767 else if ( method == QLatin1String(
"sha3_224" ) )
6769 hash = fcnHash(
str, QCryptographicHash::Sha3_224 );
6771 else if ( method == QLatin1String(
"sha3_256" ) )
6773 hash = fcnHash(
str, QCryptographicHash::Sha3_256 );
6775 else if ( method == QLatin1String(
"sha3_384" ) )
6777 hash = fcnHash(
str, QCryptographicHash::Sha3_384 );
6779 else if ( method == QLatin1String(
"sha3_512" ) )
6781 hash = fcnHash(
str, QCryptographicHash::Sha3_512 );
6783 else if ( method == QLatin1String(
"keccak_224" ) )
6785 hash = fcnHash(
str, QCryptographicHash::Keccak_224 );
6787 else if ( method == QLatin1String(
"keccak_256" ) )
6789 hash = fcnHash(
str, QCryptographicHash::Keccak_256 );
6791 else if ( method == QLatin1String(
"keccak_384" ) )
6793 hash = fcnHash(
str, QCryptographicHash::Keccak_384 );
6795 else if ( method == QLatin1String(
"keccak_512" ) )
6797 hash = fcnHash(
str, QCryptographicHash::Keccak_512 );
6801 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg(
str ) );
6808 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
6813 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
6818 const QByteArray input = values.at( 0 ).toByteArray();
6819 return QVariant( QString( input.toBase64() ) );
6824 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6826 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6828 query.addQueryItem( it.key(), it.value().toString() );
6830 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
6835 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6836 const QByteArray base64 = value.toLocal8Bit();
6837 const QByteArray decoded = QByteArray::fromBase64( base64 );
6838 return QVariant( decoded );
6843static QVariant executeGeomOverlay(
const QVariantList &values,
const QgsExpressionContext *context,
QgsExpression *parent,
const RelationFunction &relationFunction,
bool invert =
false,
double bboxGrow = 0,
bool isNearestFunc =
false,
bool isIntersectsFunc =
false )
6846 const QVariant sourceLayerRef = context->
variable( QStringLiteral(
"layer" ) );
6847 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, parent );
6855 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6858 const bool layerCanBeCached = node->
isStatic( parent, context );
6859 QVariant targetLayerValue = node->
eval( parent, context );
6863 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6865 QString subExpString = node->
dump();
6867 bool testOnly = ( subExpString ==
"NULL" );
6868 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, parent );
6871 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
6876 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6878 QString filterString = node->
dump();
6879 if ( filterString !=
"NULL" )
6885 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
6887 QVariant limitValue = node->
eval( parent, context );
6889 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
6892 double max_distance = 0;
6893 if ( isNearestFunc )
6895 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
6897 QVariant distanceValue = node->
eval( parent, context );
6899 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
6903 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
6905 QVariant cacheValue = node->
eval( parent, context );
6907 bool cacheEnabled = cacheValue.toBool();
6913 double minOverlap { -1 };
6914 double minInscribedCircleRadius { -1 };
6915 bool returnDetails =
false;
6916 bool sortByMeasure =
false;
6917 bool sortAscending =
false;
6918 bool requireMeasures =
false;
6919 bool overlapOrRadiusFilter =
false;
6920 if ( isIntersectsFunc )
6923 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
6925 const QVariant minOverlapValue = node->
eval( parent, context );
6927 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
6928 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
6930 const QVariant minInscribedCircleRadiusValue = node->
eval( parent, context );
6932 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
6933 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
6935 returnDetails = !testOnly && node->
eval( parent, context ).toBool();
6936 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
6938 const QString sorting { node->
eval( parent, context ).toString().toLower() };
6939 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
6940 sortAscending = sorting.startsWith(
"asc" );
6941 requireMeasures = sortByMeasure || returnDetails;
6942 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
6949 if ( sourceLayer && targetLayer->
crs() != sourceLayer->
crs() )
6955 bool sameLayers = ( sourceLayer && sourceLayer->
id() == targetLayer->
id() );
6958 if ( bboxGrow != 0 )
6960 intDomain.
grow( bboxGrow );
6963 const QString cacheBase { QStringLiteral(
"%1:%2:%3" ).arg( targetLayer->
id(), subExpString, filterString ) };
6969 QList<QgsFeature> features;
6970 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
6974 const QString cacheLayer { QStringLiteral(
"ovrlaylyr:%1" ).arg( cacheBase ) };
6975 const QString cacheIndex { QStringLiteral(
"ovrlayidx:%1" ).arg( cacheBase ) };
6979 cachedTarget = targetLayer->
materialize( request );
6980 if ( layerCanBeCached )
6981 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
6991 if ( layerCanBeCached )
6992 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
6999 QList<QgsFeatureId> fidsList;
7000 if ( isNearestFunc )
7002 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
7006 fidsList = spatialIndex.
intersects( intDomain );
7009 QListIterator<QgsFeatureId> i( fidsList );
7010 while ( i.hasNext() )
7013 if ( sameLayers && feat.
id() == fId2 )
7015 features.append( cachedTarget->
getFeature( fId2 ) );
7028 if ( sameLayers && feat.
id() == feat2.
id() )
7030 features.append( feat2 );
7038 const QString expCacheKey { QStringLiteral(
"exp:%1" ).arg( cacheBase ) };
7039 const QString ctxCacheKey { QStringLiteral(
"ctx:%1" ).arg( cacheBase ) };
7045 subExpression.
prepare( &subContext );
7058 auto testLinestring = [ = ](
const QgsGeometry intersection,
double & overlapValue ) ->
bool
7060 bool testResult {
false };
7062 QVector<double> overlapValues;
7065 const QgsCurve *geom = qgsgeometry_cast< const QgsCurve * >( *it );
7067 if ( minOverlap != -1 || requireMeasures )
7069 overlapValue = geom->
length();
7070 overlapValues.append( overlapValue );
7071 if ( minOverlap != -1 )
7073 if ( overlapValue >= minOverlap )
7085 if ( ! overlapValues.isEmpty() )
7087 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
7094 auto testPolygon = [ = ](
const QgsGeometry intersection,
double & radiusValue,
double & overlapValue ) ->
bool
7097 bool testResult {
false };
7099 QVector<double> overlapValues;
7100 QVector<double> radiusValues;
7103 const QgsCurvePolygon *geom = qgsgeometry_cast< const QgsCurvePolygon * >( *it );
7105 if ( minOverlap != -1 || requireMeasures )
7107 overlapValue = geom->
area();
7108 overlapValues.append( geom->
area() );
7109 if ( minOverlap != - 1 )
7111 if ( overlapValue >= minOverlap )
7123 if ( minInscribedCircleRadius != -1 || requireMeasures )
7126 const double width = bbox.
width();
7127 const double height = bbox.
height();
7128 const double size = width > height ? width : height;
7129 const double tolerance = size / 100.0;
7131 testResult = radiusValue >= minInscribedCircleRadius;
7132 radiusValues.append( radiusValues );
7137 if ( !radiusValues.isEmpty() )
7139 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
7142 if ( ! overlapValues.isEmpty() )
7144 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
7154 QVariantList results;
7156 QListIterator<QgsFeature> i( features );
7157 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
7163 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
7166 double overlapValue = -1;
7167 double radiusValue = -1;
7169 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
7176 switch ( intersection.
type() )
7179 case QgsWkbTypes::GeometryType::PolygonGeometry:
7183 bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
7185 if ( ! testResult && overlapOrRadiusFilter )
7193 case QgsWkbTypes::GeometryType::LineGeometry:
7198 if ( minInscribedCircleRadius != -1 )
7204 const bool testResult { testLinestring( intersection, overlapValue ) };
7206 if ( ! testResult && overlapOrRadiusFilter )
7214 case QgsWkbTypes::GeometryType::PointGeometry:
7219 if ( minInscribedCircleRadius != -1 )
7224 bool testResult {
false };
7225 if ( minOverlap != -1 || requireMeasures )
7233 if ( geometry.
type() == QgsWkbTypes::GeometryType::PointGeometry )
7237 case QgsWkbTypes::GeometryType::UnknownGeometry:
7238 case QgsWkbTypes::GeometryType::NullGeometry:
7239 case QgsWkbTypes::GeometryType::PointGeometry:
7243 case QgsWkbTypes::GeometryType::LineGeometry:
7245 testResult = testLinestring( feat2.
geometry(), overlapValue );
7248 case QgsWkbTypes::GeometryType::PolygonGeometry:
7250 testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
7256 if ( ! testResult && overlapOrRadiusFilter )
7265 case QgsWkbTypes::GeometryType::NullGeometry:
7266 case QgsWkbTypes::GeometryType::UnknownGeometry:
7284 const QVariant expResult = subExpression.
evaluate( &subContext );
7286 if ( requireMeasures )
7288 QVariantMap resultRecord;
7289 resultRecord.insert( QStringLiteral(
"id" ), feat2.
id() );
7290 resultRecord.insert( QStringLiteral(
"result" ), expResult );
7292 resultRecord.insert( QStringLiteral(
"overlap" ), overlapValue );
7294 if ( radiusValue != -1 )
7296 resultRecord.insert( QStringLiteral(
"radius" ), radiusValue );
7298 results.append( resultRecord );
7302 results.append( expResult );
7308 results.append( feat2.
id() );
7322 if ( requireMeasures )
7324 if ( sortByMeasure )
7326 std::sort( results.begin(), results.end(), [ sortAscending ](
const QVariant & recordA,
const QVariant & recordB ) ->
bool
7328 return sortAscending ?
7329 recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble()
7330 : recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble();
7334 if ( limit > 0 && results.size() > limit )
7336 results.erase( results.begin() + limit );
7339 if ( ! returnDetails )
7341 QVariantList expResults;
7342 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
7344 expResults.append( it->toMap().value( QStringLiteral(
"result" ) ) );
7354 QVariantList disjoint_results;
7363 if ( !results.contains( feat2.
id() ) )
7366 disjoint_results.append( subExpression.
evaluate( &subContext ) );
7369 return disjoint_results;
7412 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
7421 static QRecursiveMutex sFunctionsMutex;
7422 QMutexLocker locker( &sFunctionsMutex );
7424 QList<QgsExpressionFunction *> &functions = *sFunctions();
7426 if ( functions.isEmpty() )
7463 functions << randFunc;
7467 functions << randfFunc;
7470 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max" ), -1, fcnMax, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7471 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min" ), -1, fcnMin, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7477 <<
new QgsStaticExpressionFunction( QStringLiteral(
"pi" ), 0, fcnPi, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$pi" ) )
7481 <<
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" ) )
7482 <<
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" ) )
7483 <<
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" ) )
7488 <<
new QgsStaticExpressionFunction( QStringLiteral(
"coalesce" ), -1, fcnCoalesce, QStringLiteral(
"Conditionals" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7502 QStringLiteral(
"Aggregates" ),
7511 if ( !node->
args() )
7514 QSet<QString> referencedVars;
7517 QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
7518 referencedVars = subExpressionNode->referencedVariables();
7523 QgsExpressionNode *filterNode = node->args()->at( 3 );
7524 referencedVars.unite( filterNode->referencedVariables() );
7526 return referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() );
7535 if ( !node->
args() )
7536 return QSet<QString>();
7538 QSet<QString> referencedCols;
7539 QSet<QString> referencedVars;
7554 if ( referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() ) )
7557 return referencedCols;
7570 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count" ), aggParams, fcnAggregateCount, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7571 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7572 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7573 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7574 <<
new QgsStaticExpressionFunction( QStringLiteral(
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7575 <<
new QgsStaticExpressionFunction( QStringLiteral(
"sum" ), aggParams, fcnAggregateSum, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7576 <<
new QgsStaticExpressionFunction( QStringLiteral(
"mean" ), aggParams, fcnAggregateMean, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7577 <<
new QgsStaticExpressionFunction( QStringLiteral(
"median" ), aggParams, fcnAggregateMedian, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7578 <<
new QgsStaticExpressionFunction( QStringLiteral(
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7579 <<
new QgsStaticExpressionFunction( QStringLiteral(
"range" ), aggParams, fcnAggregateRange, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7580 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7581 <<
new QgsStaticExpressionFunction( QStringLiteral(
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7582 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7583 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7584 <<
new QgsStaticExpressionFunction( QStringLiteral(
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7585 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7586 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7587 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7588 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7589 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7590 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7595 <<
new QgsStaticExpressionFunction( QStringLiteral(
"now" ), 0, fcnNow, QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$now" ) )
7598 fcnAge, QStringLiteral(
"Date and Time" ) )
7612 fcnMakeDate, QStringLiteral(
"Date and Time" ) )
7616 fcnMakeTime, QStringLiteral(
"Date and Time" ) )
7623 fcnMakeDateTime, QStringLiteral(
"Date and Time" ) )
7631 fcnMakeInterval, QStringLiteral(
"Date and Time" ) )
7650 false, QSet< QString >(),
false, QStringList(), true )
7651 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concat" ), -1, fcnConcat, QStringLiteral(
"String" ), QString(),
false, QSet<QString>(),
false, QStringList(), true )
7664 fcnColorMixRgb, QStringLiteral(
"Color" ) )
7668 fcnColorRgb, QStringLiteral(
"Color" ) )
7673 fncColorRgba, QStringLiteral(
"Color" ) )
7679 fcnCreateRamp, QStringLiteral(
"Color" ) )
7683 fcnColorHsl, QStringLiteral(
"Color" ) )
7688 fncColorHsla, QStringLiteral(
"Color" ) )
7692 fcnColorHsv, QStringLiteral(
"Color" ) )
7697 fncColorHsva, QStringLiteral(
"Color" ) )
7702 fcnColorCmyk, QStringLiteral(
"Color" ) )
7708 fncColorCmyka, QStringLiteral(
"Color" ) )
7711 fncColorPart, QStringLiteral(
"Color" ) )
7714 fncDarker, QStringLiteral(
"Color" ) )
7717 fncLighter, QStringLiteral(
"Color" ) )
7722 fcnBaseFileName, QStringLiteral(
"Files and Paths" ) )
7724 fcnFileSuffix, QStringLiteral(
"Files and Paths" ) )
7726 fcnFileExists, QStringLiteral(
"Files and Paths" ) )
7728 fcnFileName, QStringLiteral(
"Files and Paths" ) )
7730 fcnPathIsFile, QStringLiteral(
"Files and Paths" ) )
7732 fcnPathIsDir, QStringLiteral(
"Files and Paths" ) )
7734 fcnFilePath, QStringLiteral(
"Files and Paths" ) )
7736 fcnFileSize, QStringLiteral(
"Files and Paths" ) )
7739 fcnExif, QStringLiteral(
"Files and Paths" ) )
7741 fcnExifGeoTag, QStringLiteral(
"GeometryGroup" ) )
7745 fcnGenericHash, QStringLiteral(
"Conversions" ) )
7747 fcnHashMd5, QStringLiteral(
"Conversions" ) )
7749 fcnHashSha256, QStringLiteral(
"Conversions" ) )
7753 fcnToBase64, QStringLiteral(
"Conversions" ) )
7755 fcnFromBase64, QStringLiteral(
"Conversions" ) )
7761 geomFunc->setIsStatic(
false );
7762 functions << geomFunc;
7766 functions << areaFunc;
7772 functions << lengthFunc;
7776 functions << perimeterFunc;
7782 fcnRoundness, QStringLiteral(
"GeometryGroup" ) );
7796 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
7798 { QStringLiteral(
"overlay_intersects" ), fcnGeomOverlayIntersects },
7799 { QStringLiteral(
"overlay_contains" ), fcnGeomOverlayContains },
7800 { QStringLiteral(
"overlay_crosses" ), fcnGeomOverlayCrosses },
7801 { QStringLiteral(
"overlay_equals" ), fcnGeomOverlayEquals },
7802 { QStringLiteral(
"overlay_touches" ), fcnGeomOverlayTouches },
7803 { QStringLiteral(
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
7804 { QStringLiteral(
"overlay_within" ), fcnGeomOverlayWithin },
7806 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
7807 while ( i.hasNext() )
7824 functions << fcnGeomOverlayFunc;
7837 functions << fcnGeomOverlayNearestFunc;
7850 fcnNodesToPoints, QStringLiteral(
"GeometryGroup" ) )
7852 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral(
"GeometryGroup" ) )
7857 fcnMakePointM, QStringLiteral(
"GeometryGroup" ) )
7863 fcnMakeTriangle, QStringLiteral(
"GeometryGroup" ) )
7868 fcnMakeCircle, QStringLiteral(
"GeometryGroup" ) )
7875 fcnMakeEllipse, QStringLiteral(
"GeometryGroup" ) )
7881 fcnMakeRegularPolygon, QStringLiteral(
"GeometryGroup" ) )
7885 fcnMakeSquare, QStringLiteral(
"GeometryGroup" ) )
7891 fcnMakeRectangleFrom3Points, QStringLiteral(
"GeometryGroup" ) )
7895#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10
7901 }, fcnGeomMakeValid, QStringLiteral(
"GeometryGroup" ) );
7903 xAtFunc->setIsStatic(
false );
7904 functions << xAtFunc;
7908 functions << yAtFunc;
7924 fcnDisjoint, QStringLiteral(
"GeometryGroup" ) )
7927 fcnIntersects, QStringLiteral(
"GeometryGroup" ) )
7930 fcnTouches, QStringLiteral(
"GeometryGroup" ) )
7933 fcnCrosses, QStringLiteral(
"GeometryGroup" ) )
7936 fcnContains, QStringLiteral(
"GeometryGroup" ) )
7939 fcnOverlaps, QStringLiteral(
"GeometryGroup" ) )
7942 fcnWithin, QStringLiteral(
"GeometryGroup" ) )
7946 fcnTranslate, QStringLiteral(
"GeometryGroup" ) )
7951 fcnRotate, QStringLiteral(
"GeometryGroup" ) )
7956 fcnScale, QStringLiteral(
"GeometryGroup" ) )
7967 fcnAffineTransform, QStringLiteral(
"GeometryGroup" ) )
7974 fcnBuffer, QStringLiteral(
"GeometryGroup" ) )
7976 fcnForceRHR, QStringLiteral(
"GeometryGroup" ) )
7978 fcnForcePolygonCW, QStringLiteral(
"GeometryGroup" ) )
7980 fcnForcePolygonCCW, QStringLiteral(
"GeometryGroup" ) )
7990 , fcnTaperedBuffer, QStringLiteral(
"GeometryGroup" ) )
7993 , fcnBufferByM, QStringLiteral(
"GeometryGroup" ) )
7999 fcnOffsetCurve, QStringLiteral(
"GeometryGroup" ) )
8005 fcnSingleSidedBuffer, QStringLiteral(
"GeometryGroup" ) )
8009 fcnExtend, QStringLiteral(
"GeometryGroup" ) )
8018 fcnInteriorRingN, QStringLiteral(
"GeometryGroup" ) )
8021 fcnGeometryN, QStringLiteral(
"GeometryGroup" ) )
8028 }, fcnSharedPaths, QStringLiteral(
"GeometryGroup" ) )
8042 }, fcnTriangularWave, QStringLiteral(
"GeometryGroup" ) )
8051 }, fcnTriangularWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
8058 }, fcnSquareWave, QStringLiteral(
"GeometryGroup" ) )
8067 }, fcnSquareWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
8074 }, fcnRoundWave, QStringLiteral(
"GeometryGroup" ) )
8083 }, fcnRoundWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
8092 }, fcnApplyDashPattern, QStringLiteral(
"GeometryGroup" ) )
8097 }, fcnDensifyByCount, QStringLiteral(
"GeometryGroup" ) )
8102 }, fcnDensifyByDistance, QStringLiteral(
"GeometryGroup" ) )
8119 fcnOrientedBBox, QStringLiteral(
"GeometryGroup" ) )
8122 fcnMainAngle, QStringLiteral(
"GeometryGroup" ) )
8126 fcnMinimalCircle, QStringLiteral(
"GeometryGroup" ) )
8129 fcnDifference, QStringLiteral(
"GeometryGroup" ) )
8132 fcnDistance, QStringLiteral(
"GeometryGroup" ) )
8135 fcnHausdorffDistance, QStringLiteral(
"GeometryGroup" ) )
8138 fcnIntersection, QStringLiteral(
"GeometryGroup" ) )
8141 fcnSymDifference, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"symDifference" ) )
8144 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
8147 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
8150 fcnGeomToWKT, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"geomToWKT" ) )
8152 fcnGeomToWKB, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(), false )
8157 fcnTransformGeometry, QStringLiteral(
"GeometryGroup" ) )
8161 fcnExtrude, QStringLiteral(
"GeometryGroup" ), QString() )
8163 fcnGeomIsMultipart, QStringLiteral(
"GeometryGroup" ) )
8165 fcnZMax, QStringLiteral(
"GeometryGroup" ) )
8167 fcnZMin, QStringLiteral(
"GeometryGroup" ) )
8169 fcnMMax, QStringLiteral(
"GeometryGroup" ) )
8171 fcnMMin, QStringLiteral(
"GeometryGroup" ) )
8173 fcnSinuosity, QStringLiteral(
"GeometryGroup" ) )
8175 fcnStraightDistance2d, QStringLiteral(
"GeometryGroup" ) );
8181 fcnOrderParts, QStringLiteral(
"GeometryGroup" ), QString() );
8183 orderPartsFunc->setIsStaticFunction(
8186 const QList< QgsExpressionNode *> argList = node->
args()->list();
8189 if ( !argNode->isStatic( parent, context ) )
8195 QgsExpressionNode *argNode = node->args()->at( 1 );
8197 QString expString = argNode->eval( parent, context ).toString();
8199 QgsExpression e( expString );
8201 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8212 QgsExpressionNode *argNode = node->args()->at( 1 );
8213 QString expression = argNode->eval( parent, context ).toString();
8214 QgsExpression e( expression );
8215 e.prepare( context );
8216 context->setCachedValue( expression, QVariant::fromValue( e ) );
8221 functions << orderPartsFunc;
8226 fcnClosestPoint, QStringLiteral(
"GeometryGroup" ) )
8229 fcnShortestLine, QStringLiteral(
"GeometryGroup" ) )
8248 functions << idFunc;
8252 functions << currentFeatureFunc;
8254 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" ) );
8256 functions << uuidFunc;
8262 fcnGetFeature, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"QgsExpressionUtils::getFeature" ) )
8265 fcnGetFeatureById, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false );
8270 functions << attributesFunc;
8274 functions << representAttributesFunc;
8277 QStringLiteral(
"maptip" ),
8280 QStringLiteral(
"Record and Attributes" ),
8286 functions << maptipFunc;
8289 QStringLiteral(
"display_expression" ),
8291 fcnFeatureDisplayExpression,
8292 QStringLiteral(
"Record and Attributes" ),
8298 functions << displayFunc;
8301 QStringLiteral(
"is_selected" ),
8304 QStringLiteral(
"Record and Attributes" ),
8310 functions << isSelectedFunc;
8314 QStringLiteral(
"num_selected" ),
8317 QStringLiteral(
"Record and Attributes" ),
8325 QStringLiteral(
"sqlite_fetch_and_increment" ),
8333 fcnSqliteFetchAndIncrement,
8334 QStringLiteral(
"Record and Attributes" )
8352 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
8362 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
8368 functions << representValueFunc;
8374 fcnGetLayerProperty, QStringLiteral(
"Map Layers" ) )
8379 fcnDecodeUri, QStringLiteral(
"Map Layers" ) )
8383 fcnMimeType, QStringLiteral(
"General" ) )
8400 QgsExpressionNode *argNode = node->args()->at( 0 );
8402 if ( !argNode->isStatic( parent, context ) )
8405 const QString varName = argNode->eval( parent, context ).toString();
8406 if ( varName == QLatin1String(
"feature" ) || varName == QLatin1String(
"id" ) || varName == QLatin1String(
"geometry" ) )
8409 const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
8410 return scope ? scope->isStatic( varName ) : false;
8427 QgsExpressionNode *argNode = node->args()->at( 0 );
8429 if ( argNode->isStatic( parent, context ) )
8431 QString expString = argNode->eval( parent, context ).toString();
8433 QgsExpression e( expString );
8435 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8443 functions << evalFunc;
8449 const QList< QgsExpressionNode *> argList = node->
args()->list();
8452 if ( !argNode->isStatic( parent, context ) )
8464 functions << attributeFunc;
8474 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array" ), -1, fcnArray, QStringLiteral(
"Arrays" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8523 fcnMapPrefixKeys, QStringLiteral(
"Maps" ) )
8525 fcnToFormUrlEncode, QStringLiteral(
"Maps" ) )
8534 *sOwnedFunctions() << func;
8535 *sBuiltinFunctions() << func->name();
8536 sBuiltinFunctions()->append( func->aliases() );
8549 sFunctions()->append( function );
8550 if ( transferOwnership )
8551 sOwnedFunctions()->append( function );
8565 sFunctions()->removeAt( fnIdx );
8573 qDeleteAll( *sOwnedFunctions() );
8574 sOwnedFunctions()->clear();
8579 if ( sBuiltinFunctions()->isEmpty() )
8583 return *sBuiltinFunctions();
8591 QStringLiteral(
"Arrays" ) )
8602 if ( args->
count() < 2 )
8605 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8615 QVariantList result;
8617 if ( args->
count() < 2 )
8621 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8624 std::unique_ptr< QgsExpressionContext > tempContext;
8627 tempContext = std::make_unique< QgsExpressionContext >();
8628 subContext = tempContext.get();
8634 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8637 result << args->
at( 1 )->
eval( parent, subContext );
8662 if ( args->
count() < 2 )
8666 args->
at( 0 )->
prepare( parent, context );
8670 subContext = *context;
8676 args->
at( 1 )->
prepare( parent, &subContext );
8686 QStringLiteral(
"Arrays" ) )
8697 if ( args->
count() < 2 )
8700 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8710 QVariantList result;
8712 if ( args->
count() < 2 )
8716 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8719 std::unique_ptr< QgsExpressionContext > tempContext;
8722 tempContext = std::make_unique< QgsExpressionContext >();
8723 subContext = tempContext.get();
8730 if ( args->
count() >= 3 )
8732 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
8734 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
8736 limit = limitVar.toInt();
8744 for (
const QVariant &value : array )
8747 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
8751 if ( limit > 0 && limit == result.size() )
8778 if ( args->
count() < 2 )
8782 args->
at( 0 )->
prepare( parent, context );
8786 subContext = *context;
8792 args->
at( 1 )->
prepare( parent, &subContext );
8801 QStringLiteral(
"General" ) )
8812 if ( args->
count() < 3 )
8816 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8818 QVariant
name = args->
at( 0 )->
eval( parent, context );
8819 QVariant value = args->
at( 1 )->
eval( parent, context );
8822 appendTemporaryVariable( context,
name.toString(), value );
8823 if ( args->
at( 2 )->
isStatic( parent, context ) )
8825 popTemporaryVariable( context );
8836 if ( args->
count() < 3 )
8840 QVariant
name = args->
at( 0 )->
eval( parent, context );
8841 QVariant value = args->
at( 1 )->
eval( parent, context );
8844 std::unique_ptr< QgsExpressionContext > tempContext;
8845 if ( !updatedContext )
8847 tempContext = std::make_unique< QgsExpressionContext >();
8848 updatedContext = tempContext.get();
8851 appendTemporaryVariable( updatedContext,
name.toString(), value );
8852 result = args->
at( 2 )->
eval( parent, updatedContext );
8855 popTemporaryVariable( updatedContext );
8876 if ( args->
count() < 3 )
8881 QVariant value = args->
at( 1 )->
prepare( parent, context );
8884 std::unique_ptr< QgsExpressionContext > tempContext;
8885 if ( !updatedContext )
8887 tempContext = std::make_unique< QgsExpressionContext >();
8888 updatedContext = tempContext.get();
8891 appendTemporaryVariable( updatedContext,
name.toString(), value );
8892 args->
at( 2 )->
prepare( parent, updatedContext );
8895 popTemporaryVariable( updatedContext );
8900void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
8906void QgsWithVariableExpressionFunction::appendTemporaryVariable(
const QgsExpressionContext *context,
const QString &name,
const QVariant &value )
const
DashPatternSizeAdjustment
Dash pattern size adjustment options.
@ ScaleDashOnly
Only dash lengths are adjusted.
@ ScaleBothDashAndGap
Both the dash and gap lengths are adjusted equally.
@ ScaleGapOnly
Only gap lengths are adjusted.
@ Success
Operation succeeded.
JoinStyle
Join styles for buffers.
EndCapStyle
End cap styles for buffers.
DashPatternLineEndingRule
Dash pattern line ending rules.
@ HalfDash
Start or finish the pattern with a half length dash.
@ HalfGap
Start or finish the pattern with a half length gap.
@ FullGap
Start or finish the pattern with a full gap.
@ FullDash
Start or finish the pattern with a full dash.
MakeValidMethod
Algorithms to use when repairing invalid geometries.
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
@ Structure
Structured method, first makes all rings valid and then merges shells and subtracts holes from shells...
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 bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
part_iterator parts_end()
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
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.
part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
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.
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.
double roundness() const
Returns the roundness of the curve polygon.
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
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.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
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.
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
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 hasGeometry() const
Returns true if the context has a geometry associated with it.
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.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
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 createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QVariant::Type fieldType=QVariant::Type::Invalid)
Create an expression allowing to evaluate if a field is equal to a value.
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)
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 hasGeometry() const
Returns true if the feature has an associated geometry.
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.
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.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
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.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
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.
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
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 densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
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 squareWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs square waves along the boundary of the geometry, with the specified wavelength and amplitu...
QgsGeometry triangularWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs triangular waves along the boundary of the geometry, with the specified wavelength and amp...
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry concaveHull(double targetPercent, bool allowHoles=false) const SIP_THROW(QgsNotSupportedException)
Returns a possibly concave polygon that contains all the points in the geometry.
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 applyDashPattern(const QVector< double > &pattern, Qgis::DashPatternLineEndingRule startRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternLineEndingRule endRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternSizeAdjustment adjustment=Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap, double patternOffset=0) const
Applies a dash pattern to a geometry, returning a MultiLineString geometry which is the input geometr...
QgsGeometry roundWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs rounded (sine-like) waves along the boundary of the geometry, with the specified wavelengt...
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 combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
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.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
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.
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 makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false) const SIP_THROW(QgsNotSupportedException)
Attempts to make an invalid geometry valid without losing vertices.
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
QgsGeometry sharedPaths(const QgsGeometry &other) const
Find paths shared between the two given lineal geometries (this and other).
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 intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
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...
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
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 triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
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.
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
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.
Does vector analysis using the geos library and handles import, export, exception handling*.
std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle(double tolerance, QString *errorMsg=nullptr) const
Returns the maximum inscribed circle.
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 source() const
Returns the source for 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.
Custom exception class which is raised when an operation is not supported.
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.
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
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.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
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.
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
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
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
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_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
QList< QgsExpressionFunction * > ExpressionFunctionList
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
bool(QgsGeometry::* RelationFunction)(const QgsGeometry &geometry) const
#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.
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.