67 #include <QMimeDatabase>
68 #include <QProcessEnvironment>
69 #include <QCryptographicHash>
70 #include <QRegularExpression>
93 QVariantList argValues;
97 const QList< QgsExpressionNode * > argList = args->
list();
104 v = QVariant::fromValue( n );
108 v = n->eval( parent, context );
110 bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
111 if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
114 argValues.append( v );
119 return func( argValues, context, parent, node );
130 return QStringList();
157 return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral(
"deprecated" ) );
162 return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
174 const QString &group,
175 const QString &helpText,
179 const QStringList &aliases,
183 , mAliases( aliases )
184 , mUsesGeometry( false )
185 , mUsesGeometryFunc( usesGeometry )
186 , mReferencedColumnsFunc( referencedColumns )
198 if ( mUsesGeometryFunc )
199 return mUsesGeometryFunc( node );
201 return mUsesGeometry;
206 if ( mReferencedColumnsFunc )
207 return mReferencedColumnsFunc( node );
209 return mReferencedColumns;
215 return mIsStaticFunc( node, parent, context );
223 return mPrepareFunc( node, parent, context );
235 mIsStaticFunc =
nullptr;
241 mPrepareFunc = prepareFunc;
246 if ( node && node->
args() )
248 const QList< QgsExpressionNode * > argList = node->
args()->
list();
251 if ( !argNode->isStatic( parent, context ) )
261 double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
262 double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
263 double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
265 if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
272 double current = start + step;
273 while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
288 QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
294 QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
303 QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
305 return expression.evaluate( context );
310 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
311 return QVariant( std::sqrt( x ) );
316 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
317 return QVariant( std::fabs( val ) );
322 double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
323 return ( deg * M_PI ) / 180;
327 double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
328 return ( 180 * rad ) / M_PI;
332 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
333 return QVariant( std::sin( x ) );
337 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
338 return QVariant( std::cos( x ) );
342 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
343 return QVariant( std::tan( x ) );
347 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
348 return QVariant( std::asin( x ) );
352 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
353 return QVariant( std::acos( x ) );
357 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
358 return QVariant( std::atan( x ) );
362 double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
363 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
364 return QVariant( std::atan2( y, x ) );
368 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
369 return QVariant( std::exp( x ) );
373 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
376 return QVariant( std::log( x ) );
380 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
383 return QVariant( log10( x ) );
387 double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
388 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
389 if ( x <= 0 || b <= 0 )
391 return QVariant( std::log( x ) / std::log( b ) );
395 double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
396 double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
400 std::random_device rd;
401 std::mt19937_64 generator( rd() );
403 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
406 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
409 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
414 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
415 std::hash<std::string> hasher;
416 seed = hasher( seedStr.toStdString() );
418 generator.seed( seed );
422 double f =
static_cast< double >( generator() ) /
static_cast< double >( std::mt19937_64::max() );
423 return QVariant( min + f * ( max - min ) );
427 qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
428 qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
432 std::random_device rd;
433 std::mt19937_64 generator( rd() );
435 if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
438 if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
441 seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
446 QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
447 std::hash<std::string> hasher;
448 seed = hasher( seedStr.toStdString() );
450 generator.seed( seed );
453 qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
454 if ( randomInteger > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
455 return QVariant( randomInteger );
458 return QVariant(
int( randomInteger ) );
463 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
464 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
465 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
466 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
467 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
469 if ( domainMin >= domainMax )
471 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
476 if ( val >= domainMax )
480 else if ( val <= domainMin )
486 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
487 double c = rangeMin - ( domainMin * m );
490 return QVariant( m * val +
c );
495 double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
496 double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
497 double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
498 double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
499 double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
500 double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
502 if ( domainMin >= domainMax )
504 parent->
setEvalErrorString( QObject::tr(
"Domain max must be greater than domain min" ) );
514 if ( val >= domainMax )
518 else if ( val <= domainMin )
524 return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
529 QVariant result( QVariant::Double );
530 double maxVal = std::numeric_limits<double>::quiet_NaN();
531 for (
const QVariant &val : values )
533 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
534 if ( std::isnan( maxVal ) )
538 else if ( !std::isnan( testVal ) )
540 maxVal = std::max( maxVal, testVal );
544 if ( !std::isnan( maxVal ) )
546 result = QVariant( maxVal );
553 QVariant result( QVariant::Double );
554 double minVal = std::numeric_limits<double>::quiet_NaN();
555 for (
const QVariant &val : values )
557 double testVal = val.isNull() ? std::numeric_limits<double>::quiet_NaN() :
QgsExpressionUtils::getDoubleValue( val, parent );
558 if ( std::isnan( minVal ) )
562 else if ( !std::isnan( testVal ) )
564 minVal = std::min( minVal, testVal );
568 if ( !std::isnan( minVal ) )
570 result = QVariant( minVal );
582 QVariant value = node->
eval( parent, context );
584 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, parent );
587 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
592 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
594 value = node->
eval( parent, context );
600 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
605 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
607 QString subExpression = node->
dump();
611 if ( values.count() > 3 )
613 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
616 if ( !nl || nl->value().isValid() )
621 if ( values.count() > 4 )
623 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
625 value = node->
eval( parent, context );
632 if ( values.count() > 5 )
634 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
637 if ( !nl || nl->value().isValid() )
639 orderBy = node->
dump();
644 QString aggregateError;
652 bool isStatic =
true;
653 if ( filterExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
654 || filterExp.referencedVariables().contains( QString() )
655 || subExp.referencedVariables().contains( QStringLiteral(
"parent" ) )
656 || subExp.referencedVariables().contains( QString() ) )
662 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
663 for (
const QString &varName : refVars )
666 if ( scope && !scope->
isStatic( varName ) )
676 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
677 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
681 cacheKey = QStringLiteral(
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
692 subContext.appendScope( subScope );
693 result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &aggregateError );
705 result = vl->aggregate( aggregate, subExpression, parameters,
nullptr, &ok,
nullptr,
nullptr, &aggregateError );
709 if ( !aggregateError.isEmpty() )
710 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
712 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
723 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
728 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
731 parent->
setEvalErrorString( QObject::tr(
"Cannot use relation aggregate function in this context" ) );
740 QVariant value = node->
eval( parent, context );
742 QString relationId = value.toString();
749 if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
751 parent->
setEvalErrorString( QObject::tr(
"Cannot find relation with id '%1'" ).arg( relationId ) );
756 relation = relations.at( 0 );
763 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
765 value = node->
eval( parent, context );
771 parent->
setEvalErrorString( QObject::tr(
"No such aggregate '%1'" ).arg( value.toString() ) );
776 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
778 QString subExpression = node->
dump();
782 if ( values.count() > 3 )
784 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
786 value = node->
eval( parent, context );
793 if ( values.count() > 4 )
795 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
798 if ( !nl || nl->value().isValid() )
800 orderBy = node->
dump();
811 QString cacheKey = QStringLiteral(
"relagg:%1:%2:%3:%4:%5" ).arg( vl->
id(),
812 QString::number(
static_cast< int >( aggregate ) ),
825 result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
829 if ( !error.isEmpty() )
830 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
832 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
846 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
851 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
854 parent->
setEvalErrorString( QObject::tr(
"Cannot use aggregate function in this context" ) );
863 QString subExpression = node->
dump();
867 if ( values.count() > 1 )
869 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
872 if ( !nl || nl->value().isValid() )
873 groupBy = node->
dump();
877 if ( values.count() > 2 )
879 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
882 if ( !nl || nl->value().isValid() )
888 if ( orderByPos >= 0 && values.count() > orderByPos )
890 node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
893 if ( !nl || nl->value().isValid() )
895 orderBy = node->
dump();
903 if ( !groupBy.isEmpty() )
906 QVariant groupByValue = groupByExp.evaluate( context );
907 QString groupByClause = QStringLiteral(
"%1 %2 %3" ).arg( groupBy,
908 groupByValue.isNull() ? QStringLiteral(
"is" ) : QStringLiteral(
"=" ),
910 if ( !parameters.
filter.isEmpty() )
911 parameters.
filter = QStringLiteral(
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
913 parameters.
filter = groupByClause;
919 bool isStatic =
true;
920 const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
921 for (
const QString &varName : refVars )
924 if ( scope && !scope->
isStatic( varName ) )
934 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter,
935 QString::number( context->
feature().
id() ), QString::number(
qHash( context->
feature() ) ), orderBy );
939 cacheKey = QStringLiteral(
"agg:%1:%2:%3:%4:%5" ).arg( vl->
id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
951 subContext.appendScope( subScope );
953 result = vl->
aggregate( aggregate, subExpression, parameters, &subContext, &ok,
nullptr, context->
feedback(), &error );
957 if ( !error.isEmpty() )
958 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
960 parent->
setEvalErrorString( QObject::tr(
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
1065 if ( values.count() > 3 )
1067 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1069 QVariant value = node->
eval( parent, context );
1071 parameters.
delimiter = value.toString();
1082 if ( values.count() > 3 )
1084 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
1086 QVariant value = node->
eval( parent, context );
1088 parameters.
delimiter = value.toString();
1104 QVariant scale = context->
variable( QStringLiteral(
"map_scale" ) );
1106 if ( !scale.isValid() || scale.isNull() )
1109 const double v = scale.toDouble( &ok );
1117 double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1118 double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1119 double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1122 if ( testValue <= minValue )
1124 return QVariant( minValue );
1126 else if ( testValue >= maxValue )
1128 return QVariant( maxValue );
1132 return QVariant( testValue );
1138 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1139 return QVariant( std::floor( x ) );
1144 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1145 return QVariant( std::ceil( x ) );
1150 return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
1154 return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
1158 return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
1163 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1164 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1165 if ( format.isEmpty() && !language.isEmpty() )
1167 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to DateTime when the language is specified" ) );
1168 return QVariant( QDateTime() );
1171 if ( format.isEmpty() && language.isEmpty() )
1172 return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
1174 QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1175 QLocale locale = QLocale();
1176 if ( !language.isEmpty() )
1178 locale = QLocale( language );
1181 QDateTime datetime = locale.toDateTime( datetimestring, format );
1182 if ( !datetime.isValid() )
1184 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
1185 datetime = QDateTime();
1187 return QVariant( datetime );
1192 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1193 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1194 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1196 const QDate date( year, month, day );
1197 if ( !date.isValid() )
1199 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1202 return QVariant( date );
1207 const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1208 const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1209 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1211 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1212 if ( !time.isValid() )
1214 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1217 return QVariant( time );
1222 const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1223 const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1224 const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1225 const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1226 const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1227 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1229 const QDate date( year, month, day );
1230 if ( !date.isValid() )
1232 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
1235 const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
1236 if ( !time.isValid() )
1238 parent->
setEvalErrorString( QObject::tr(
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
1241 return QVariant( QDateTime( date, time ) );
1246 const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
1247 const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
1248 const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
1249 const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
1250 const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
1251 const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
1252 const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1254 return QVariant::fromValue(
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1259 for (
const QVariant &value : values )
1261 if ( value.isNull() )
1270 const QVariant val1 = values.at( 0 );
1271 const QVariant val2 = values.at( 1 );
1281 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1282 return QVariant(
str.toLower() );
1286 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1287 return QVariant(
str.toUpper() );
1291 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1292 QStringList elems =
str.split(
' ' );
1293 for (
int i = 0; i < elems.size(); i++ )
1295 if ( elems[i].size() > 1 )
1296 elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
1298 return QVariant( elems.join( QLatin1Char(
' ' ) ) );
1303 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1304 return QVariant(
str.trimmed() );
1309 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1310 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1316 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1317 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1323 QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1324 QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1331 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1337 QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
1338 return QVariant( QString( character ) );
1343 QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1345 if ( value.isEmpty() )
1350 int res = value.at( 0 ).unicode();
1351 return QVariant( res );
1356 if ( values.length() == 2 || values.length() == 3 )
1358 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1359 qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1361 QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1375 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1379 return QVariant( geom.
length() );
1383 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1384 return QVariant(
str.length() );
1389 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
1394 double totalLength = 0;
1397 if (
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
1399 totalLength += line->length3D();
1403 std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
1404 totalLength += segmentized->length3D();
1413 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
1415 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1416 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
1417 QVector< QPair< QString, QString > > mapItems;
1419 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1421 mapItems.append( qMakePair( it.key(), it.value().toString() ) );
1425 std::sort( mapItems.begin(),
1427 [](
const QPair< QString, QString > &pair1,
1428 const QPair< QString, QString > &pair2 )
1430 return ( pair1.first.length() > pair2.first.length() );
1433 for (
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
1435 str =
str.replace( it->first, it->second );
1438 return QVariant(
str );
1440 else if ( values.count() == 3 )
1442 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1443 QVariantList before;
1445 bool isSingleReplacement =
false;
1447 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
1449 before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1453 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
1456 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
1458 after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1459 isSingleReplacement =
true;
1463 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
1466 if ( !isSingleReplacement && before.length() != after.length() )
1468 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
1472 for (
int i = 0; i < before.length(); i++ )
1474 str =
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
1477 return QVariant(
str );
1481 parent->
setEvalErrorString( QObject::tr(
"Function replace requires 2 or 3 arguments" ) );
1488 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1489 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1490 QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1492 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1493 if ( !re.isValid() )
1495 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1498 return QVariant(
str.replace( re, after ) );
1503 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1504 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1506 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1507 if ( !re.isValid() )
1509 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1512 return QVariant( (
str.indexOf( re ) + 1 ) );
1517 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1518 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1519 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
1521 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1522 if ( !re.isValid() )
1524 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1528 QRegularExpressionMatch matches = re.match(
str );
1529 if ( matches.hasMatch() )
1532 QStringList list = matches.capturedTexts();
1535 for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
1537 array += ( !( *it ).isEmpty() ) ? *it : empty;
1540 return QVariant( array );
1550 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1551 QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1553 QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
1554 if ( !re.isValid() )
1556 parent->
setEvalErrorString( QObject::tr(
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
1561 QRegularExpressionMatch match = re.match(
str );
1562 if ( match.hasMatch() )
1565 if ( match.lastCapturedIndex() > 0 )
1568 return QVariant( match.captured( 1 ) );
1573 return QVariant( match.captured( 0 ) );
1578 return QVariant(
"" );
1584 QString uuid = QUuid::createUuid().toString();
1585 if ( values.at( 0 ).toString().compare( QStringLiteral(
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
1586 uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
1587 else if ( values.at( 0 ).toString().compare( QStringLiteral(
"Id128" ), Qt::CaseInsensitive ) == 0 )
1588 uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
1594 if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
1597 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1598 int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1601 if ( values.at( 2 ).isValid() )
1602 len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
1608 from =
str.size() + from;
1614 else if ( from > 0 )
1622 len =
str.size() + len - from;
1629 return QVariant(
str.mid( from, len ) );
1635 return QVariant(
static_cast< int >( f.
id() ) );
1640 QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
1643 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster layer." ) );
1647 int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
1648 if ( bandNb < 1 || bandNb > layer->
bandCount() )
1650 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid raster band number." ) );
1654 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
1657 parent->
setEvalErrorString( QObject::tr(
"Function `raster_value` requires a valid point geometry." ) );
1665 if ( multiPoint.count() == 1 )
1667 point = multiPoint[0];
1677 return std::isnan( value ) ? QVariant() : value;
1692 if ( values.size() == 1 )
1694 attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
1697 else if ( values.size() == 2 )
1699 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1700 attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
1704 parent->
setEvalErrorString( QObject::tr(
"Function `attribute` requires one or two parameters. %n given.",
nullptr, values.length() ) );
1714 if ( values.size() == 0 || values.at( 0 ).isNull() )
1720 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1725 for (
int i = 0; i < fields.
count(); ++i )
1737 if ( values.isEmpty() )
1740 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1742 else if ( values.size() == 1 )
1744 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1745 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1747 else if ( values.size() == 2 )
1749 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1750 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1754 parent->
setEvalErrorString( QObject::tr(
"Function `represent_attributes` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1760 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: layer could not be resolved." ) );
1766 parent->
setEvalErrorString( QObject::tr(
"Cannot use represent attributes function: feature could not be resolved." ) );
1772 for (
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
1774 const QString fieldName { fields.
at( fieldIndex ).
name() };
1775 const QVariant attributeVal = feature.
attribute( fieldIndex );
1776 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
1779 result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
1788 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
1800 QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
1802 result.insert( fields.
at( fieldIndex ).
name(), value );
1818 bool evaluate =
true;
1820 if ( values.isEmpty() )
1823 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1825 else if ( values.size() == 1 )
1827 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1828 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1830 else if ( values.size() == 2 )
1832 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1833 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1835 else if ( values.size() == 3 )
1837 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1838 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1839 evaluate = values.value( 2 ).toBool();
1845 parent->
setEvalErrorString( QObject::tr(
"Function `maptip` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1849 parent->
setEvalErrorString( QObject::tr(
"Function `display` requires no more than three parameters. %n given.",
nullptr, values.length() ) );
1880 subContext.setFeature( feature );
1889 exp.prepare( &subContext );
1890 return exp.evaluate( &subContext ).toString();
1896 return fcnCoreFeatureMaptipDisplay( values, context, parent,
false );
1901 return fcnCoreFeatureMaptipDisplay( values, context, parent,
true );
1909 if ( values.isEmpty() )
1912 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1914 else if ( values.size() == 1 )
1916 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1917 feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
1919 else if ( values.size() == 2 )
1921 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1922 feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
1926 parent->
setEvalErrorString( QObject::tr(
"Function `is_selected` requires no more than two parameters. %n given.",
nullptr, values.length() ) );
1930 if ( !layer || !feature.
isValid() )
1932 return QVariant( QVariant::Bool );
1942 if ( values.isEmpty() )
1943 layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
1944 else if ( values.count() == 1 )
1945 layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1948 parent->
setEvalErrorString( QObject::tr(
"Function `num_selected` requires no more than one parameter. %n given.",
nullptr, values.length() ) );
1954 return QVariant( QVariant::LongLong );
1962 static QMap<QString, qlonglong> counterCache;
1963 QVariant functionResult;
1965 std::function<void()> fetchAndIncrementFunc = [ =, &functionResult ]()
1968 const QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
1973 database = decodedUri.value( QStringLiteral(
"path" ) ).toString();
1974 if ( database.isEmpty() )
1976 parent->
setEvalErrorString( QObject::tr(
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
1981 database = values.at( 0 ).toString();
1984 const QString table = values.at( 1 ).toString();
1985 const QString idColumn = values.at( 2 ).toString();
1986 const QString filterAttribute = values.at( 3 ).toString();
1987 const QVariant filterValue = values.at( 4 ).toString();
1988 const QVariantMap defaultValues = values.at( 5 ).toMap();
1994 if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE,
nullptr ) != SQLITE_OK )
1997 functionResult = QVariant();
2001 QString errorMessage;
2002 QString currentValSql;
2004 qlonglong nextId = 0;
2005 bool cachedMode =
false;
2006 bool valueRetrieved =
false;
2008 QString cacheString = QStringLiteral(
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
2015 auto cachedCounter = counterCache.find( cacheString );
2017 if ( cachedCounter != counterCache.end() )
2019 qlonglong &cachedValue = cachedCounter.value();
2020 nextId = cachedValue;
2022 cachedValue = nextId;
2023 valueRetrieved =
true;
2028 if ( !cachedMode || !valueRetrieved )
2030 int result = SQLITE_ERROR;
2033 if ( !filterAttribute.isNull() )
2038 sqliteStatement = sqliteDb.
prepare( currentValSql, result );
2040 if ( result == SQLITE_OK )
2043 if ( sqliteStatement.
step() == SQLITE_ROW )
2049 if ( cachedMode && result == SQLITE_OK )
2051 counterCache.insert( cacheString, nextId );
2055 counterCache.remove( cacheString );
2058 valueRetrieved =
true;
2062 if ( valueRetrieved )
2071 if ( !filterAttribute.isNull() )
2077 for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
2080 vals << iter.value().toString();
2083 upsertSql += QLatin1String(
" (" ) + cols.join(
',' ) +
')';
2084 upsertSql += QLatin1String(
" VALUES " );
2085 upsertSql +=
'(' + vals.join(
',' ) +
')';
2087 int result = SQLITE_ERROR;
2091 if ( transaction->
executeSql( upsertSql, errorMessage ) )
2098 result = sqliteDb.
exec( upsertSql, errorMessage );
2100 if ( result == SQLITE_OK )
2102 functionResult = QVariant( nextId );
2107 parent->
setEvalErrorString( QStringLiteral(
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
2108 functionResult = QVariant();
2113 functionResult = QVariant();
2118 return functionResult;
2124 for (
const QVariant &value : values )
2126 if ( !value.isNull() )
2127 concat += QgsExpressionUtils::getStringValue( value, parent );
2134 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2135 return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
2140 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2141 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2142 return string.right( pos );
2147 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2148 int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2149 return string.left( pos );
2154 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2155 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2156 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2157 return string.leftJustified( length, fill.at( 0 ),
true );
2162 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2163 int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2164 QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2165 return string.rightJustified( length, fill.at( 0 ),
true );
2170 if ( values.size() < 1 )
2172 parent->
setEvalErrorString( QObject::tr(
"Function format requires at least 1 argument" ) );
2176 QString
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2177 for (
int n = 1; n < values.length(); n++ )
2179 string =
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
2187 return QVariant( QDateTime::currentDateTime() );
2192 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2193 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2194 if ( format.isEmpty() && !language.isEmpty() )
2196 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Date when the language is specified" ) );
2197 return QVariant( QDate() );
2200 if ( format.isEmpty() && language.isEmpty() )
2201 return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
2203 QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2204 QLocale locale = QLocale();
2205 if ( !language.isEmpty() )
2207 locale = QLocale( language );
2210 QDate date = locale.toDate( datestring, format );
2211 if ( !date.isValid() )
2213 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( datestring ) );
2216 return QVariant( date );
2221 QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2222 QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
2223 if ( format.isEmpty() && !language.isEmpty() )
2225 parent->
setEvalErrorString( QObject::tr(
"A format is required to convert to Time when the language is specified" ) );
2226 return QVariant( QTime() );
2229 if ( format.isEmpty() && language.isEmpty() )
2230 return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
2232 QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
2233 QLocale locale = QLocale();
2234 if ( !language.isEmpty() )
2236 locale = QLocale( language );
2239 QTime time = locale.toTime( timestring, format );
2240 if ( !time.isValid() )
2242 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( timestring ) );
2245 return QVariant( time );
2250 return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
2259 double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
2260 QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2261 int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
2263 QString formatString;
2264 if ( values.count() > 3 )
2265 formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
2267 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
2268 if ( formatString.compare( QLatin1String(
"suffix" ), Qt::CaseInsensitive ) == 0 )
2272 else if ( formatString.compare( QLatin1String(
"aligned" ), Qt::CaseInsensitive ) == 0 )
2276 else if ( ! formatString.isEmpty() )
2278 parent->
setEvalErrorString( QObject::tr(
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
2282 if ( axis.compare( QLatin1String(
"x" ), Qt::CaseInsensitive ) == 0 )
2286 else if ( axis.compare( QLatin1String(
"y" ), Qt::CaseInsensitive ) == 0 )
2292 parent->
setEvalErrorString( QObject::tr(
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
2300 return floatToDegreeFormat( format, values, context, parent, node );
2307 value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
2309 return ok ? QVariant( value ) : QVariant();
2315 return floatToDegreeFormat( format, values, context, parent, node );
2320 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2321 QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
2322 qint64 seconds = d2.secsTo( d1 );
2323 return QVariant::fromValue(
QgsInterval( seconds ) );
2328 if ( !values.at( 0 ).canConvert<QDate>() )
2331 QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
2332 if ( !date.isValid() )
2337 return date.dayOfWeek() % 7;
2342 QVariant value = values.at( 0 );
2343 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2346 return QVariant( inter.
days() );
2350 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2351 return QVariant( d1.date().day() );
2357 QVariant value = values.at( 0 );
2358 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2361 return QVariant( inter.
years() );
2365 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2366 return QVariant( d1.date().year() );
2372 QVariant value = values.at( 0 );
2373 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2376 return QVariant( inter.
months() );
2380 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2381 return QVariant( d1.date().month() );
2387 QVariant value = values.at( 0 );
2388 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2391 return QVariant( inter.
weeks() );
2395 QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
2396 return QVariant( d1.date().weekNumber() );
2402 QVariant value = values.at( 0 );
2403 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2406 return QVariant( inter.
hours() );
2410 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2411 return QVariant( t1.hour() );
2417 QVariant value = values.at( 0 );
2418 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2421 return QVariant( inter.
minutes() );
2425 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2426 return QVariant( t1.minute() );
2432 QVariant value = values.at( 0 );
2433 QgsInterval inter = QgsExpressionUtils::getInterval( value, parent,
false );
2436 return QVariant( inter.
seconds() );
2440 QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
2441 return QVariant( t1.second() );
2447 QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
2450 return QVariant( dt.toMSecsSinceEpoch() );
2460 long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
2462 return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
2467 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2470 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"exif" ) ) );
2473 QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
2479 const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
2482 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"exif_geotag" ) ) );
2489 #define ENSURE_GEOM_TYPE(f, g, geomtype) \
2490 if ( !(f).hasGeometry() ) \
2491 return QVariant(); \
2492 QgsGeometry g = (f).geometry(); \
2493 if ( (g).type() != (geomtype) ) \
2500 if ( g.isMultipart() )
2502 return g.asMultiPoint().at( 0 ).x();
2506 return g.asPoint().x();
2514 if ( g.isMultipart() )
2516 return g.asMultiPoint().at( 0 ).y();
2520 return g.asPoint().y();
2534 if ( g.isEmpty() || !abGeom->
is3D() )
2539 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
2545 if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
2547 if ( collection->numGeometries() > 0 )
2549 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2560 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2566 return QVariant( isValid );
2571 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2583 QVariant result(
centroid.asPoint().
x() );
2589 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2601 QVariant result(
centroid.asPoint().
y() );
2607 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2617 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2625 if ( collection->numGeometries() == 1 )
2627 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2638 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2648 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
2656 if ( collection->numGeometries() == 1 )
2658 if (
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
2669 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2674 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
2701 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2718 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2735 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2740 bool ignoreClosing =
false;
2741 if ( values.length() > 1 )
2743 ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
2753 bool skipLast =
false;
2754 if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
2759 for (
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
2771 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2782 for (
int i = 0; i < line->numPoints() - 1; ++i )
2786 << line->pointN( i )
2787 << line->pointN( i + 1 ) );
2798 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2808 if ( collection->numGeometries() == 1 )
2810 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
2815 if ( !curvePolygon )
2819 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2825 QVariant result = curve ? QVariant::fromValue(
QgsGeometry( curve ) ) : QVariant();
2831 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2841 qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
2847 QVariant result = part ? QVariant::fromValue(
QgsGeometry( part ) ) : QVariant();
2853 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2862 return QVariant::fromValue(
QgsGeometry( boundary ) );
2867 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2876 return QVariant::fromValue( merged );
2881 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2886 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2889 if ( simplified.
isNull() )
2897 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2902 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2907 if ( simplified.
isNull() )
2915 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2920 int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
2921 double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
2922 double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2923 double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
2925 QgsGeometry smoothed = geom.
smooth(
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
2934 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2939 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2940 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2941 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
2952 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2957 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2958 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2959 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2960 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
2961 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
2964 minAmplitude, maxAmplitude, seed );
2973 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2978 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2979 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2980 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
2991 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2996 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2997 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2998 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2999 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3000 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3003 minAmplitude, maxAmplitude, seed );
3012 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3017 const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3018 const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3019 const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
3030 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3035 const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3036 const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3037 const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3038 const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
3039 const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
3042 minAmplitude, maxAmplitude, seed );
3051 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3056 const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
3057 QVector< double > dashPattern;
3058 dashPattern.reserve( pattern.size() );
3059 for (
const QVariant &value : std::as_const( pattern ) )
3062 double v = value.toDouble( &ok );
3069 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must be an array of numbers" ) );
3074 if ( dashPattern.size() % 2 != 0 )
3076 parent->
setEvalErrorString( QStringLiteral(
"Dash pattern must contain an even number of elements" ) );
3080 const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
3082 if ( startRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3084 else if ( startRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3086 else if ( startRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3088 else if ( startRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3090 else if ( startRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3094 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
3098 const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
3100 if ( endRuleString.compare( QLatin1String(
"no_rule" ), Qt::CaseInsensitive ) == 0 )
3102 else if ( endRuleString.compare( QLatin1String(
"full_dash" ), Qt::CaseInsensitive ) == 0 )
3104 else if ( endRuleString.compare( QLatin1String(
"half_dash" ), Qt::CaseInsensitive ) == 0 )
3106 else if ( endRuleString.compare( QLatin1String(
"full_gap" ), Qt::CaseInsensitive ) == 0 )
3108 else if ( endRuleString.compare( QLatin1String(
"half_gap" ), Qt::CaseInsensitive ) == 0 )
3112 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
3116 const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
3118 if ( adjustString.compare( QLatin1String(
"both" ), Qt::CaseInsensitive ) == 0 )
3120 else if ( adjustString.compare( QLatin1String(
"dash" ), Qt::CaseInsensitive ) == 0 )
3122 else if ( adjustString.compare( QLatin1String(
"gap" ), Qt::CaseInsensitive ) == 0 )
3126 parent->
setEvalErrorString( QStringLiteral(
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
3130 const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
3141 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3146 const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3148 if ( densified.
isNull() )
3156 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3161 const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3163 if ( densified.
isNull() )
3172 if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
3174 list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3181 QVector< QgsGeometry > parts;
3182 parts.reserve( list.size() );
3183 for (
const QVariant &value : std::as_const( list ) )
3201 if ( values.count() < 2 || values.count() > 4 )
3203 parent->
setEvalErrorString( QObject::tr(
"Function make_point requires 2-4 arguments" ) );
3207 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3208 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3209 double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
3210 double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
3211 switch ( values.count() )
3225 double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
3226 double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3227 double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3233 if ( values.empty() )
3238 QVector<QgsPoint> points;
3239 points.reserve( values.count() );
3241 auto addPoint = [&points](
const QgsGeometry & geom )
3249 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3256 for (
const QVariant &value : values )
3258 if ( value.type() == QVariant::List )
3260 const QVariantList list = value.toList();
3261 for (
const QVariant &v : list )
3263 addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
3268 addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
3272 if ( points.count() < 2 )
3280 if ( values.count() < 1 )
3282 parent->
setEvalErrorString( QObject::tr(
"Function make_polygon requires an argument" ) );
3286 QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3294 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
3296 const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
3303 exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3308 if ( !exteriorRing )
3311 polygon->setExteriorRing( exteriorRing->
segmentize() );
3314 for (
int i = 1; i < values.count(); ++i )
3316 QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
3323 const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
3330 ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
3338 polygon->addInteriorRing( ring->
segmentize() );
3341 return QVariant::fromValue(
QgsGeometry( std::move( polygon ) ) );
3346 std::unique_ptr<QgsTriangle> tr(
new QgsTriangle() );
3347 std::unique_ptr<QgsLineString> lineString(
new QgsLineString() );
3348 lineString->clear();
3350 for (
const QVariant &value : values )
3352 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
3359 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3366 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3374 lineString->addVertex( *point );
3377 tr->setExteriorRing( lineString.release() );
3379 return QVariant::fromValue(
QgsGeometry( tr.release() ) );
3384 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3391 double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3392 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
3399 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3406 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3414 return QVariant::fromValue(
QgsGeometry( circ.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3419 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3426 double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
3427 double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
3428 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
3429 int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
3435 const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
3442 point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3449 QgsEllipse elp( *point, majorAxis, minorAxis, azimuth );
3450 return QVariant::fromValue(
QgsGeometry( elp.toPolygon(
static_cast<unsigned int>(
segment ) ) ) );
3456 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3463 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3470 unsigned int nbEdges =
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
3473 parent->
setEvalErrorString( QObject::tr(
"Number of edges/sides must be greater than 2" ) );
3480 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
3484 const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
3491 center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3498 const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
3505 corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
3520 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3526 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3532 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3533 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3541 QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3547 QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
3553 QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
3562 parent->
setEvalErrorString( QObject::tr(
"Option can be 0 (distance) or 1 (projected)" ) );
3565 const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
3566 const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
3567 const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
3575 int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
3591 return QVariant( QPointF( p.
x(), p.
y() ) );
3596 QVariant v = pointAt( values, f, parent );
3597 if ( v.type() == QVariant::PointF )
3598 return QVariant( v.toPointF().x() );
3604 QVariant v = pointAt( values, f, parent );
3605 if ( v.type() == QVariant::PointF )
3606 return QVariant( v.toPointF().y() );
3623 return QVariant::fromValue( geom );
3631 QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3633 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3639 const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
3645 return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3650 QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
3657 ogcContext.
layer = mapLayerPtr.data();
3658 ogcContext.
transformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
3662 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
3675 return QVariant( area );
3685 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3690 return QVariant( geom.
area() );
3702 return QVariant( len );
3719 return QVariant( len );
3723 return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
3729 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3735 return QVariant( geom.
length() );
3740 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3746 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3755 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3764 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3779 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
3780 if ( !curvePolygon )
3792 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3799 return QVariant( curvePolygon->
ringCount() );
3801 bool foundPoly =
false;
3809 curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
3810 if ( !curvePolygon )
3821 return QVariant( ringCount );
3826 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3828 QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
3834 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3840 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3846 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3855 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3861 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3867 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3873 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3879 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3887 double max = std::numeric_limits< double >::lowest();
3891 double z = ( *it ).z();
3897 if ( max == std::numeric_limits< double >::lowest() )
3898 return QVariant( QVariant::Double );
3900 return QVariant( max );
3905 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3913 double min = std::numeric_limits< double >::max();
3917 double z = ( *it ).z();
3923 if ( min == std::numeric_limits< double >::max() )
3924 return QVariant( QVariant::Double );
3926 return QVariant( min );
3931 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3939 double min = std::numeric_limits< double >::max();
3943 double m = ( *it ).m();
3949 if ( min == std::numeric_limits< double >::max() )
3950 return QVariant( QVariant::Double );
3952 return QVariant( min );
3957 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3965 double max = std::numeric_limits< double >::lowest();
3969 double m = ( *it ).m();
3975 if ( max == std::numeric_limits< double >::lowest() )
3976 return QVariant( QVariant::Double );
3978 return QVariant( max );
3983 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
3984 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
3987 parent->
setEvalErrorString( QObject::tr(
"Function `sinuosity` requires a line geometry." ) );
3996 const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4000 parent->
setEvalErrorString( QObject::tr(
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
4009 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4014 parent->
setEvalErrorString( QObject::tr(
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
4025 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4029 std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
4031 return QVariant::fromValue(
QgsGeometry( std::move( flipped ) ) );
4036 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4040 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
4047 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4055 return QVariant::fromValue( curve->
isClosed() );
4060 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4073 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4074 closedLine->close();
4076 result = QVariant::fromValue(
QgsGeometry( std::move( closedLine ) ) );
4086 if (
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
4088 std::unique_ptr< QgsLineString > closedLine( line->
clone() );
4089 closedLine->close();
4091 closed->addGeometry( closedLine.release() );
4094 result = QVariant::fromValue(
QgsGeometry( std::move( closed ) ) );
4102 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4106 return QVariant::fromValue( fGeom.
isEmpty() );
4111 if ( values.at( 0 ).isNull() )
4112 return QVariant::fromValue(
true );
4114 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4115 return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
4120 if ( values.length() < 2 || values.length() > 3 )
4123 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4124 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4131 if ( values.length() == 2 )
4134 QString result = engine->relate( sGeom.
constGet() );
4135 return QVariant::fromValue( result );
4140 QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
4141 bool result = engine->relatePattern( sGeom.
constGet(), pattern );
4142 return QVariant::fromValue( result );
4148 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4149 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4154 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4155 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4156 return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
4160 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4161 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4162 return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
4166 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4167 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4168 return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
4172 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4173 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4174 return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
4178 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4179 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4180 return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
4184 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4185 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4186 return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
4190 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4191 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4192 return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
4197 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4198 const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4199 const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4200 const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
4201 const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
4202 const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4205 if ( endCapString.compare( QLatin1String(
"flat" ), Qt::CaseInsensitive ) == 0 )
4206 capStyle = Qgis::EndCapStyle::Flat;
4207 else if ( endCapString.compare( QLatin1String(
"square" ), Qt::CaseInsensitive ) == 0 )
4208 capStyle = Qgis::EndCapStyle::Square;
4211 if ( joinString.compare( QLatin1String(
"miter" ), Qt::CaseInsensitive ) == 0 )
4212 joinStyle = Qgis::JoinStyle::Miter;
4213 else if ( joinString.compare( QLatin1String(
"bevel" ), Qt::CaseInsensitive ) == 0 )
4214 joinStyle = Qgis::JoinStyle::Bevel;
4217 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4223 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4225 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4230 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4232 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4237 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4239 return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
4244 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4245 const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
4252 pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4259 parent->
setEvalErrorString( QObject::tr(
"Function `wedge_buffer` requires a point value for the center." ) );
4263 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4264 double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4265 double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4266 double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4269 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4275 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4278 parent->
setEvalErrorString( QObject::tr(
"Function `tapered_buffer` requires a line geometry." ) );
4282 double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4283 double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4284 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
4287 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4293 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4296 parent->
setEvalErrorString( QObject::tr(
"Function `buffer_by_m` requires a line geometry." ) );
4300 int segments =
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
4303 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4309 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4310 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4311 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4312 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4313 if ( joinInt < 1 || joinInt > 3 )
4317 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4320 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4326 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4327 double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4328 int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
4330 const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
4331 if ( joinInt < 1 || joinInt > 3 )
4335 double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4338 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4344 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4345 double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4346 double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4349 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4355 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4356 double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4357 double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4359 return QVariant::fromValue( fGeom );
4364 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4365 const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4366 const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
4368 const bool perPart = values.value( 3 ).toBool();
4375 std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
4378 const QgsPointXY partCenter = ( *it )->boundingBox().center();
4379 QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
4380 t.rotate( -rotation );
4381 t.translate( -partCenter.
x(), -partCenter.
y() );
4382 ( *it )->transform( t );
4384 return QVariant::fromValue(
QgsGeometry( std::move( collection ) ) );
4396 parent->
setEvalErrorString( QObject::tr(
"Function 'rotate' requires a point value for the center" ) );
4404 fGeom.
rotate( rotation, pt );
4405 return QVariant::fromValue( fGeom );
4411 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4412 const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4413 const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4414 const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
4425 parent->
setEvalErrorString( QObject::tr(
"Function 'scale' requires a point value for the center" ) );
4433 QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
4434 t.scale( xScale, yScale );
4435 t.translate( -pt.
x(), -pt.
y() );
4437 return QVariant::fromValue( fGeom );
4442 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4448 const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4449 const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4451 const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4453 const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
4454 const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
4456 const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
4457 const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
4458 const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
4459 const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
4470 QTransform transform;
4471 transform.translate( deltaX, deltaY );
4472 transform.rotate( rotationZ );
4473 transform.scale( scaleX, scaleY );
4474 fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
4476 return QVariant::fromValue( fGeom );
4482 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4484 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4489 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4491 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4497 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4498 double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4500 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4506 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4508 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4515 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4517 if ( values.length() == 2 )
4518 segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4526 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4532 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4534 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4540 const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4546 double area,
angle, width, height;
4559 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4560 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4562 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4568 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4575 const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
4580 result = reversed ? QVariant::fromValue(
QgsGeometry( reversed ) ) : QVariant();
4588 if (
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
4590 reversed->addGeometry( curve->
reversed() );
4597 result = reversed ? QVariant::fromValue(
QgsGeometry( std::move( reversed ) ) ) : QVariant();
4604 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4615 curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
4624 QVariant result = exterior ? QVariant::fromValue(
QgsGeometry( exterior ) ) : QVariant();
4630 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4631 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4632 return QVariant( fGeom.
distance( sGeom ) );
4637 QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4638 QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4641 if ( values.length() == 3 && values.at( 2 ).isValid() )
4643 double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4644 densify = std::clamp( densify, 0.0, 1.0 );
4652 return res > -1 ? QVariant( res ) : QVariant();
4657 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4658 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4660 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4665 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4666 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4668 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4673 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4674 QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4676 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4682 if ( values.length() < 1 || values.length() > 2 )
4685 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4687 if ( values.length() == 2 )
4688 prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
4689 QString wkt = fGeom.
asWkt( prec );
4690 return QVariant( wkt );
4695 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4696 return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
4701 if ( values.length() != 2 )
4703 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires exactly two parameters. %n given.",
nullptr, values.length() ) );
4707 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4708 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4710 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4717 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4722 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4729 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4736 parent->
setEvalErrorString( QObject::tr(
"Function `azimuth` requires two points as arguments." ) );
4743 if ( pt1->
y() < pt2->
y() )
4745 else if ( pt1->
y() > pt2->
y() )
4753 if ( pt1->
x() < pt2->
x() )
4755 else if ( pt1->
x() > pt2->
x() )
4756 return M_PI + ( M_PI_2 );
4761 if ( pt1->
x() < pt2->
x() )
4763 if ( pt1->
y() < pt2->
y() )
4765 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
4769 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4776 if ( pt1->
y() > pt2->
y() )
4778 return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
4783 return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
4784 + ( M_PI + ( M_PI_2 ) );
4791 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4795 parent->
setEvalErrorString( QStringLiteral(
"'project' requires a point geometry" ) );
4799 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4800 double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4801 double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
4804 QgsPoint newPoint = p->
project( distance, 180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
4811 QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4812 QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4814 const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
4821 pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4825 const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
4832 pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
4840 parent->
setEvalErrorString( QStringLiteral(
"Function 'inclination' requires two points as arguments." ) );
4850 if ( values.length() != 3 )
4853 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4854 double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4855 double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
4859 QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
4865 if ( values.length() < 2 )
4868 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4871 return values.at( 0 );
4873 QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
4874 QVariant cachedExpression;
4879 if ( cachedExpression.isValid() )
4886 bool asc = values.value( 2 ).toBool();
4904 Q_ASSERT( collection );
4908 QgsExpressionSorter sorter( orderBy );
4910 QList<QgsFeature> partFeatures;
4911 partFeatures.reserve( collection->
partCount() );
4912 for (
int i = 0; i < collection->
partCount(); ++i )
4918 sorter.sortFeatures( partFeatures, unconstedContext );
4922 Q_ASSERT( orderedGeom );
4927 for (
const QgsFeature &feature : std::as_const( partFeatures ) )
4932 QVariant result = QVariant::fromValue(
QgsGeometry( orderedGeom ) );
4935 delete unconstedContext;
4942 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4943 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4947 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4953 QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4954 QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
4958 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4964 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4965 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4969 QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
4975 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
4978 parent->
setEvalErrorString( QObject::tr(
"line_substring requires a curve geometry input" ) );
4984 curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
4991 curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
4998 double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
4999 double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5001 std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
5003 return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
5008 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5009 double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5016 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5017 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5022 vertex = count + vertex;
5030 QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5031 int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5036 vertex = count + vertex;
5044 QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5045 QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
5049 return distance >= 0 ? distance : QVariant();
5054 if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
5056 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5057 return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5060 if ( values.length() >= 1 )
5062 double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5063 return QVariant( qlonglong( std::round( number ) ) );
5078 const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
5079 const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5080 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5087 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5088 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5089 return locale.toString( value,
'f', places );
5094 const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
5095 const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5096 const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5098 QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
5099 return locale.toString( datetime, format );
5105 int avg = ( color.red() + color.green() + color.blue() ) / 3;
5106 int alpha = color.alpha();
5108 color.setRgb( avg, avg, avg, alpha );
5117 double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
5122 else if ( ratio < 0 )
5127 int red =
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
5128 int green =
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
5129 int blue =
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
5130 int alpha =
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
5132 QColor newColor( red, green, blue, alpha );
5139 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5140 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5141 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5142 QColor color = QColor( red, green, blue );
5143 if ( ! color.isValid() )
5145 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
5146 color = QColor( 0, 0, 0 );
5149 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5154 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5155 QVariant value = node->
eval( parent, context );
5159 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5161 value = node->
eval( parent, context );
5169 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
5171 QVariant value = node->
eval( parent, context );
5173 if ( value.toBool() )
5175 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
5177 value = node->
eval( parent, context );
5182 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
5184 value = node->
eval( parent, context );
5192 int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
5193 int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5194 int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5195 int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
5196 QColor color = QColor( red, green, blue, alpha );
5197 if ( ! color.isValid() )
5199 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
5200 color = QColor( 0, 0, 0 );
5211 expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
5216 QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5220 parent->
setEvalErrorString( QObject::tr(
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
5225 double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
5226 QColor color = ramp->
color( value );
5233 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5235 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5237 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5239 QColor color = QColor::fromHslF( hue, saturation, lightness );
5241 if ( ! color.isValid() )
5243 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
5244 color = QColor( 0, 0, 0 );
5247 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5253 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5255 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5257 double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5259 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5261 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
5262 if ( ! color.isValid() )
5264 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
5265 color = QColor( 0, 0, 0 );
5273 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5275 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5277 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5279 QColor color = QColor::fromHsvF( hue, saturation, value );
5281 if ( ! color.isValid() )
5283 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
5284 color = QColor( 0, 0, 0 );
5287 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5293 double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
5295 double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5297 double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5299 double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
5301 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
5302 if ( ! color.isValid() )
5304 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
5305 color = QColor( 0, 0, 0 );
5313 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5315 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5317 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5319 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5321 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
5323 if ( ! color.isValid() )
5325 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
5326 color = QColor( 0, 0, 0 );
5329 return QStringLiteral(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
5335 double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
5337 double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
5339 double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
5341 double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
5343 double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
5345 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
5346 if ( ! color.isValid() )
5348 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
5349 color = QColor( 0, 0, 0 );
5357 if ( ! color.isValid() )
5359 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5363 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5364 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5366 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5367 return color.green();
5368 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5369 return color.blue();
5370 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5371 return color.alpha();
5372 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5373 return color.hsvHueF() * 360;
5374 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5375 return color.hsvSaturationF() * 100;
5376 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5377 return color.valueF() * 100;
5378 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5379 return color.hslHueF() * 360;
5380 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5381 return color.hslSaturationF() * 100;
5382 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5383 return color.lightnessF() * 100;
5384 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5385 return color.cyanF() * 100;
5386 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5387 return color.magentaF() * 100;
5388 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5389 return color.yellowF() * 100;
5390 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5391 return color.blackF() * 100;
5393 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5399 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
5400 if ( map.count() < 1 )
5402 parent->
setEvalErrorString( QObject::tr(
"A minimum of two colors is required to create a ramp" ) );
5406 QList< QColor > colors;
5408 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5411 if ( !colors.last().isValid() )
5413 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
5417 double step = it.key().toDouble();
5418 if ( it == map.constBegin() )
5423 else if ( it == map.constEnd() )
5433 bool discrete = values.at( 1 ).toBool();
5435 return QVariant::fromValue(
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
5441 if ( ! color.isValid() )
5443 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5447 QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5448 int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
5449 if ( part.compare( QLatin1String(
"red" ), Qt::CaseInsensitive ) == 0 )
5450 color.setRed( value );
5451 else if ( part.compare( QLatin1String(
"green" ), Qt::CaseInsensitive ) == 0 )
5452 color.setGreen( value );
5453 else if ( part.compare( QLatin1String(
"blue" ), Qt::CaseInsensitive ) == 0 )
5454 color.setBlue( value );
5455 else if ( part.compare( QLatin1String(
"alpha" ), Qt::CaseInsensitive ) == 0 )
5456 color.setAlpha( value );
5457 else if ( part.compare( QLatin1String(
"hue" ), Qt::CaseInsensitive ) == 0 )
5458 color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
5459 else if ( part.compare( QLatin1String(
"saturation" ), Qt::CaseInsensitive ) == 0 )
5460 color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
5461 else if ( part.compare( QLatin1String(
"value" ), Qt::CaseInsensitive ) == 0 )
5462 color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
5463 else if ( part.compare( QLatin1String(
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
5464 color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
5465 else if ( part.compare( QLatin1String(
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
5466 color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
5467 else if ( part.compare( QLatin1String(
"lightness" ), Qt::CaseInsensitive ) == 0 )
5468 color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
5469 else if ( part.compare( QLatin1String(
"cyan" ), Qt::CaseInsensitive ) == 0 )
5470 color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
5471 else if ( part.compare( QLatin1String(
"magenta" ), Qt::CaseInsensitive ) == 0 )
5472 color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
5473 else if ( part.compare( QLatin1String(
"yellow" ), Qt::CaseInsensitive ) == 0 )
5474 color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
5475 else if ( part.compare( QLatin1String(
"black" ), Qt::CaseInsensitive ) == 0 )
5476 color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
5479 parent->
setEvalErrorString( QObject::tr(
"Unknown color component '%1'" ).arg( part ) );
5488 if ( ! color.isValid() )
5490 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5494 color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5502 if ( ! color.isValid() )
5504 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
5508 color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
5515 QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
5518 return QVariant::fromValue( geom );
5524 QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
5525 QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5526 QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5530 return QVariant::fromValue( fGeom );
5533 return QVariant::fromValue( fGeom );
5542 return QVariant::fromValue( fGeom );
5556 QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( values.at( 0 ), parent );
5559 QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
5571 result = QVariant::fromValue( fet );
5581 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), parent );
5584 if ( !featureSource )
5589 QString cacheValueKey;
5590 if ( values.at( 1 ).type() == QVariant::Map )
5592 QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
5594 QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
5595 QString filterString;
5596 for ( ; i != attributeMap.constEnd(); ++i )
5598 if ( !filterString.isEmpty() )
5600 filterString.append(
" AND " );
5604 cacheValueKey = QStringLiteral(
"getfeature:%1:%2" ).arg( featureSource->id(), filterString );
5613 QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5614 int attributeId = featureSource->fields().lookupField( attribute );
5615 if ( attributeId == -1 )
5620 const QVariant &attVal = values.at( 2 );
5622 cacheValueKey = QStringLiteral(
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
5645 res = QVariant::fromValue( fet );
5660 if ( !values.isEmpty() )
5663 if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
5664 fieldName = col->
name();
5665 else if ( values.size() == 2 )
5666 fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5669 QVariant value = values.at( 0 );
5674 if ( fieldIndex == -1 )
5676 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: Field not found %2" ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5680 QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral(
"layer" ) ), parent );
5682 const QString cacheValueKey = QStringLiteral(
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName, value.toString() );
5691 const QString cacheKey = QStringLiteral(
"repvalfcn:%1:%2" ).arg( layer ? layer->
id() : QStringLiteral(
"[None]" ), fieldName );
5702 result =
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
5709 parent->
setEvalErrorString( QCoreApplication::translate(
"expression",
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral(
"represent_value" ), fieldName ) );
5717 const QVariant data = values.at( 0 );
5718 const QMimeDatabase db;
5719 return db.mimeTypeForData( data.toByteArray() ).name();
5724 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5730 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
5731 if ( QString::compare( layerProperty, QStringLiteral(
"name" ), Qt::CaseInsensitive ) == 0 )
5732 return layer->
name();
5733 else if ( QString::compare( layerProperty, QStringLiteral(
"id" ), Qt::CaseInsensitive ) == 0 )
5735 else if ( QString::compare( layerProperty, QStringLiteral(
"title" ), Qt::CaseInsensitive ) == 0 )
5737 else if ( QString::compare( layerProperty, QStringLiteral(
"abstract" ), Qt::CaseInsensitive ) == 0 )
5739 else if ( QString::compare( layerProperty, QStringLiteral(
"keywords" ), Qt::CaseInsensitive ) == 0 )
5741 QStringList keywords;
5743 for (
auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
5745 keywords.append( it.value() );
5747 if ( !keywords.isEmpty() )
5751 else if ( QString::compare( layerProperty, QStringLiteral(
"data_url" ), Qt::CaseInsensitive ) == 0 )
5753 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution" ), Qt::CaseInsensitive ) == 0 )
5757 else if ( QString::compare( layerProperty, QStringLiteral(
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
5759 else if ( QString::compare( layerProperty, QStringLiteral(
"source" ), Qt::CaseInsensitive ) == 0 )
5761 else if ( QString::compare( layerProperty, QStringLiteral(
"min_scale" ), Qt::CaseInsensitive ) == 0 )
5763 else if ( QString::compare( layerProperty, QStringLiteral(
"max_scale" ), Qt::CaseInsensitive ) == 0 )
5765 else if ( QString::compare( layerProperty, QStringLiteral(
"is_editable" ), Qt::CaseInsensitive ) == 0 )
5767 else if ( QString::compare( layerProperty, QStringLiteral(
"crs" ), Qt::CaseInsensitive ) == 0 )
5769 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
5771 else if ( QString::compare( layerProperty, QStringLiteral(
"crs_description" ), Qt::CaseInsensitive ) == 0 )
5773 else if ( QString::compare( layerProperty, QStringLiteral(
"extent" ), Qt::CaseInsensitive ) == 0 )
5776 QVariant result = QVariant::fromValue( extentGeom );
5779 else if ( QString::compare( layerProperty, QStringLiteral(
"distance_units" ), Qt::CaseInsensitive ) == 0 )
5781 else if ( QString::compare( layerProperty, QStringLiteral(
"type" ), Qt::CaseInsensitive ) == 0 )
5783 switch ( layer->
type() )
5786 return QCoreApplication::translate(
"expressions",
"Vector" );
5788 return QCoreApplication::translate(
"expressions",
"Raster" );
5790 return QCoreApplication::translate(
"expressions",
"Mesh" );
5792 return QCoreApplication::translate(
"expressions",
"Vector Tile" );
5794 return QCoreApplication::translate(
"expressions",
"Plugin" );
5796 return QCoreApplication::translate(
"expressions",
"Annotation" );
5798 return QCoreApplication::translate(
"expressions",
"Point Cloud" );
5800 return QCoreApplication::translate(
"expressions",
"Group" );
5806 QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
5809 if ( QString::compare( layerProperty, QStringLiteral(
"storage_type" ), Qt::CaseInsensitive ) == 0 )
5811 else if ( QString::compare( layerProperty, QStringLiteral(
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
5813 else if ( QString::compare( layerProperty, QStringLiteral(
"feature_count" ), Qt::CaseInsensitive ) == 0 )
5815 else if ( QString::compare( layerProperty, QStringLiteral(
"path" ), Qt::CaseInsensitive ) == 0 )
5820 return decodedUri.value( QStringLiteral(
"path" ) );
5831 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
5834 parent->
setEvalErrorString( QObject::tr(
"Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
5844 const QString uriPart = values.at( 1 ).toString();
5848 if ( !uriPart.isNull() )
5850 return decodedUri.value( values.at( 1 ).toString() );
5860 QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
5867 if ( !layersByName.isEmpty() )
5869 layer = layersByName.at( 0 );
5880 int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5881 if ( band < 1 || band > rl->
bandCount() )
5883 parent->
setEvalErrorString( QObject::tr(
"Invalid band number %1 for layer %2" ).arg( band ).arg( layerIdOrName ) );
5887 QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
5890 if ( QString::compare( layerProperty, QStringLiteral(
"avg" ), Qt::CaseInsensitive ) == 0 )
5892 else if ( QString::compare( layerProperty, QStringLiteral(
"stdev" ), Qt::CaseInsensitive ) == 0 )
5894 else if ( QString::compare( layerProperty, QStringLiteral(
"min" ), Qt::CaseInsensitive ) == 0 )
5896 else if ( QString::compare( layerProperty, QStringLiteral(
"max" ), Qt::CaseInsensitive ) == 0 )
5898 else if ( QString::compare( layerProperty, QStringLiteral(
"range" ), Qt::CaseInsensitive ) == 0 )
5900 else if ( QString::compare( layerProperty, QStringLiteral(
"sum" ), Qt::CaseInsensitive ) == 0 )
5904 parent->
setEvalErrorString( QObject::tr(
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
5934 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5935 bool ascending = values.value( 1 ).toBool();
5936 std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) ->
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
5942 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
5947 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
5952 return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
5957 QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5958 QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
5960 for (
const auto &item : listB )
5962 if ( listA.contains( item ) )
5966 return QVariant( match == listB.count() );
5971 return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
5976 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5977 const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
5978 if ( pos < list.length() && pos >= 0 )
return list.at( pos );
5979 else if ( pos < 0 && ( list.length() + pos ) >= 0 )
5980 return list.at( list.length() + pos );
5986 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5987 return list.value( 0 );
5992 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5993 return list.value( list.size() - 1 );
5998 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
5999 return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
6004 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6005 return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return (
qgsVariantLessThan( a, b ) ); } );
6010 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6013 for (
const QVariant &item : list )
6015 switch ( item.userType() )
6017 case QMetaType::Int:
6018 case QMetaType::UInt:
6019 case QMetaType::LongLong:
6020 case QMetaType::ULongLong:
6021 case QMetaType::Float:
6022 case QMetaType::Double:
6023 total += item.toDouble();
6028 return i == 0 ? QVariant() : total / i;
6033 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6034 QVariantList numbers;
6035 for (
const auto &item : list )
6037 switch ( item.userType() )
6039 case QMetaType::Int:
6040 case QMetaType::UInt:
6041 case QMetaType::LongLong:
6042 case QMetaType::ULongLong:
6043 case QMetaType::Float:
6044 case QMetaType::Double:
6045 numbers.append( item );
6049 std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) ->
bool { return ( qgsVariantLessThan( a, b ) ); } );
6050 const int count = numbers.count();
6055 else if ( count % 2 )
6057 return numbers.at( count / 2 );
6061 return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
6067 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6070 for (
const QVariant &item : list )
6072 switch ( item.userType() )
6074 case QMetaType::Int:
6075 case QMetaType::UInt:
6076 case QMetaType::LongLong:
6077 case QMetaType::ULongLong:
6078 case QMetaType::Float:
6079 case QMetaType::Double:
6080 total += item.toDouble();
6085 return i == 0 ? QVariant() : total;
6088 static QVariant convertToSameType(
const QVariant &value, QVariant::Type type )
6090 QVariant result = value;
6091 result.convert(
static_cast<int>( type ) );
6097 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6098 QHash< QVariant, int > hash;
6099 for (
const auto &item : list )
6103 const QList< int > occurrences = hash.values();
6104 if ( occurrences.empty() )
6105 return QVariantList();
6107 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6109 const QString option = values.at( 1 ).toString();
6110 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6112 return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
6114 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6116 if ( hash.isEmpty() )
6119 return QVariant( hash.keys( maxValue ).first() );
6121 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6123 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
6125 else if ( option.compare( QLatin1String(
"real_majority" ), Qt::CaseInsensitive ) == 0 )
6127 if ( maxValue * 2 <= list.size() )
6130 return QVariant( hash.keys( maxValue ).first() );
6141 const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6142 QHash< QVariant, int > hash;
6143 for (
const auto &item : list )
6147 const QList< int > occurrences = hash.values();
6148 if ( occurrences.empty() )
6149 return QVariantList();
6151 const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
6153 const QString option = values.at( 1 ).toString();
6154 if ( option.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
6156 return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
6158 else if ( option.compare( QLatin1String(
"any" ), Qt::CaseInsensitive ) == 0 )
6160 if ( hash.isEmpty() )
6163 return QVariant( hash.keys( minValue ).first() );
6165 else if ( option.compare( QLatin1String(
"median" ), Qt::CaseInsensitive ) == 0 )
6167 return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
6169 else if ( option.compare( QLatin1String(
"real_minority" ), Qt::CaseInsensitive ) == 0 )
6171 if ( hash.keys().isEmpty() )
6175 const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
6176 if ( maxValue * 2 > list.size() )
6177 hash.remove( hash.key( maxValue ) );
6179 return convertToSameType( hash.keys(), values.at( 0 ).type() );
6190 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6191 list.append( values.at( 1 ) );
6192 return convertToSameType( list, values.at( 0 ).type() );
6197 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6198 list.prepend( values.at( 1 ) );
6199 return convertToSameType( list, values.at( 0 ).type() );
6204 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6205 list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
6206 return convertToSameType( list, values.at( 0 ).type() );
6211 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6212 int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6214 position = position + list.length();
6215 if ( position >= 0 && position < list.length() )
6216 list.removeAt( position );
6217 return convertToSameType( list, values.at( 0 ).type() );
6222 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6223 list.removeAll( values.at( 1 ) );
6224 return convertToSameType( list, values.at( 0 ).type() );
6229 if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
6231 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
6233 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6234 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
6236 int index = list.indexOf( it.key() );
6237 while ( index >= 0 )
6239 list.replace( index, it.value() );
6240 index = list.indexOf( it.key() );
6244 return convertToSameType( list, values.at( 0 ).type() );
6246 else if ( values.count() == 3 )
6248 QVariantList before;
6250 bool isSingleReplacement =
false;
6252 if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
6254 before = QVariantList() << values.at( 1 );
6258 before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6261 if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
6263 after = QVariantList() << values.at( 2 );
6264 isSingleReplacement =
true;
6268 after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
6271 if ( !isSingleReplacement && before.length() != after.length() )
6273 parent->
setEvalErrorString( QObject::tr(
"Invalid pair of array, length not identical" ) );
6277 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6278 for (
int i = 0; i < before.length(); i++ )
6280 int index = list.indexOf( before.at( i ) );
6281 while ( index >= 0 )
6283 list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
6284 index = list.indexOf( before.at( i ) );
6288 return convertToSameType( list, values.at( 0 ).type() );
6292 parent->
setEvalErrorString( QObject::tr(
"Function array_replace requires 2 or 3 arguments" ) );
6299 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6300 QVariantList list_new;
6302 for (
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
6304 while ( list.removeOne( cur ) )
6306 list_new.append( cur );
6310 list_new.append( list );
6312 return convertToSameType( list_new, values.at( 0 ).type() );
6318 for (
const QVariant &cur : values )
6320 list += QgsExpressionUtils::getListValue( cur, parent );
6322 return convertToSameType( list, values.at( 0 ).type() );
6327 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6328 int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
6329 const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
6330 int slice_length = 0;
6332 if ( start_pos < 0 )
6334 start_pos = list.length() + start_pos;
6338 slice_length = end_pos - start_pos + 1;
6342 slice_length = list.length() + end_pos - start_pos + 1;
6345 if ( slice_length < 0 )
6349 list = list.mid( start_pos, slice_length );
6355 QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6356 std::reverse( list.begin(), list.end() );
6362 const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6363 const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
6364 for (
const QVariant &cur : array2 )
6366 if ( array1.contains( cur ) )
6367 return QVariant(
true );
6369 return QVariant(
false );
6374 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6376 QVariantList distinct;
6378 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6380 if ( !distinct.contains( *it ) )
6382 distinct += ( *it );
6391 QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
6392 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6393 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6397 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
6399 str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
6400 if ( it != ( array.constEnd() - 1 ) )
6406 return QVariant(
str );
6411 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6412 QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6413 QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
6415 QStringList list =
str.split( delimiter );
6418 for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
6420 array += ( !( *it ).isEmpty() ) ? *it : empty;
6428 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6429 QJsonDocument document = QJsonDocument::fromJson(
str.toUtf8() );
6430 if ( document.isNull() )
6433 return document.toVariant();
6439 QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
6440 return document.toJson( QJsonDocument::Compact );
6445 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6446 if (
str.isEmpty() )
6447 return QVariantMap();
6455 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6462 for (
int i = 0; i + 1 < values.length(); i += 2 )
6464 result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
6471 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6472 const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
6473 QVariantMap resultMap;
6475 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6477 resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
6485 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
6490 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
6495 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6496 map.remove( values.at( 1 ).toString() );
6502 QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6503 map.insert( values.at( 1 ).toString(), values.at( 2 ) );
6510 for (
const QVariant &cur : values )
6512 const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
6513 for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
6514 result.insert( it.key(), it.value() );
6521 return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
6526 return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
6531 QString envVarName = values.at( 0 ).toString();
6532 return QProcessEnvironment::systemEnvironment().value( envVarName );
6537 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6540 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"base_file_name" ) ) );
6543 return QFileInfo( file ).completeBaseName();
6548 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6551 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"file_suffix" ) ) );
6554 return QFileInfo( file ).completeSuffix();
6559 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6562 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"file_exists" ) ) );
6565 return QFileInfo::exists( file );
6570 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6573 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"file_name" ) ) );
6576 return QFileInfo( file ).fileName();
6581 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6584 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"is_file" ) ) );
6587 return QFileInfo( file ).isFile();
6592 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6595 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"is_directory" ) ) );
6598 return QFileInfo( file ).isDir();
6603 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6606 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"file_path" ) ) );
6609 return QDir::toNativeSeparators( QFileInfo( file ).path() );
6614 const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), parent );
6617 parent->
setEvalErrorString( QObject::tr(
"Function `%1` requires a value which represents a possible file path" ).arg( QStringLiteral(
"file_size" ) ) );
6620 return QFileInfo( file ).size();
6623 static QVariant fcnHash(
const QString &
str,
const QCryptographicHash::Algorithm
algorithm )
6625 return QString( QCryptographicHash::hash(
str.toUtf8(),
algorithm ).toHex() );
6631 QString
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6632 QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
6634 if ( method == QLatin1String(
"md4" ) )
6636 hash = fcnHash(
str, QCryptographicHash::Md4 );
6638 else if ( method == QLatin1String(
"md5" ) )
6640 hash = fcnHash(
str, QCryptographicHash::Md5 );
6642 else if ( method == QLatin1String(
"sha1" ) )
6644 hash = fcnHash(
str, QCryptographicHash::Sha1 );
6646 else if ( method == QLatin1String(
"sha224" ) )
6648 hash = fcnHash(
str, QCryptographicHash::Sha224 );
6650 else if ( method == QLatin1String(
"sha256" ) )
6652 hash = fcnHash(
str, QCryptographicHash::Sha256 );
6654 else if ( method == QLatin1String(
"sha384" ) )
6656 hash = fcnHash(
str, QCryptographicHash::Sha384 );
6658 else if ( method == QLatin1String(
"sha512" ) )
6660 hash = fcnHash(
str, QCryptographicHash::Sha512 );
6662 else if ( method == QLatin1String(
"sha3_224" ) )
6664 hash = fcnHash(
str, QCryptographicHash::Sha3_224 );
6666 else if ( method == QLatin1String(
"sha3_256" ) )
6668 hash = fcnHash(
str, QCryptographicHash::Sha3_256 );
6670 else if ( method == QLatin1String(
"sha3_384" ) )
6672 hash = fcnHash(
str, QCryptographicHash::Sha3_384 );
6674 else if ( method == QLatin1String(
"sha3_512" ) )
6676 hash = fcnHash(
str, QCryptographicHash::Sha3_512 );
6678 else if ( method == QLatin1String(
"keccak_224" ) )
6680 hash = fcnHash(
str, QCryptographicHash::Keccak_224 );
6682 else if ( method == QLatin1String(
"keccak_256" ) )
6684 hash = fcnHash(
str, QCryptographicHash::Keccak_256 );
6686 else if ( method == QLatin1String(
"keccak_384" ) )
6688 hash = fcnHash(
str, QCryptographicHash::Keccak_384 );
6690 else if ( method == QLatin1String(
"keccak_512" ) )
6692 hash = fcnHash(
str, QCryptographicHash::Keccak_512 );
6696 parent->
setEvalErrorString( QObject::tr(
"Hash method %1 is not available on this system." ).arg(
str ) );
6703 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
6708 return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
6713 const QByteArray input = values.at( 0 ).toByteArray();
6714 return QVariant( QString( input.toBase64() ) );
6719 const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
6721 for (
auto it = map.cbegin(); it != map.cend(); it++ )
6723 query.addQueryItem( it.key(), it.value().toString() );
6725 return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
6730 const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
6731 const QByteArray base64 = value.toLocal8Bit();
6732 const QByteArray decoded = QByteArray::fromBase64( base64 );
6733 return QVariant( decoded );
6738 static QVariant executeGeomOverlay(
const QVariantList &values,
const QgsExpressionContext *context,
QgsExpression *parent,
const RelationFunction &relationFunction,
bool invert =
false,
double bboxGrow = 0,
bool isNearestFunc =
false,
bool isIntersectsFunc =
false )
6741 const QVariant sourceLayerRef = context->
variable( QStringLiteral(
"layer" ) );
6742 QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, parent );
6750 QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
6753 const bool layerCanBeCached = node->
isStatic( parent, context );
6754 QVariant targetLayerValue = node->
eval( parent, context );
6758 node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
6760 QString subExpString = node->
dump();
6762 bool testOnly = ( subExpString ==
"NULL" );
6763 QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, parent );
6766 parent->
setEvalErrorString( QObject::tr(
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
6771 node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
6773 QString filterString = node->
dump();
6774 if ( filterString !=
"NULL" )
6780 node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
6782 QVariant limitValue = node->
eval( parent, context );
6784 qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
6787 double max_distance = 0;
6788 if ( isNearestFunc )
6790 node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
6792 QVariant distanceValue = node->
eval( parent, context );
6794 max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
6798 node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
6800 QVariant cacheValue = node->
eval( parent, context );
6802 bool cacheEnabled = cacheValue.toBool();
6808 double minOverlap { -1 };
6809 double minInscribedCircleRadius { -1 };
6810 bool returnDetails =
false;
6811 bool sortByMeasure =
false;
6812 bool sortAscending =
false;
6813 bool requireMeasures =
false;
6814 bool overlapOrRadiusFilter =
false;
6815 if ( isIntersectsFunc )
6818 node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
6820 const QVariant minOverlapValue = node->
eval( parent, context );
6822 minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
6823 node = QgsExpressionUtils::getNode( values.at( 6 ), parent );
6825 const QVariant minInscribedCircleRadiusValue = node->
eval( parent, context );
6827 minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
6828 #if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<9
6829 if ( minInscribedCircleRadiusValue != -1 )
6831 parent->
setEvalErrorString( QObject::tr(
"'min_inscribed_circle_radius' is only available when QGIS is built with GEOS >= 3.9." ) );
6835 node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
6837 returnDetails = !testOnly && node->
eval( parent, context ).toBool();
6838 node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
6840 const QString sorting { node->
eval( parent, context ).toString().toLower() };
6841 sortByMeasure = !testOnly && ( sorting.startsWith(
"asc" ) || sorting.startsWith(
"des" ) );
6842 sortAscending = sorting.startsWith(
"asc" );
6843 requireMeasures = sortByMeasure || returnDetails;
6844 overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
6851 if ( sourceLayer && targetLayer->
crs() != sourceLayer->
crs() )
6857 bool sameLayers = ( sourceLayer && sourceLayer->
id() == targetLayer->
id() );
6860 if ( bboxGrow != 0 )
6862 intDomain.
grow( bboxGrow );
6865 const QString cacheBase { QStringLiteral(
"%1:%2:%3" ).arg( targetLayer->
id(), subExpString, filterString ) };
6871 QList<QgsFeature> features;
6872 if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
6876 const QString cacheLayer { QStringLiteral(
"ovrlaylyr:%1" ).arg( cacheBase ) };
6877 const QString cacheIndex { QStringLiteral(
"ovrlayidx:%1" ).arg( cacheBase ) };
6881 cachedTarget = targetLayer->
materialize( request );
6882 if ( layerCanBeCached )
6883 context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
6893 if ( layerCanBeCached )
6894 context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
6901 QList<QgsFeatureId> fidsList;
6902 if ( isNearestFunc )
6904 fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
6908 fidsList = spatialIndex.
intersects( intDomain );
6911 QListIterator<QgsFeatureId> i( fidsList );
6912 while ( i.hasNext() )
6915 if ( sameLayers && feat.
id() == fId2 )
6917 features.append( cachedTarget->
getFeature( fId2 ) );
6930 if ( sameLayers && feat.
id() == feat2.
id() )
6932 features.append( feat2 );
6940 const QString expCacheKey { QStringLiteral(
"exp:%1" ).arg( cacheBase ) };
6941 const QString ctxCacheKey { QStringLiteral(
"ctx:%1" ).arg( cacheBase ) };
6947 subExpression.
prepare( &subContext );
6959 QVariantList results;
6961 QListIterator<QgsFeature> i( features );
6962 while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
6966 if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) )
6969 double overlapValue = -1;
6970 double radiusValue = -1;
6972 if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
6979 switch ( intersection.type() )
6982 case QgsWkbTypes::GeometryType::PolygonGeometry:
6986 bool testResult {
false };
6988 QVector<double> overlapValues;
6989 QVector<double> radiusValues;
6990 for (
auto it = intersection.const_parts_begin(); ( ! testResult || requireMeasures ) && it != intersection.const_parts_end(); ++it )
6992 const QgsCurvePolygon *geom = qgsgeometry_cast< const QgsCurvePolygon * >( *it );
6994 if ( minOverlap != -1 || requireMeasures )
6996 overlapValue = geom->
area();
6997 overlapValues.append( geom->
area() );
6998 if ( minOverlap != - 1 )
7000 if ( overlapValue >= minOverlap )
7011 #if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
7013 if ( minInscribedCircleRadius != -1 || requireMeasures )
7016 const double width = bbox.
width();
7017 const double height = bbox.
height();
7018 const double size = width > height ? width : height;
7019 const double tolerance = size / 100.0;
7021 testResult = radiusValue >= minInscribedCircleRadius;
7022 radiusValues.append( radiusValues );
7028 if ( !radiusValues.isEmpty() )
7030 radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
7033 if ( ! overlapValues.isEmpty() )
7035 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
7038 if ( ! testResult && overlapOrRadiusFilter )
7045 case QgsWkbTypes::GeometryType::LineGeometry:
7047 bool testResult {
false };
7049 QVector<double> overlapValues;
7050 for (
auto it = intersection.const_parts_begin(); ! testResult && it != intersection.const_parts_end(); ++it )
7052 const QgsCurve *geom = qgsgeometry_cast< const QgsCurve * >( *it );
7054 if ( minOverlap != -1 || requireMeasures )
7056 overlapValue = geom->
length();
7057 overlapValues.append( overlapValue );
7058 if ( minOverlap != -1 )
7060 if ( overlapValue >= minOverlap )
7072 if ( ! overlapValues.isEmpty() )
7074 overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
7077 if ( ! testResult && overlapOrRadiusFilter )
7084 case QgsWkbTypes::GeometryType::PointGeometry:
7086 if ( minOverlap != -1 || requireMeasures )
7094 if ( geometry.
type() == QgsWkbTypes::GeometryType::PointGeometry )
7098 case QgsWkbTypes::GeometryType::UnknownGeometry:
7099 case QgsWkbTypes::GeometryType::NullGeometry:
7100 case QgsWkbTypes::GeometryType::PointGeometry:
7104 case QgsWkbTypes::GeometryType::LineGeometry:
7109 case QgsWkbTypes::GeometryType::PolygonGeometry:
7117 if ( minOverlap != -1 && overlapValue < minOverlap )
7125 case QgsWkbTypes::GeometryType::NullGeometry:
7126 case QgsWkbTypes::GeometryType::UnknownGeometry:
7144 const QVariant expResult = subExpression.
evaluate( &subContext );
7146 if ( requireMeasures )
7148 QVariantMap resultRecord;
7149 resultRecord.insert( QStringLiteral(
"id" ), feat2.
id() );
7150 resultRecord.insert( QStringLiteral(
"result" ), expResult );
7152 resultRecord.insert( QStringLiteral(
"overlap" ), overlapValue );
7154 if ( radiusValue != -1 )
7156 resultRecord.insert( QStringLiteral(
"radius" ), radiusValue );
7158 results.append( resultRecord );
7162 results.append( expResult );
7168 results.append( feat2.
id() );
7182 if ( requireMeasures )
7184 if ( sortByMeasure )
7186 std::sort( results.begin(), results.end(), [ sortAscending ](
const QVariant & recordA,
const QVariant & recordB ) ->
bool
7188 return sortAscending ?
7189 recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble()
7190 : recordA.toMap().value( QStringLiteral(
"overlap" ) ).toDouble() > recordB.toMap().value( QStringLiteral(
"overlap" ) ).toDouble();
7194 if ( limit > 0 && results.size() > limit )
7196 results.erase( results.begin() + limit );
7199 if ( ! returnDetails )
7201 QVariantList expResults;
7202 for (
auto it = results.constBegin(); it != results.constEnd(); ++it )
7204 expResults.append( it->toMap().value( QStringLiteral(
"result" ) ) );
7214 QVariantList disjoint_results;
7223 if ( !results.contains( feat2.
id() ) )
7226 disjoint_results.append( subExpression.
evaluate( &subContext ) );
7229 return disjoint_results;
7272 return executeGeomOverlay( values, context, parent,
nullptr,
false, 0,
true );
7281 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
7282 static QMutex sFunctionsMutex( QMutex::Recursive );
7283 QMutexLocker locker( &sFunctionsMutex );
7285 static QRecursiveMutex sFunctionsMutex;
7286 QMutexLocker locker( &sFunctionsMutex );
7289 QList<QgsExpressionFunction *> &functions = *sFunctions();
7291 if ( functions.isEmpty() )
7328 functions << randFunc;
7332 functions << randfFunc;
7335 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max" ), -1, fcnMax, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7336 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min" ), -1, fcnMin, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7342 <<
new QgsStaticExpressionFunction( QStringLiteral(
"pi" ), 0, fcnPi, QStringLiteral(
"Math" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$pi" ) )
7346 <<
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" ) )
7347 <<
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" ) )
7348 <<
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" ) )
7353 <<
new QgsStaticExpressionFunction( QStringLiteral(
"coalesce" ), -1, fcnCoalesce, QStringLiteral(
"Conditionals" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
7367 QStringLiteral(
"Aggregates" ),
7376 if ( !node->
args() )
7379 QSet<QString> referencedVars;
7382 QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
7383 referencedVars = subExpressionNode->referencedVariables();
7388 QgsExpressionNode *filterNode = node->args()->at( 3 );
7389 referencedVars.unite( filterNode->referencedVariables() );
7391 return referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() );
7400 if ( !node->
args() )
7401 return QSet<QString>();
7403 QSet<QString> referencedCols;
7404 QSet<QString> referencedVars;
7419 if ( referencedVars.contains( QStringLiteral(
"parent" ) ) || referencedVars.contains( QString() ) )
7422 return referencedCols;
7435 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count" ), aggParams, fcnAggregateCount, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7436 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7437 <<
new QgsStaticExpressionFunction( QStringLiteral(
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7438 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7439 <<
new QgsStaticExpressionFunction( QStringLiteral(
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7440 <<
new QgsStaticExpressionFunction( QStringLiteral(
"sum" ), aggParams, fcnAggregateSum, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7441 <<
new QgsStaticExpressionFunction( QStringLiteral(
"mean" ), aggParams, fcnAggregateMean, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7442 <<
new QgsStaticExpressionFunction( QStringLiteral(
"median" ), aggParams, fcnAggregateMedian, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7443 <<
new QgsStaticExpressionFunction( QStringLiteral(
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7444 <<
new QgsStaticExpressionFunction( QStringLiteral(
"range" ), aggParams, fcnAggregateRange, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7445 <<
new QgsStaticExpressionFunction( QStringLiteral(
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7446 <<
new QgsStaticExpressionFunction( QStringLiteral(
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7447 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7448 <<
new QgsStaticExpressionFunction( QStringLiteral(
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7449 <<
new QgsStaticExpressionFunction( QStringLiteral(
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7450 <<
new QgsStaticExpressionFunction( QStringLiteral(
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7451 <<
new QgsStaticExpressionFunction( QStringLiteral(
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7452 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7453 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7454 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7455 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral(
"Aggregates" ), QString(),
false, QSet<QString>(), true )
7460 <<
new QgsStaticExpressionFunction( QStringLiteral(
"now" ), 0, fcnNow, QStringLiteral(
"Date and Time" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"$now" ) )
7463 fcnAge, QStringLiteral(
"Date and Time" ) )
7477 fcnMakeDate, QStringLiteral(
"Date and Time" ) )
7481 fcnMakeTime, QStringLiteral(
"Date and Time" ) )
7488 fcnMakeDateTime, QStringLiteral(
"Date and Time" ) )
7496 fcnMakeInterval, QStringLiteral(
"Date and Time" ) )
7515 false, QSet< QString >(),
false, QStringList(), true )
7516 <<
new QgsStaticExpressionFunction( QStringLiteral(
"concat" ), -1, fcnConcat, QStringLiteral(
"String" ), QString(),
false, QSet<QString>(),
false, QStringList(), true )
7529 fcnColorMixRgb, QStringLiteral(
"Color" ) )
7533 fcnColorRgb, QStringLiteral(
"Color" ) )
7538 fncColorRgba, QStringLiteral(
"Color" ) )
7544 fcnCreateRamp, QStringLiteral(
"Color" ) )
7548 fcnColorHsl, QStringLiteral(
"Color" ) )
7553 fncColorHsla, QStringLiteral(
"Color" ) )
7557 fcnColorHsv, QStringLiteral(
"Color" ) )
7562 fncColorHsva, QStringLiteral(
"Color" ) )
7567 fcnColorCmyk, QStringLiteral(
"Color" ) )
7573 fncColorCmyka, QStringLiteral(
"Color" ) )
7576 fncColorPart, QStringLiteral(
"Color" ) )
7579 fncDarker, QStringLiteral(
"Color" ) )
7582 fncLighter, QStringLiteral(
"Color" ) )
7587 fcnBaseFileName, QStringLiteral(
"Files and Paths" ) )
7589 fcnFileSuffix, QStringLiteral(
"Files and Paths" ) )
7591 fcnFileExists, QStringLiteral(
"Files and Paths" ) )
7593 fcnFileName, QStringLiteral(
"Files and Paths" ) )
7595 fcnPathIsFile, QStringLiteral(
"Files and Paths" ) )
7597 fcnPathIsDir, QStringLiteral(
"Files and Paths" ) )
7599 fcnFilePath, QStringLiteral(
"Files and Paths" ) )
7601 fcnFileSize, QStringLiteral(
"Files and Paths" ) )
7604 fcnExif, QStringLiteral(
"Files and Paths" ) )
7606 fcnExifGeoTag, QStringLiteral(
"GeometryGroup" ) )
7610 fcnGenericHash, QStringLiteral(
"Conversions" ) )
7612 fcnHashMd5, QStringLiteral(
"Conversions" ) )
7614 fcnHashSha256, QStringLiteral(
"Conversions" ) )
7618 fcnToBase64, QStringLiteral(
"Conversions" ) )
7620 fcnFromBase64, QStringLiteral(
"Conversions" ) )
7626 geomFunc->setIsStatic(
false );
7627 functions << geomFunc;
7631 functions << areaFunc;
7637 functions << lengthFunc;
7641 functions << perimeterFunc;
7647 fcnRoundness, QStringLiteral(
"GeometryGroup" ) );
7661 QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
7663 { QStringLiteral(
"overlay_intersects" ), fcnGeomOverlayIntersects },
7664 { QStringLiteral(
"overlay_contains" ), fcnGeomOverlayContains },
7665 { QStringLiteral(
"overlay_crosses" ), fcnGeomOverlayCrosses },
7666 { QStringLiteral(
"overlay_equals" ), fcnGeomOverlayEquals },
7667 { QStringLiteral(
"overlay_touches" ), fcnGeomOverlayTouches },
7668 { QStringLiteral(
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
7669 { QStringLiteral(
"overlay_within" ), fcnGeomOverlayWithin },
7671 QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
7672 while ( i.hasNext() )
7689 functions << fcnGeomOverlayFunc;
7702 functions << fcnGeomOverlayNearestFunc;
7715 fcnNodesToPoints, QStringLiteral(
"GeometryGroup" ) )
7717 <<
new QgsStaticExpressionFunction( QStringLiteral(
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral(
"GeometryGroup" ) )
7722 fcnMakePointM, QStringLiteral(
"GeometryGroup" ) )
7728 fcnMakeTriangle, QStringLiteral(
"GeometryGroup" ) )
7733 fcnMakeCircle, QStringLiteral(
"GeometryGroup" ) )
7740 fcnMakeEllipse, QStringLiteral(
"GeometryGroup" ) )
7746 fcnMakeRegularPolygon, QStringLiteral(
"GeometryGroup" ) )
7750 fcnMakeSquare, QStringLiteral(
"GeometryGroup" ) )
7756 fcnMakeRectangleFrom3Points, QStringLiteral(
"GeometryGroup" ) );
7759 functions << xAtFunc;
7763 functions << yAtFunc;
7779 fcnDisjoint, QStringLiteral(
"GeometryGroup" ) )
7782 fcnIntersects, QStringLiteral(
"GeometryGroup" ) )
7785 fcnTouches, QStringLiteral(
"GeometryGroup" ) )
7788 fcnCrosses, QStringLiteral(
"GeometryGroup" ) )
7791 fcnContains, QStringLiteral(
"GeometryGroup" ) )
7794 fcnOverlaps, QStringLiteral(
"GeometryGroup" ) )
7797 fcnWithin, QStringLiteral(
"GeometryGroup" ) )
7801 fcnTranslate, QStringLiteral(
"GeometryGroup" ) )
7806 fcnRotate, QStringLiteral(
"GeometryGroup" ) )
7811 fcnScale, QStringLiteral(
"GeometryGroup" ) )
7822 fcnAffineTransform, QStringLiteral(
"GeometryGroup" ) )
7829 fcnBuffer, QStringLiteral(
"GeometryGroup" ) )
7831 fcnForceRHR, QStringLiteral(
"GeometryGroup" ) )
7833 fcnForcePolygonCW, QStringLiteral(
"GeometryGroup" ) )
7835 fcnForcePolygonCCW, QStringLiteral(
"GeometryGroup" ) )
7845 , fcnTaperedBuffer, QStringLiteral(
"GeometryGroup" ) )
7848 , fcnBufferByM, QStringLiteral(
"GeometryGroup" ) )
7854 fcnOffsetCurve, QStringLiteral(
"GeometryGroup" ) )
7860 fcnSingleSidedBuffer, QStringLiteral(
"GeometryGroup" ) )
7864 fcnExtend, QStringLiteral(
"GeometryGroup" ) )
7873 fcnInteriorRingN, QStringLiteral(
"GeometryGroup" ) )
7876 fcnGeometryN, QStringLiteral(
"GeometryGroup" ) )
7892 }, fcnTriangularWave, QStringLiteral(
"GeometryGroup" ) )
7901 }, fcnTriangularWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7908 }, fcnSquareWave, QStringLiteral(
"GeometryGroup" ) )
7917 }, fcnSquareWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7924 }, fcnRoundWave, QStringLiteral(
"GeometryGroup" ) )
7933 }, fcnRoundWaveRandomized, QStringLiteral(
"GeometryGroup" ) )
7942 }, fcnApplyDashPattern, QStringLiteral(
"GeometryGroup" ) )
7947 }, fcnDensifyByCount, QStringLiteral(
"GeometryGroup" ) )
7952 }, fcnDensifyByDistance, QStringLiteral(
"GeometryGroup" ) )
7966 fcnOrientedBBox, QStringLiteral(
"GeometryGroup" ) )
7969 fcnMainAngle, QStringLiteral(
"GeometryGroup" ) )
7973 fcnMinimalCircle, QStringLiteral(
"GeometryGroup" ) )
7976 fcnDifference, QStringLiteral(
"GeometryGroup" ) )
7979 fcnDistance, QStringLiteral(
"GeometryGroup" ) )
7982 fcnHausdorffDistance, QStringLiteral(
"GeometryGroup" ) )
7985 fcnIntersection, QStringLiteral(
"GeometryGroup" ) )
7988 fcnSymDifference, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"symDifference" ) )
7991 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
7994 fcnCombine, QStringLiteral(
"GeometryGroup" ) )
7997 fcnGeomToWKT, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"geomToWKT" ) )
7999 fcnGeomToWKB, QStringLiteral(
"GeometryGroup" ), QString(),
false, QSet<QString>(), false )
8004 fcnTransformGeometry, QStringLiteral(
"GeometryGroup" ) )
8008 fcnExtrude, QStringLiteral(
"GeometryGroup" ), QString() )
8010 fcnGeomIsMultipart, QStringLiteral(
"GeometryGroup" ) )
8012 fcnZMax, QStringLiteral(
"GeometryGroup" ) )
8014 fcnZMin, QStringLiteral(
"GeometryGroup" ) )
8016 fcnMMax, QStringLiteral(
"GeometryGroup" ) )
8018 fcnMMin, QStringLiteral(
"GeometryGroup" ) )
8020 fcnSinuosity, QStringLiteral(
"GeometryGroup" ) )
8022 fcnStraightDistance2d, QStringLiteral(
"GeometryGroup" ) );
8028 fcnOrderParts, QStringLiteral(
"GeometryGroup" ), QString() );
8030 orderPartsFunc->setIsStaticFunction(
8033 const QList< QgsExpressionNode *> argList = node->
args()->list();
8036 if ( !argNode->isStatic( parent, context ) )
8042 QgsExpressionNode *argNode = node->args()->at( 1 );
8044 QString expString = argNode->eval( parent, context ).toString();
8046 QgsExpression e( expString );
8048 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8059 QgsExpressionNode *argNode = node->args()->at( 1 );
8060 QString expression = argNode->eval( parent, context ).toString();
8061 QgsExpression e( expression );
8062 e.prepare( context );
8063 context->setCachedValue( expression, QVariant::fromValue( e ) );
8068 functions << orderPartsFunc;
8073 fcnClosestPoint, QStringLiteral(
"GeometryGroup" ) )
8076 fcnShortestLine, QStringLiteral(
"GeometryGroup" ) )
8095 functions << idFunc;
8099 functions << currentFeatureFunc;
8101 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" ) );
8103 functions << uuidFunc;
8109 fcnGetFeature, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false, QStringList() << QStringLiteral(
"QgsExpressionUtils::getFeature" ) )
8112 fcnGetFeatureById, QStringLiteral(
"Record and Attributes" ), QString(),
false, QSet<QString>(),
false );
8117 functions << attributesFunc;
8121 functions << representAttributesFunc;
8124 QStringLiteral(
"maptip" ),
8127 QStringLiteral(
"Record and Attributes" ),
8133 functions << maptipFunc;
8136 QStringLiteral(
"display_expression" ),
8138 fcnFeatureDisplayExpression,
8139 QStringLiteral(
"Record and Attributes" ),
8145 functions << displayFunc;
8148 QStringLiteral(
"is_selected" ),
8151 QStringLiteral(
"Record and Attributes" ),
8157 functions << isSelectedFunc;
8161 QStringLiteral(
"num_selected" ),
8164 QStringLiteral(
"Record and Attributes" ),
8172 QStringLiteral(
"sqlite_fetch_and_increment" ),
8180 fcnSqliteFetchAndIncrement,
8181 QStringLiteral(
"Record and Attributes" )
8199 parent->
setEvalErrorString( tr(
"If represent_value is called with 1 parameter, it must be an attribute." ) );
8209 parent->
setEvalErrorString( tr(
"represent_value must be called with exactly 1 or 2 parameters." ) );
8215 functions << representValueFunc;
8221 fcnGetLayerProperty, QStringLiteral(
"Map Layers" ) )
8226 fcnDecodeUri, QStringLiteral(
"Map Layers" ) )
8230 fcnMimeType, QStringLiteral(
"General" ) )
8247 QgsExpressionNode *argNode = node->args()->at( 0 );
8249 if ( !argNode->isStatic( parent, context ) )
8252 QString varName = argNode->eval( parent, context ).toString();
8254 const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
8255 return scope ? scope->isStatic( varName ) : false;
8272 QgsExpressionNode *argNode = node->args()->at( 0 );
8274 if ( argNode->isStatic( parent, context ) )
8276 QString expString = argNode->eval( parent, context ).toString();
8278 QgsExpression e( expString );
8280 if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
8288 functions << evalFunc;
8294 const QList< QgsExpressionNode *> argList = node->
args()->list();
8297 if ( !argNode->isStatic( parent, context ) )
8309 functions << attributeFunc;
8319 <<
new QgsStaticExpressionFunction( QStringLiteral(
"array" ), -1, fcnArray, QStringLiteral(
"Arrays" ), QString(),
false, QSet<QString>(),
false, QStringList(),
true )
8367 fcnMapPrefixKeys, QStringLiteral(
"Maps" ) )
8369 fcnToFormUrlEncode, QStringLiteral(
"Maps" ) )
8378 *sOwnedFunctions() << func;
8379 *sBuiltinFunctions() << func->name();
8380 sBuiltinFunctions()->append( func->aliases() );
8393 sFunctions()->append(
function );
8394 if ( transferOwnership )
8395 sOwnedFunctions()->append(
function );
8409 sFunctions()->removeAt( fnIdx );
8417 qDeleteAll( *sOwnedFunctions() );
8418 sOwnedFunctions()->clear();
8423 if ( sBuiltinFunctions()->isEmpty() )
8427 return *sBuiltinFunctions();
8435 QStringLiteral(
"Arrays" ) )
8446 if ( args->
count() < 2 )
8449 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8459 QVariantList result;
8461 if ( args->
count() < 2 )
8465 QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8468 std::unique_ptr< QgsExpressionContext > tempContext;
8471 tempContext = std::make_unique< QgsExpressionContext >();
8472 subContext = tempContext.get();
8478 for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
8481 result << args->
at( 1 )->
eval( parent, subContext );
8506 if ( args->
count() < 2 )
8510 args->
at( 0 )->
prepare( parent, context );
8514 subContext = *context;
8520 args->
at( 1 )->
prepare( parent, &subContext );
8530 QStringLiteral(
"Arrays" ) )
8541 if ( args->
count() < 2 )
8544 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8554 QVariantList result;
8556 if ( args->
count() < 2 )
8560 const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
8563 std::unique_ptr< QgsExpressionContext > tempContext;
8566 tempContext = std::make_unique< QgsExpressionContext >();
8567 subContext = tempContext.get();
8574 if ( args->
count() >= 3 )
8576 const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
8578 if ( QgsExpressionUtils::isIntSafe( limitVar ) )
8580 limit = limitVar.toInt();
8588 for (
const QVariant &value : array )
8591 if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
8595 if ( limit > 0 && limit == result.size() )
8622 if ( args->
count() < 2 )
8626 args->
at( 0 )->
prepare( parent, context );
8630 subContext = *context;
8636 args->
at( 1 )->
prepare( parent, &subContext );
8645 QStringLiteral(
"General" ) )
8656 if ( args->
count() < 3 )
8660 if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
8662 QVariant
name = args->
at( 0 )->
eval( parent, context );
8663 QVariant value = args->
at( 1 )->
eval( parent, context );
8666 appendTemporaryVariable( context,
name.toString(), value );
8667 if ( args->
at( 2 )->
isStatic( parent, context ) )
8669 popTemporaryVariable( context );
8680 if ( args->
count() < 3 )
8684 QVariant
name = args->
at( 0 )->
eval( parent, context );
8685 QVariant value = args->
at( 1 )->
eval( parent, context );
8688 std::unique_ptr< QgsExpressionContext > tempContext;
8689 if ( !updatedContext )
8691 tempContext = std::make_unique< QgsExpressionContext >();
8692 updatedContext = tempContext.get();
8695 appendTemporaryVariable( updatedContext,
name.toString(), value );
8696 result = args->
at( 2 )->
eval( parent, updatedContext );
8699 popTemporaryVariable( updatedContext );
8720 if ( args->
count() < 3 )
8725 QVariant value = args->
at( 1 )->
prepare( parent, context );
8728 std::unique_ptr< QgsExpressionContext > tempContext;
8729 if ( !updatedContext )
8731 tempContext = std::make_unique< QgsExpressionContext >();
8732 updatedContext = tempContext.get();
8735 appendTemporaryVariable( updatedContext,
name.toString(), value );
8736 args->
at( 2 )->
prepare( parent, updatedContext );
8739 popTemporaryVariable( updatedContext );
8744 void QgsWithVariableExpressionFunction::popTemporaryVariable(
const QgsExpressionContext *context )
const
8750 void 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.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
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.
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.
double roundness() const
Returns the roundness of the curve polygon.
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
Abstract base class for curved geometry type.
double sinuosity() const
Returns the curve sinuosity, which is the ratio of the curve length() to curve straightDistance2d().
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
double straightDistance2d() const
Returns the straight distance of the curve, i.e.
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
double convertAreaMeasurement(double area, QgsUnitTypes::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
double convertLengthMeasurement(double length, QgsUnitTypes::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
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.
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
int count() const
Returns the number of nodes in the list.
Abstract base class for all nodes that can appear in an expression.
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
A set of expression-related functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static const QStringList & BuiltinFunctions()
static QString 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 isValid() const
Returns the validity of this feature.
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
int partCount() const override
Returns count of parts contained in the geometry.
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
A geometry is the spatial representation of a feature.
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
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.
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 difference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other.
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 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 variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
QgsMultiPointXY asMultiPoint() const
Returns the contents of the geometry as a multi-point.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
QgsGeometry combine(const QgsGeometry &geometry) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
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.
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool equals(const QgsGeometry &geometry) const
Test if this geometry is exactly equal to another geometry.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsWkbTypes::GeometryType type
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
QString lastError() const SIP_HOLDGIL
Returns an error string referring to the last error encountered either when this geometry was created...
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
QgsGeometry mergeLines() const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
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...
QgsGeometry symDifference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other.
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsGeometry 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 providerType() const
Returns the provider type (provider key) for this layer.
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QgsLayerMetadata metadata
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
virtual bool isEditable() const
Returns true if the layer can be edited.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
Implementation of GeometrySimplifier using the "MapToPixel" algorithm.
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Multi point geometry collection.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override SIP_HOLDGIL
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
double inclination(const QgsPoint &other) const SIP_HOLDGIL
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Quadrilateral geometry type.
static QgsQuadrilateral squareFromDiagonal(const QgsPoint &p1, const QgsPoint &p2) SIP_HOLDGIL
Construct a QgsQuadrilateral as a square from a diagonal.
QgsPolygon * toPolygon(bool force2D=false) const
Returns the quadrilateral as a new polygon.
ConstructionOption
A quadrilateral can be constructed from 3 points where the second distance can be determined by the t...
@ Distance
Second distance is equal to the distance between 2nd and 3rd point.
@ Projected
Second distance is equal to the distance of the perpendicular projection of the 3rd point on the segm...
static QgsQuadrilateral rectangleFrom3Points(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, ConstructionOption mode) SIP_HOLDGIL
Construct a QgsQuadrilateral as a Rectangle from 3 points.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
virtual double sample(const QgsPointXY &point, int band, bool *ok=nullptr, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Samples a raster value from the specified band found at the point position.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
Represents a raster layer.
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void grow(double delta)
Grows the rectangle in place by the specified amount.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Regular Polygon geometry type.
ConstructionOption
A regular polygon can be constructed inscribed in a circle or circumscribed about a circle.
@ CircumscribedCircle
Circumscribed about a circle (the radius is the distance from the center to the midpoints of the side...
@ InscribedCircle
Inscribed in a circle (the radius is the distance between the center and vertices)
QgsPolygon * toPolygon() const
Returns as a polygon.
QList< QgsRelation > relationsByName(const QString &name) const
Returns a list of relations with matching names.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
c++ helper class for defining QgsExpression functions.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
static QgsStyle * defaultStyle()
Returns default application-wide style.
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.
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_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
bool(QgsGeometry::* RelationFunction)(const QgsGeometry &geometry) const
QList< QgsExpressionFunction * > ExpressionFunctionList
#define ENSURE_GEOM_TYPE(f, g, geomtype)
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
#define ENSURE_NO_EVAL_ERROR
#define FEAT_FROM_CONTEXT(c, f)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
QLineF segment(int index, QRectF rect, double radius)
A bundle of parameters controlling aggregate calculation.
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
Single variable definition for use within a QgsExpressionContextScope.
The Context struct stores the current layer and coordinate transform context.
const QgsMapLayer * layer
QgsCoordinateTransformContext transformContext
Utility class for identifying a unique vertex within a geometry.