68#include <QMimeDatabase> 
   69#include <QProcessEnvironment> 
   70#include <QCryptographicHash> 
   71#include <QRegularExpression> 
   94  QVariantList argValues;
 
   98    const QList< QgsExpressionNode * > argList = args->
list();
 
  105        v = QVariant::fromValue( n );
 
  109        v = n->eval( parent, context );
 
  111        bool defaultParamIsNull = mParameterList.count() > arg && mParameterList.at( arg ).optional() && !mParameterList.at( arg ).defaultValue().isValid();
 
  112        if ( QgsExpressionUtils::isNull( v ) && !defaultParamIsNull && !
handlesNull() )
 
  115      argValues.append( v );
 
  120  return func( argValues, context, parent, node );
 
  131  return QStringList();
 
  158  return mGroups.isEmpty() ? false : mGroups.contains( QStringLiteral( 
"deprecated" ) );
 
  163  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
 
  175    const QString &group,
 
  176    const QString &helpText,
 
  180    const QStringList &aliases,
 
  184  , mAliases( aliases )
 
  185  , mUsesGeometry( false )
 
  186  , mUsesGeometryFunc( usesGeometry )
 
  187  , mReferencedColumnsFunc( referencedColumns )
 
  199  if ( mUsesGeometryFunc )
 
  200    return mUsesGeometryFunc( node );
 
  202    return mUsesGeometry;
 
  212  if ( mReferencedColumnsFunc )
 
  213    return mReferencedColumnsFunc( node );
 
  215    return mReferencedColumns;
 
  221    return mIsStaticFunc( node, parent, context );
 
  229    return mPrepareFunc( node, parent, context );
 
  241  mIsStaticFunc = 
nullptr;
 
  247  mPrepareFunc = prepareFunc;
 
  252  if ( node && node->
args() )
 
  254    const QList< QgsExpressionNode * > argList = node->
args()->
list();
 
  257      if ( !argNode->isStatic( parent, context ) )
 
  267  double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  268  double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  269  double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
  271  if ( step == 0.0  || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
 
  278  double current = start + step;
 
  279  while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
 
  294  const QString name = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
  296  if ( name == QLatin1String( 
"feature" ) )
 
  298    return context->
hasFeature() ? QVariant::fromValue( context->
feature() ) : QVariant();
 
  300  else if ( name == QLatin1String( 
"id" ) )
 
  302    return context->
hasFeature() ? QVariant::fromValue( context->
feature().
id() ) : QVariant();
 
  304  else if ( name == QLatin1String( 
"geometry" ) )
 
  320  QString templateString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
  329  QString expString = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
  331  return expression.evaluate( context );
 
  336  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  337  return QVariant( std::sqrt( x ) );
 
  342  double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  343  return QVariant( std::fabs( val ) );
 
  348  double deg = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  349  return ( deg * M_PI ) / 180;
 
  353  double rad = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  354  return ( 180 * rad ) / M_PI;
 
  358  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  359  return QVariant( std::sin( x ) );
 
  363  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  364  return QVariant( std::cos( x ) );
 
  368  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  369  return QVariant( std::tan( x ) );
 
  373  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  374  return QVariant( std::asin( x ) );
 
  378  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  379  return QVariant( std::acos( x ) );
 
  383  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  384  return QVariant( std::atan( x ) );
 
  388  double y = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  389  double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  390  return QVariant( std::atan2( y, x ) );
 
  394  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  395  return QVariant( std::exp( x ) );
 
  399  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  402  return QVariant( std::log( x ) );
 
  406  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  409  return QVariant( log10( x ) );
 
  413  double b = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  414  double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  415  if ( x <= 0 || b <= 0 )
 
  417  return QVariant( std::log( x ) / std::log( b ) );
 
  421  double min = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  422  double max = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  426  std::random_device rd;
 
  427  std::mt19937_64 generator( rd() );
 
  429  if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
 
  432    if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
 
  435      seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
 
  440      QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
  441      std::hash<std::string> hasher;
 
  442      seed = hasher( seedStr.toStdString() );
 
  444    generator.seed( seed );
 
  448  double f = 
static_cast< double >( generator() ) / 
static_cast< double >( std::mt19937_64::max() );
 
  449  return QVariant( min + f * ( max - min ) );
 
  453  qlonglong min = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
 
  454  qlonglong max = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
  458  std::random_device rd;
 
  459  std::mt19937_64 generator( rd() );
 
  461  if ( !QgsExpressionUtils::isNull( values.at( 2 ) ) )
 
  464    if ( QgsExpressionUtils::isIntSafe( values.at( 2 ) ) )
 
  467      seed = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
 
  472      QString seedStr = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
  473      std::hash<std::string> hasher;
 
  474      seed = hasher( seedStr.toStdString() );
 
  476    generator.seed( seed );
 
  479  qint64 randomInteger = min + ( generator() % ( max - min + 1 ) );
 
  480  if ( randomInteger  > std::numeric_limits<int>::max() || randomInteger < -std::numeric_limits<int>::max() )
 
  481    return QVariant( randomInteger );
 
  484  return QVariant( 
int( randomInteger ) );
 
  489  double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  490  double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  491  double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
  492  double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
  493  double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
  495  if ( domainMin >= domainMax )
 
  497    parent->
setEvalErrorString( QObject::tr( 
"Domain max must be greater than domain min" ) );
 
  502  if ( val >= domainMax )
 
  506  else if ( val <= domainMin )
 
  512  double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
 
  513  double c = rangeMin - ( domainMin * m );
 
  516  return QVariant( m * val + 
c );
 
  521  double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  522  double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  523  double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
  524  double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
  525  double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
  526  double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
  528  if ( domainMin >= domainMax )
 
  530    parent->
setEvalErrorString( QObject::tr( 
"Domain max must be greater than domain min" ) );
 
  540  if ( val >= domainMax )
 
  544  else if ( val <= domainMin )
 
  550  return QVariant( ( ( rangeMax - rangeMin ) / std::pow( domainMax - domainMin, exponent ) ) * std::pow( val - domainMin, exponent ) + rangeMin );
 
  555  double val = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
  556  double domainMin = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
  557  double domainMax = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
  558  double rangeMin = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
  559  double rangeMax = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
  560  double exponent = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
  562  if ( domainMin >= domainMax )
 
  564    parent->
setEvalErrorString( QObject::tr( 
"Domain max must be greater than domain min" ) );
 
  574  if ( val >= domainMax )
 
  578  else if ( val <= domainMin )
 
  584  double ratio = ( std::pow( exponent, val - domainMin ) - 1 ) / ( std::pow( exponent, domainMax - domainMin ) - 1 );
 
  585  return QVariant( ( rangeMax - rangeMin ) * ratio + rangeMin );
 
  590  QVariant result( QVariant::Double );
 
  591  double maxVal = std::numeric_limits<double>::quiet_NaN();
 
  592  for ( 
const QVariant &val : values )
 
  595    if ( std::isnan( maxVal ) )
 
  599    else if ( !std::isnan( testVal ) )
 
  601      maxVal = std::max( maxVal, testVal );
 
  605  if ( !std::isnan( maxVal ) )
 
  607    result = QVariant( maxVal );
 
  614  QVariant result( QVariant::Double );
 
  615  double minVal = std::numeric_limits<double>::quiet_NaN();
 
  616  for ( 
const QVariant &val : values )
 
  619    if ( std::isnan( minVal ) )
 
  623    else if ( !std::isnan( testVal ) )
 
  625      minVal = std::min( minVal, testVal );
 
  629  if ( !std::isnan( minVal ) )
 
  631    result = QVariant( minVal );
 
  643  QVariant value = node->
eval( parent, context );
 
  648  QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( value, context, parent );
 
  652    parent->
setEvalErrorString( QObject::tr( 
"Cannot find layer with name or ID '%1'" ).arg( value.toString() ) );
 
  657  node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
  659  value = node->
eval( parent, context );
 
  665    parent->
setEvalErrorString( QObject::tr( 
"No such aggregate '%1'" ).arg( value.toString() ) );
 
  670  node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
 
  672  QString subExpression = node->
dump();
 
  676  if ( values.count() > 3 )
 
  678    node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
 
  681    if ( !nl || nl->value().isValid() )
 
  686  if ( values.count() > 4 )
 
  688    node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
 
  690    value = node->
eval( parent, context );
 
  697  if ( values.count() > 5 )
 
  699    node = QgsExpressionUtils::getNode( values.at( 5 ), parent );
 
  702    if ( !nl || nl->value().isValid() )
 
  704      orderBy = node->
dump();
 
  709  QString aggregateError;
 
  717    bool isStatic = 
true;
 
  718    if ( filterExp.referencedVariables().contains( QStringLiteral( 
"parent" ) )
 
  719         || filterExp.referencedVariables().contains( QString() )
 
  720         || subExp.referencedVariables().contains( QStringLiteral( 
"parent" ) )
 
  721         || subExp.referencedVariables().contains( QString() ) )
 
  727      const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
 
  728      for ( 
const QString &varName : refVars )
 
  731        if ( scope && !scope->
isStatic( varName ) )
 
  741      cacheKey = QStringLiteral( 
"aggfcn:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
 
  742                 QString::number( context->
feature().
id() ), QString::number( 
qHash( context->
feature() ) ), orderBy );
 
  746      cacheKey = QStringLiteral( 
"aggfcn:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
 
  757    subContext.appendScope( subScope );
 
  758    result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok, 
nullptr, context->
feedback(), &aggregateError );
 
  770    result = vl->aggregate( aggregate, subExpression, parameters, 
nullptr, &ok, 
nullptr, 
nullptr, &aggregateError );
 
  774    if ( !aggregateError.isEmpty() )
 
  775      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, aggregateError ) );
 
  777      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
 
  788    parent->
setEvalErrorString( QObject::tr( 
"Cannot use relation aggregate function in this context" ) );
 
  796  QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
  800    parent->
setEvalErrorString( QObject::tr( 
"Cannot use relation aggregate function in this context" ) );
 
  809  QVariant value = node->
eval( parent, context );
 
  811  QString relationId = value.toString();
 
  818    if ( relations.isEmpty() || relations.at( 0 ).referencedLayer() != vl )
 
  820      parent->
setEvalErrorString( QObject::tr( 
"Cannot find relation with id '%1'" ).arg( relationId ) );
 
  825      relation = relations.at( 0 );
 
  832  node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
  834  value = node->
eval( parent, context );
 
  840    parent->
setEvalErrorString( QObject::tr( 
"No such aggregate '%1'" ).arg( value.toString() ) );
 
  845  node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
 
  847  QString subExpression = node->
dump();
 
  851  if ( values.count() > 3 )
 
  853    node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
 
  855    value = node->
eval( parent, context );
 
  862  if ( values.count() > 4 )
 
  864    node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
 
  867    if ( !nl || nl->value().isValid() )
 
  869      orderBy = node->
dump();
 
  880  QString cacheKey = QStringLiteral( 
"relagg:%1:%2:%3:%4:%5" ).arg( vl->id(),
 
  881                     QString::number( 
static_cast< int >( aggregate ) ),
 
  894  result = childLayer->
aggregate( aggregate, subExpression, parameters, &subContext, &ok, 
nullptr, context->
feedback(), &error );
 
  898    if ( !error.isEmpty() )
 
  899      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
 
  901      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
 
  915    parent->
setEvalErrorString( QObject::tr( 
"Cannot use aggregate function in this context" ) );
 
  923  QgsVectorLayer *vl = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
  927    parent->
setEvalErrorString( QObject::tr( 
"Cannot use aggregate function in this context" ) );
 
  936  QString subExpression = node->
dump();
 
  940  if ( values.count() > 1 )
 
  942    node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
  945    if ( !nl || nl->value().isValid() )
 
  946      groupBy = node->
dump();
 
  950  if ( values.count() > 2 )
 
  952    node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
 
  955    if ( !nl || nl->value().isValid() )
 
  961  if ( orderByPos >= 0 && values.count() > orderByPos )
 
  963    node = QgsExpressionUtils::getNode( values.at( orderByPos ), parent );
 
  966    if ( !nl || nl->value().isValid() )
 
  968      orderBy = node->
dump();
 
  976  if ( !groupBy.isEmpty() )
 
  979    QVariant groupByValue = groupByExp.evaluate( context );
 
  980    QString groupByClause = QStringLiteral( 
"%1 %2 %3" ).arg( groupBy,
 
  983    if ( !parameters.
filter.isEmpty() )
 
  984      parameters.
filter = QStringLiteral( 
"(%1) AND (%2)" ).arg( parameters.
filter, groupByClause );
 
  986      parameters.
filter = groupByClause;
 
  992  bool isStatic = 
true;
 
  993  const QSet<QString> refVars = filterExp.referencedVariables() + subExp.referencedVariables();
 
  994  for ( 
const QString &varName : refVars )
 
  997    if ( scope && !scope->
isStatic( varName ) )
 
 1007    cacheKey = QStringLiteral( 
"agg:%1:%2:%3:%4:%5%6:%7" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter,
 
 1008               QString::number( context->
feature().
id() ), QString::number( 
qHash( context->
feature() ) ), orderBy );
 
 1012    cacheKey = QStringLiteral( 
"agg:%1:%2:%3:%4:%5" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.
filter, orderBy );
 
 1024  subContext.appendScope( subScope );
 
 1026  result = vl->aggregate( aggregate, subExpression, parameters, &subContext, &ok, 
nullptr, context->
feedback(), &error );
 
 1030    if ( !error.isEmpty() )
 
 1031      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1 (%2)" ).arg( subExpression, error ) );
 
 1033      parent->
setEvalErrorString( QObject::tr( 
"Could not calculate aggregate for: %1" ).arg( subExpression ) );
 
 1138  if ( values.count() > 3 )
 
 1140    QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
 
 1142    QVariant value = node->
eval( parent, context );
 
 1144    parameters.
delimiter = value.toString();
 
 1155  if ( values.count() > 3 )
 
 1157    QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 3 ), parent );
 
 1159    QVariant value = node->
eval( parent, context );
 
 1161    parameters.
delimiter = value.toString();
 
 1177  QVariant scale = context->
variable( QStringLiteral( 
"map_scale" ) );
 
 1182  const double v = scale.toDouble( &ok );
 
 1190  double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 1191  double testValue = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 1192  double maxValue = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 1195  if ( testValue <= minValue )
 
 1197    return QVariant( minValue );
 
 1199  else if ( testValue >= maxValue )
 
 1201    return QVariant( maxValue );
 
 1205    return QVariant( testValue );
 
 1211  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 1212  return QVariant( std::floor( x ) );
 
 1217  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 1218  return QVariant( std::ceil( x ) );
 
 1223  return QVariant( QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) );
 
 1227  return QVariant( QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ) );
 
 1231  return QVariant( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ) );
 
 1236  QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1237  QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 1238  if ( format.isEmpty() && !language.isEmpty() )
 
 1240    parent->
setEvalErrorString( QObject::tr( 
"A format is required to convert to DateTime when the language is specified" ) );
 
 1241    return QVariant( QDateTime() );
 
 1244  if ( format.isEmpty() && language.isEmpty() )
 
 1245    return QVariant( QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent ) );
 
 1247  QString datetimestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1248  QLocale locale = QLocale();
 
 1249  if ( !language.isEmpty() )
 
 1251    locale = QLocale( language );
 
 1254  QDateTime datetime = locale.toDateTime( datetimestring, format );
 
 1255  if ( !datetime.isValid() )
 
 1257    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to DateTime" ).arg( datetimestring ) );
 
 1258    datetime = QDateTime();
 
 1260  return QVariant( datetime );
 
 1265  const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
 
 1266  const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 1267  const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
 
 1269  const QDate date( year, month, day );
 
 1270  if ( !date.isValid() )
 
 1272    parent->
setEvalErrorString( QObject::tr( 
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
 
 1275  return QVariant( date );
 
 1280  const int hours = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
 
 1281  const int minutes = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 1282  const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 1284  const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
 
 1285  if ( !time.isValid() )
 
 1287    parent->
setEvalErrorString( QObject::tr( 
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
 
 1290  return QVariant( time );
 
 1295  const int year = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
 
 1296  const int month = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 1297  const int day = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
 
 1298  const int hours = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 1299  const int minutes = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
 
 1300  const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
 1302  const QDate date( year, month, day );
 
 1303  if ( !date.isValid() )
 
 1305    parent->
setEvalErrorString( QObject::tr( 
"'%1-%2-%3' is not a valid date" ).arg( year ).arg( month ).arg( day ) );
 
 1308  const QTime time( hours, minutes, std::floor( seconds ), ( seconds - std::floor( seconds ) ) * 1000 );
 
 1309  if ( !time.isValid() )
 
 1311    parent->
setEvalErrorString( QObject::tr( 
"'%1-%2-%3' is not a valid time" ).arg( hours ).arg( minutes ).arg( seconds ) );
 
 1314  return QVariant( QDateTime( date, time ) );
 
 1319  const double years = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 1320  const double months = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 1321  const double weeks = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 1322  const double days = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 1323  const double hours = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 1324  const double minutes = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
 1325  const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
 
 1327  return QVariant::fromValue( 
QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
 
 1332  for ( 
const QVariant &value : values )
 
 1343  const QVariant val1 = values.at( 0 );
 
 1344  const QVariant val2 = values.at( 1 );
 
 1354  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1355  return QVariant( 
str.toLower() );
 
 1359  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1360  return QVariant( 
str.toUpper() );
 
 1364  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1365  QStringList elems = 
str.split( 
' ' );
 
 1366  for ( 
int i = 0; i < elems.size(); i++ )
 
 1368    if ( elems[i].size() > 1 )
 
 1369      elems[i] = elems[i].at( 0 ).toUpper() + elems[i].mid( 1 ).toLower();
 
 1371  return QVariant( elems.join( QLatin1Char( 
' ' ) ) );
 
 1376  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1377  return QVariant( 
str.trimmed() );
 
 1382  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1384  const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1386  const QRegularExpression re( QStringLiteral( 
"^([%1]*)" ).arg( QRegularExpression::escape( characters ) ) );
 
 1387  str.replace( re, QString() );
 
 1388  return QVariant( 
str );
 
 1393  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1395  const QString characters = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1397  const QRegularExpression re( QStringLiteral( 
"([%1]*)$" ).arg( QRegularExpression::escape( characters ) ) );
 
 1398  str.replace( re, QString() );
 
 1399  return QVariant( 
str );
 
 1404  QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1405  QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1411  QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1412  QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1418  QString string1 = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1419  QString string2 = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1426  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1432  QChar character = QChar( QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent ) );
 
 1433  return QVariant( QString( character ) );
 
 1438  QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1440  if ( value.isEmpty() )
 
 1445  int res = value.at( 0 ).unicode();
 
 1446  return QVariant( res );
 
 1451  if ( values.length() == 2 || values.length() == 3 )
 
 1453    QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1454    qlonglong wrap = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 1456    QString customdelimiter = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 1467  if ( values.at( 0 ).userType() == QMetaType::type( 
"QgsGeometry" ) )
 
 1470    QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 1471    if ( geom.
type() != Qgis::GeometryType::Line )
 
 1474    return QVariant( geom.
length() );
 
 1478  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1479  return QVariant( 
str.length() );
 
 1484  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 1486  if ( geom.
type() != Qgis::GeometryType::Line )
 
 1489  double totalLength = 0;
 
 1492    if ( 
const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( *it ) )
 
 1494      totalLength += line->length3D();
 
 1498      std::unique_ptr< QgsLineString > segmentized( qgsgeometry_cast< const QgsCurve * >( *it )->curveToLine() );
 
 1499      totalLength += segmentized->length3D();
 
 1508  if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
 
 1510    QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1511    QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
 
 1512    QVector< QPair< QString, QString > > mapItems;
 
 1514    for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
 
 1516      mapItems.append( qMakePair( it.key(), it.value().toString() ) );
 
 1520    std::sort( mapItems.begin(),
 
 1522               []( 
const QPair< QString, QString > &pair1,
 
 1523                   const QPair< QString, QString > &pair2 )
 
 1525      return ( pair1.first.length() > pair2.first.length() );
 
 1528    for ( 
auto it = mapItems.constBegin(); it != mapItems.constEnd(); ++it )
 
 1530      str = 
str.replace( it->first, it->second );
 
 1533    return QVariant( 
str );
 
 1535  else if ( values.count() == 3 )
 
 1537    QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1538    QVariantList before;
 
 1540    bool isSingleReplacement = 
false;
 
 1542    if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
 
 1544      before = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1548      before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
 
 1551    if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
 
 1553      after = QVariantList() << QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 1554      isSingleReplacement = 
true;
 
 1558      after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
 
 1561    if ( !isSingleReplacement && before.length() != after.length() )
 
 1563      parent->
setEvalErrorString( QObject::tr( 
"Invalid pair of array, length not identical" ) );
 
 1567    for ( 
int i = 0; i < before.length(); i++ )
 
 1569      str = 
str.replace( before.at( i ).toString(), after.at( isSingleReplacement ? 0 : i ).toString() );
 
 1572    return QVariant( 
str );
 
 1576    parent->
setEvalErrorString( QObject::tr( 
"Function replace requires 2 or 3 arguments" ) );
 
 1583  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1584  QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1585  QString after = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 1587  QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
 
 1588  if ( !re.isValid() )
 
 1590    parent->
setEvalErrorString( QObject::tr( 
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
 
 1593  return QVariant( 
str.replace( re, after ) );
 
 1598  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1599  QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1601  QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
 
 1602  if ( !re.isValid() )
 
 1604    parent->
setEvalErrorString( QObject::tr( 
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
 
 1607  return QVariant( ( 
str.indexOf( re ) + 1 ) );
 
 1612  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1613  QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1614  QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 1616  QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
 
 1617  if ( !re.isValid() )
 
 1619    parent->
setEvalErrorString( QObject::tr( 
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
 
 1623  QRegularExpressionMatch matches = re.match( 
str );
 
 1624  if ( matches.hasMatch() )
 
 1627    QStringList list = matches.capturedTexts();
 
 1630    for ( QStringList::const_iterator it = ++list.constBegin(); it != list.constEnd(); ++it )
 
 1632      array += ( !( *it ).isEmpty() ) ? *it : empty;
 
 1635    return QVariant( array );
 
 1645  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1646  QString regexp = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1648  QRegularExpression re( regexp, QRegularExpression::UseUnicodePropertiesOption );
 
 1649  if ( !re.isValid() )
 
 1651    parent->
setEvalErrorString( QObject::tr( 
"Invalid regular expression '%1': %2" ).arg( regexp, re.errorString() ) );
 
 1656  QRegularExpressionMatch match = re.match( 
str );
 
 1657  if ( match.hasMatch() )
 
 1660    if ( match.lastCapturedIndex() > 0 )
 
 1663      return QVariant( match.captured( 1 ) );
 
 1668      return QVariant( match.captured( 0 ) );
 
 1673    return QVariant( 
"" );
 
 1679  QString uuid = QUuid::createUuid().toString();
 
 1680  if ( values.at( 0 ).toString().compare( QStringLiteral( 
"WithoutBraces" ), Qt::CaseInsensitive ) == 0 )
 
 1681    uuid = QUuid::createUuid().toString( QUuid::StringFormat::WithoutBraces );
 
 1682  else if ( values.at( 0 ).toString().compare( QStringLiteral( 
"Id128" ), Qt::CaseInsensitive ) == 0 )
 
 1683    uuid = QUuid::createUuid().toString( QUuid::StringFormat::Id128 );
 
 1689  if ( !values.at( 0 ).isValid() || !values.at( 1 ).isValid() )
 
 1692  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1693  int from = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 1696  if ( values.at( 2 ).isValid() )
 
 1697    len = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 1703    from = 
str.size() + from;
 
 1709  else if ( from > 0 )
 
 1717    len = 
str.size() + len - from;
 
 1724  return QVariant( 
str.mid( from, len ) );
 
 1730  return QVariant( 
static_cast< int >( f.
id() ) );
 
 1735  const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 1736  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
 
 1737  bool foundLayer = 
false;
 
 1738  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, geom]( 
QgsMapLayer * mapLayer )
 
 1740    QgsRasterLayer *layer = qobject_cast< QgsRasterLayer * >( mapLayer );
 
 1741    if ( !layer || !layer->dataProvider() )
 
 1743      parent->setEvalErrorString( QObject::tr( 
"Function `raster_value` requires a valid raster layer." ) );
 
 1747    if ( bandNb < 1 || bandNb > layer->bandCount() )
 
 1749      parent->setEvalErrorString( QObject::tr( 
"Function `raster_value` requires a valid raster band number." ) );
 
 1753    if ( geom.
isNull() || geom.
type() != Qgis::GeometryType::Point )
 
 1755      parent->setEvalErrorString( QObject::tr( 
"Function `raster_value` requires a valid point geometry." ) );
 
 1762      QgsMultiPointXY multiPoint = geom.asMultiPoint();
 
 1763      if ( multiPoint.count() == 1 )
 
 1765        point = multiPoint[0];
 
 1774    double value = layer->dataProvider()->sample( point, bandNb );
 
 1775    return std::isnan( value ) ? QVariant() : value;
 
 1781    parent->
setEvalErrorString( QObject::tr( 
"Function `raster_value` requires a valid raster layer." ) );
 
 1792  const int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 1793  const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 1795  bool foundLayer = 
false;
 
 1796  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, bandNb, value]( 
QgsMapLayer * mapLayer )-> QVariant
 
 1798    QgsRasterLayer *layer = qobject_cast< QgsRasterLayer *>( mapLayer );
 
 1799    if ( !layer || !layer->dataProvider() )
 
 1801      parent->setEvalErrorString( QObject::tr( 
"Function `raster_attributes` requires a valid raster layer." ) );
 
 1805    if ( bandNb < 1 || bandNb > layer->bandCount() )
 
 1807      parent->setEvalErrorString( QObject::tr( 
"Function `raster_attributes` requires a valid raster band number." ) );
 
 1811    if ( std::isnan( value ) )
 
 1813      parent->
setEvalErrorString( QObject::tr( 
"Function `raster_attributes` requires a valid raster value." ) );
 
 1817    if ( ! layer->dataProvider()->attributeTable( bandNb ) )
 
 1822    const QVariantList data = layer->dataProvider()->attributeTable( bandNb )->row( value );
 
 1823    if ( data.isEmpty() )
 
 1829    const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
 
 1830    for ( 
int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
 
 1837      result.insert( fields.at( idx ).name, data.at( idx ) );
 
 1845    parent->
setEvalErrorString( QObject::tr( 
"Function `raster_attributes` requires a valid raster layer." ) );
 
 1866  if ( values.size() == 1 )
 
 1868    attr = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 1871  else if ( values.size() == 2 )
 
 1873    feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 1874    attr = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 1878    parent->
setEvalErrorString( QObject::tr( 
"Function `attribute` requires one or two parameters. %n given.", 
nullptr, values.length() ) );
 
 1887  QString table { R
"html( 
 1893      <tr><td>%2</td></tr> 
 1897  if ( values.size() == 1 )
 
 1899    dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 1903    parent->
setEvalErrorString( QObject::tr( 
"Function `map_to_html_table` requires one parameter. %n given.", 
nullptr, values.length() ) );
 
 1907  if ( dict.isEmpty() )
 
 1912  QStringList headers;
 
 1915  for ( 
auto it = dict.cbegin(); it != dict.cend(); ++it )
 
 1917    headers.push_back( it.key().toHtmlEscaped() );
 
 1918    cells.push_back( it.value().toString( ).toHtmlEscaped() );
 
 1921  return table.arg( headers.join( QLatin1String( 
"</th><th>" ) ), cells.join( QLatin1String( 
"</td><td>" ) ) );
 
 1926  QString table { R
"html( 
 1931  if ( values.size() == 1 )
 
 1933    dict = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 1937    parent->
setEvalErrorString( QObject::tr( 
"Function `map_to_html_dl` requires one parameter. %n given.", 
nullptr, values.length() ) );
 
 1941  if ( dict.isEmpty() )
 
 1948  for ( 
auto it = dict.cbegin(); it != dict.cend(); ++it )
 
 1950    rows.append( QStringLiteral( 
"<dt>%1</dt><dd>%2</dd>" ).arg( it.key().toHtmlEscaped(), it.value().toString().toHtmlEscaped() ) );
 
 1953  return table.arg( rows );
 
 1961    layer = context->
variable( QStringLiteral( 
"layer" ) );
 
 1966    QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
 
 1968    layer = node->
eval( parent, context );
 
 1979    feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
 
 1983  const QString strength = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).toLower();
 
 1984  if ( strength == QLatin1String( 
"hard" ) )
 
 1988  else if ( strength == QLatin1String( 
"soft" ) )
 
 1993  bool foundLayer = 
false;
 
 1994  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, constraintStrength]( 
QgsMapLayer * mapLayer ) -> QVariant
 
 1996    QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
 
 1999      parent->
setEvalErrorString( QObject::tr( 
"No layer provided to conduct constraints checks" ) );
 
 2005    for ( 
int i = 0; i < fields.
size(); i++ )
 
 2020    parent->
setEvalErrorString( QObject::tr( 
"No layer provided to conduct constraints checks" ) );
 
 2032    layer = context->
variable( QStringLiteral( 
"layer" ) );
 
 2037    QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
 2039    layer = node->
eval( parent, context );
 
 2050    feature = QgsExpressionUtils::getFeature( values.at( 2 ), parent );
 
 2054  const QString strength = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).toLower();
 
 2055  if ( strength == QLatin1String( 
"hard" ) )
 
 2059  else if ( strength == QLatin1String( 
"soft" ) )
 
 2064  const QString attributeName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2066  bool foundLayer = 
false;
 
 2067  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [parent, feature, attributeName, constraintStrength]( 
QgsMapLayer * mapLayer ) -> QVariant
 
 2069    QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
 
 2076    if ( fieldIndex == -1 )
 
 2078      parent->
setEvalErrorString( QObject::tr( 
"The attribute name did not match any field for the given feature" ) );
 
 2089    parent->
setEvalErrorString( QObject::tr( 
"No layer provided to conduct constraints checks" ) );
 
 2105    feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 2110  for ( 
int i = 0; i < fields.
count(); ++i )
 
 2124  if ( values.isEmpty() )
 
 2127    layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
 2129  else if ( values.size() == 1 )
 
 2131    layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
 2132    feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 2134  else if ( values.size() == 2 )
 
 2136    layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context,  parent );
 
 2137    feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
 
 2141    parent->
setEvalErrorString( QObject::tr( 
"Function `represent_attributes` requires no more than two parameters. %n given.", 
nullptr, values.length() ) );
 
 2148    parent->
setEvalErrorString( QObject::tr( 
"Cannot use represent attributes function: layer could not be resolved." ) );
 
 2154    parent->
setEvalErrorString( QObject::tr( 
"Cannot use represent attributes function: feature could not be resolved." ) );
 
 2160  for ( 
int fieldIndex = 0; fieldIndex < fields.
count(); ++fieldIndex )
 
 2162    const QString fieldName { fields.
at( fieldIndex ).
name() };
 
 2163    const QVariant attributeVal = feature.
attribute( fieldIndex );
 
 2164    const QString cacheValueKey = QStringLiteral( 
"repvalfcnval:%1:%2:%3" ).arg( layer->
id(), fieldName, attributeVal.toString() );
 
 2167      result.insert( fieldName, context->
cachedValue( cacheValueKey ) );
 
 2176        const QString cacheKey = QStringLiteral( 
"repvalfcn:%1:%2" ).arg( layer->
id(), fieldName );
 
 2188      QString value( fieldFormatter->
representValue( layer, fieldIndex, setup.
config(), cache, attributeVal ) );
 
 2190      result.insert( fields.
at( fieldIndex ).
name(), value );
 
 2206  bool evaluate = 
true;
 
 2210  if ( values.isEmpty() )
 
 2213    layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
 2215  else if ( values.size() == 1 )
 
 2217    layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
 2218    feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 2220  else if ( values.size() == 2 )
 
 2222    layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
 
 2223    feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
 
 2225  else if ( values.size() == 3 )
 
 2227    layer = QgsExpressionUtils::getVectorLayer( values.at( 0 ), context, parent );
 
 2228    feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
 
 2229    evaluate = values.value( 2 ).toBool();
 
 2235      parent->
setEvalErrorString( QObject::tr( 
"Function `maptip` requires no more than three parameters. %n given.", 
nullptr, values.length() ) );
 
 2239      parent->
setEvalErrorString( QObject::tr( 
"Function `display` requires no more than three parameters. %n given.", 
nullptr, values.length() ) );
 
 2271  subContext.setFeature( feature );
 
 2280    exp.prepare( &subContext );
 
 2281    return exp.evaluate( &subContext ).toString();
 
 2287  return fcnCoreFeatureMaptipDisplay( values, context, parent, 
false );
 
 2292  return fcnCoreFeatureMaptipDisplay( values, context, parent, 
true );
 
 2299  if ( values.isEmpty() )
 
 2302    layer = context->
variable( QStringLiteral( 
"layer" ) );
 
 2304  else if ( values.size() == 1 )
 
 2306    feature = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 2307    layer = context->
variable( QStringLiteral( 
"layer" ) );
 
 2309  else if ( values.size() == 2 )
 
 2311    feature = QgsExpressionUtils::getFeature( values.at( 1 ), parent );
 
 2312    layer = values.at( 0 );
 
 2316    parent->
setEvalErrorString( QObject::tr( 
"Function `is_selected` requires no more than two parameters. %n given.", 
nullptr, values.length() ) );
 
 2320  bool foundLayer = 
false;
 
 2321  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, [feature]( 
QgsMapLayer * mapLayer ) -> QVariant
 
 2323    QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
 
 2324    if ( !layer || !feature.
isValid() )
 
 2326      return QVariant( QVariant::Bool );
 
 2332    return  QVariant( QVariant::Bool );
 
 2341  if ( values.isEmpty() )
 
 2342    layer = context->
variable( QStringLiteral( 
"layer" ) );
 
 2343  else if ( values.count() == 1 )
 
 2344    layer = values.at( 0 );
 
 2347    parent->
setEvalErrorString( QObject::tr( 
"Function `num_selected` requires no more than one parameter. %n given.", 
nullptr, values.length() ) );
 
 2351  bool foundLayer = 
false;
 
 2352  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( layer, context, parent, []( 
QgsMapLayer * mapLayer ) -> QVariant
 
 2354    QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( mapLayer );
 
 2357      return QVariant( QVariant::LongLong );
 
 2363    return  QVariant( QVariant::LongLong );
 
 2370  static QMap<QString, qlonglong> counterCache;
 
 2371  QVariant functionResult;
 
 2373  auto fetchAndIncrementFunc = [ values, parent, &functionResult ]( 
QgsMapLayer * mapLayer, 
const QString & databaseArgument )
 
 2377    const QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( mapLayer );
 
 2382      database = decodedUri.value( QStringLiteral( 
"path" ) ).toString();
 
 2383      if ( database.isEmpty() )
 
 2385        parent->
setEvalErrorString( QObject::tr( 
"Could not extract file path from layer `%1`." ).arg( layer->
name() ) );
 
 2390      database = databaseArgument;
 
 2393    const QString table = values.at( 1 ).toString();
 
 2394    const QString idColumn = values.at( 2 ).toString();
 
 2395    const QString filterAttribute = values.at( 3 ).toString();
 
 2396    const QVariant filterValue = values.at( 4 ).toString();
 
 2397    const QVariantMap defaultValues = values.at( 5 ).toMap();
 
 2403    if ( sqliteDb.
open_v2( database, SQLITE_OPEN_READWRITE, 
nullptr ) != SQLITE_OK )
 
 2406      functionResult = QVariant();
 
 2410    QString errorMessage;
 
 2411    QString currentValSql;
 
 2413    qlonglong nextId = 0;
 
 2414    bool cachedMode = 
false;
 
 2415    bool valueRetrieved = 
false;
 
 2417    QString cacheString = QStringLiteral( 
"%1:%2:%3:%4:%5" ).arg( database, table, idColumn, filterAttribute, filterValue.toString() );
 
 2424      auto cachedCounter = counterCache.find( cacheString );
 
 2426      if ( cachedCounter != counterCache.end() )
 
 2428        qlonglong &cachedValue = cachedCounter.value();
 
 2429        nextId = cachedValue;
 
 2431        cachedValue = nextId;
 
 2432        valueRetrieved = 
true;
 
 2437    if ( !cachedMode || !valueRetrieved )
 
 2439      int result = SQLITE_ERROR;
 
 2442      if ( !filterAttribute.isNull() )
 
 2447      sqliteStatement = sqliteDb.
prepare( currentValSql, result );
 
 2449      if ( result == SQLITE_OK )
 
 2452        if ( sqliteStatement.
step() == SQLITE_ROW )
 
 2458        if ( cachedMode && result == SQLITE_OK )
 
 2460          counterCache.insert( cacheString, nextId );
 
 2464            counterCache.remove( cacheString );
 
 2467        valueRetrieved = 
true;
 
 2471    if ( valueRetrieved )
 
 2480      if ( !filterAttribute.isNull() )
 
 2486      for ( QVariantMap::const_iterator iter = defaultValues.constBegin(); iter != defaultValues.constEnd(); ++iter )
 
 2489        vals << iter.value().toString();
 
 2492      upsertSql += QLatin1String( 
" (" ) + cols.join( 
',' ) + 
')';
 
 2493      upsertSql += QLatin1String( 
" VALUES " );
 
 2494      upsertSql += 
'(' + vals.join( 
',' ) + 
')';
 
 2496      int result = SQLITE_ERROR;
 
 2500        if ( transaction->
executeSql( upsertSql, errorMessage ) )
 
 2507        result = sqliteDb.
exec( upsertSql, errorMessage );
 
 2509      if ( result == SQLITE_OK )
 
 2511        functionResult = QVariant( nextId );
 
 2516        parent->
setEvalErrorString( QStringLiteral( 
"Could not increment value: SQLite error: \"%1\" (%2)." ).arg( errorMessage, QString::number( result ) ) );
 
 2517        functionResult = QVariant();
 
 2522    functionResult = QVariant();
 
 2525  bool foundLayer = 
false;
 
 2526  QgsExpressionUtils::executeLambdaForMapLayer( values.at( 0 ), context, parent, [&fetchAndIncrementFunc]( 
QgsMapLayer * layer )
 
 2528    fetchAndIncrementFunc( layer, QString() );
 
 2532    const QString databasePath = values.at( 0 ).toString();
 
 2535      fetchAndIncrementFunc( 
nullptr, databasePath );
 
 2539  return functionResult;
 
 2545  for ( 
const QVariant &value : values )
 
 2548      concat += QgsExpressionUtils::getStringValue( value, parent );
 
 2555  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2556  return string.indexOf( QgsExpressionUtils::getStringValue( values.at( 1 ), parent ) ) + 1;
 
 2561  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2562  int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 2563  return string.right( pos );
 
 2568  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2569  int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 2570  return string.left( pos );
 
 2575  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2576  int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 2577  QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 2578  return string.leftJustified( length, fill.at( 0 ), 
true );
 
 2583  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2584  int length = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 2585  QString fill = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 2586  return string.rightJustified( length, fill.at( 0 ), 
true );
 
 2591  if ( values.size() < 1 )
 
 2593    parent->
setEvalErrorString( QObject::tr( 
"Function format requires at least 1 argument" ) );
 
 2597  QString 
string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2598  for ( 
int n = 1; n < values.length(); n++ )
 
 2600    string = 
string.arg( QgsExpressionUtils::getStringValue( values.at( n ), parent ) );
 
 2608  return QVariant( QDateTime::currentDateTime() );
 
 2613  QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 2614  QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 2615  if ( format.isEmpty() && !language.isEmpty() )
 
 2617    parent->
setEvalErrorString( QObject::tr( 
"A format is required to convert to Date when the language is specified" ) );
 
 2618    return QVariant( QDate() );
 
 2621  if ( format.isEmpty() && language.isEmpty() )
 
 2622    return QVariant( QgsExpressionUtils::getDateValue( values.at( 0 ), parent ) );
 
 2624  QString datestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2625  QLocale locale = QLocale();
 
 2626  if ( !language.isEmpty() )
 
 2628    locale = QLocale( language );
 
 2631  QDate date = locale.toDate( datestring, format );
 
 2632  if ( !date.isValid() )
 
 2634    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to Date" ).arg( datestring ) );
 
 2637  return QVariant( date );
 
 2642  QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 2643  QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 2644  if ( format.isEmpty() && !language.isEmpty() )
 
 2646    parent->
setEvalErrorString( QObject::tr( 
"A format is required to convert to Time when the language is specified" ) );
 
 2647    return QVariant( QTime() );
 
 2650  if ( format.isEmpty() && language.isEmpty() )
 
 2651    return QVariant( QgsExpressionUtils::getTimeValue( values.at( 0 ), parent ) );
 
 2653  QString timestring = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 2654  QLocale locale = QLocale();
 
 2655  if ( !language.isEmpty() )
 
 2657    locale = QLocale( language );
 
 2660  QTime time = locale.toTime( timestring, format );
 
 2661  if ( !time.isValid() )
 
 2663    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to Time" ).arg( timestring ) );
 
 2666  return QVariant( time );
 
 2671  return QVariant::fromValue( QgsExpressionUtils::getInterval( values.at( 0 ), parent ) );
 
 2680  double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 2681  QString axis = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 2682  int precision = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 2684  QString formatString;
 
 2685  if ( values.count() > 3 )
 
 2686    formatString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent );
 
 2688  QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
 
 2689  if ( formatString.compare( QLatin1String( 
"suffix" ), Qt::CaseInsensitive ) == 0 )
 
 2693  else if ( formatString.compare( QLatin1String( 
"aligned" ), Qt::CaseInsensitive ) == 0 )
 
 2697  else if ( ! formatString.isEmpty() )
 
 2699    parent->
setEvalErrorString( QObject::tr( 
"Invalid formatting parameter: '%1'. It must be empty, or 'suffix' or 'aligned'." ).arg( formatString ) );
 
 2703  if ( axis.compare( QLatin1String( 
"x" ), Qt::CaseInsensitive ) == 0 )
 
 2707  else if ( axis.compare( QLatin1String( 
"y" ), Qt::CaseInsensitive ) == 0 )
 
 2713    parent->
setEvalErrorString( QObject::tr( 
"Invalid axis name: '%1'. It must be either 'x' or 'y'." ).arg( axis ) );
 
 2721  return floatToDegreeFormat( format, values, context, parent, node );
 
 2728  value = QgsCoordinateUtils::dmsToDecimal( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), &ok );
 
 2730  return ok ? QVariant( value ) : QVariant();
 
 2736  return floatToDegreeFormat( format, values, context, parent, node );
 
 2741  QDateTime d1 = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
 
 2742  QDateTime d2 = QgsExpressionUtils::getDateTimeValue( values.at( 1 ), parent );
 
 2743  qint64 seconds = d2.secsTo( d1 );
 
 2744  return QVariant::fromValue( 
QgsInterval( seconds ) );
 
 2749  if ( !values.at( 0 ).canConvert<QDate>() )
 
 2752  QDate date = QgsExpressionUtils::getDateValue( values.at( 0 ), parent );
 
 2753  if ( !date.isValid() )
 
 2758  return date.dayOfWeek() % 7;
 
 2763  QVariant value = values.at( 0 );
 
 2764  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2767    return QVariant( inter.
days() );
 
 2771    QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
 
 2772    return QVariant( d1.date().day() );
 
 2778  QVariant value = values.at( 0 );
 
 2779  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2782    return QVariant( inter.
years() );
 
 2786    QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
 
 2787    return QVariant( d1.date().year() );
 
 2793  QVariant value = values.at( 0 );
 
 2794  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2797    return QVariant( inter.
months() );
 
 2801    QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
 
 2802    return QVariant( d1.date().month() );
 
 2808  QVariant value = values.at( 0 );
 
 2809  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2812    return QVariant( inter.
weeks() );
 
 2816    QDateTime d1 = QgsExpressionUtils::getDateTimeValue( value, parent );
 
 2817    return QVariant( d1.date().weekNumber() );
 
 2823  QVariant value = values.at( 0 );
 
 2824  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2827    return QVariant( inter.
hours() );
 
 2831    QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
 
 2832    return QVariant( t1.hour() );
 
 2838  QVariant value = values.at( 0 );
 
 2839  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2842    return QVariant( inter.
minutes() );
 
 2846    QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
 
 2847    return QVariant( t1.minute() );
 
 2853  QVariant value = values.at( 0 );
 
 2854  QgsInterval inter = QgsExpressionUtils::getInterval( value, parent, 
false );
 
 2857    return QVariant( inter.
seconds() );
 
 2861    QTime t1 = QgsExpressionUtils::getTimeValue( value, parent );
 
 2862    return QVariant( t1.second() );
 
 2868  QDateTime dt = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
 
 2871    return QVariant( dt.toMSecsSinceEpoch() );
 
 2881  long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
 
 2883  return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
 
 2888  const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 2891    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"exif" ) ) );
 
 2894  QString tag = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 2900  const QString filepath = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 2903    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"exif_geotag" ) ) );
 
 2910#define ENSURE_GEOM_TYPE(f, g, geomtype) \ 
 2911  if ( !(f).hasGeometry() ) \ 
 2912    return QVariant(); \ 
 2913  QgsGeometry g = (f).geometry(); \ 
 2914  if ( (g).type() != (geomtype) ) \ 
 2921  if ( g.isMultipart() )
 
 2923    return g.asMultiPoint().at( 0 ).x();
 
 2927    return g.asPoint().x();
 
 2935  if ( g.isMultipart() )
 
 2937    return g.asMultiPoint().at( 0 ).y();
 
 2941    return g.asPoint().y();
 
 2955  if ( g.isEmpty() || !abGeom->
is3D() )
 
 2958  if ( g.type() == Qgis::GeometryType::Point && !g.isMultipart() )
 
 2960    const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
 
 2964  else if ( g.type() == Qgis::GeometryType::Point && g.isMultipart() )
 
 2966    if ( 
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
 
 2968      if ( collection->numGeometries() > 0 )
 
 2970        if ( 
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
 
 2981  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 2987  return QVariant( isValid );
 
 2992  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 2996  const QString methodString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).trimmed();
 
 2997#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10 
 3002  if ( methodString.compare( QLatin1String( 
"linework" ), Qt::CaseInsensitive ) == 0 )
 
 3004  else if ( methodString.compare( QLatin1String( 
"structure" ), Qt::CaseInsensitive ) == 0 )
 
 3007  const bool keepCollapsed = values.value( 2 ).toBool();
 
 3012    valid = geom.
makeValid( method, keepCollapsed );
 
 3016    parent->
setEvalErrorString( QObject::tr( 
"The make_valid parameters require a newer GEOS library version" ) );
 
 3020  return QVariant::fromValue( valid );
 
 3025  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3031  for ( 
int i = 0; i < multiGeom.size(); ++i )
 
 3033    array += QVariant::fromValue( multiGeom.at( i ) );
 
 3041  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3046  if ( geom.
type() == Qgis::GeometryType::Point && !geom.
isMultipart() )
 
 3053  QVariant result( 
centroid.asPoint().
x() );
 
 3059  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3064  if ( geom.
type() == Qgis::GeometryType::Point && !geom.
isMultipart() )
 
 3071  QVariant result( 
centroid.asPoint().
y() );
 
 3077  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3085  if ( geom.
type() == Qgis::GeometryType::Point && !geom.
isMultipart() )
 
 3087    const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3091  else if ( geom.
type() == Qgis::GeometryType::Point && geom.
isMultipart() )
 
 3095      if ( collection->numGeometries() == 1 )
 
 3097        if ( 
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
 
 3108  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3116  if ( geom.
type() == Qgis::GeometryType::Point && !geom.
isMultipart() )
 
 3118    const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3122  else if ( geom.
type() == Qgis::GeometryType::Point && geom.
isMultipart() )
 
 3126      if ( collection->numGeometries() == 1 )
 
 3128        if ( 
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
 
 3139  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3144  int idx = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 3171  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3188  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3205  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3210  bool ignoreClosing = 
false;
 
 3211  if ( values.length() > 1 )
 
 3213    ignoreClosing = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 3223      bool skipLast = 
false;
 
 3224      if ( ignoreClosing && ring.count() > 2 && ring.first() == ring.last() )
 
 3229      for ( 
int i = 0; i < ( skipLast ? ring.count() - 1 : ring.count() ); ++ i )
 
 3241  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3252    for ( 
int i = 0; i < line->numPoints() - 1; ++i )
 
 3256                          << line->pointN( i )
 
 3257                          << line->pointN( i + 1 ) );
 
 3268  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3278      if ( collection->numGeometries() == 1 )
 
 3280        curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN( 0 ) );
 
 3285  if ( !curvePolygon )
 
 3289  qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
 
 3295  QVariant result = curve ? QVariant::fromValue( 
QgsGeometry( curve ) ) : QVariant();
 
 3301  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3311  qlonglong idx = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) - 1;
 
 3317  QVariant result = part ? QVariant::fromValue( 
QgsGeometry( part ) ) : QVariant();
 
 3323  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3332  return QVariant::fromValue( 
QgsGeometry( boundary ) );
 
 3337  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3346  return QVariant::fromValue( merged );
 
 3351  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3355  const QgsGeometry geom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 3360  if ( sharedPaths.
isNull() )
 
 3363  return QVariant::fromValue( sharedPaths );
 
 3369  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3374  double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3377  if ( simplified.
isNull() )
 
 3385  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3390  double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3395  if ( simplified.
isNull() )
 
 3403  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3408  int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 );
 
 3409  double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 );
 
 3410  double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 3411  double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 );
 
 3413  QgsGeometry smoothed = geom.
smooth( 
static_cast<unsigned int>( iterations ), offset, minLength, maxAngle );
 
 3422  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3427  const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3428  const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3429  const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 3440  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3445  const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3446  const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3447  const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 3448  const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 3449  const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
 
 3452                            minAmplitude, maxAmplitude, seed );
 
 3461  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3466  const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3467  const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3468  const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 3479  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3484  const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3485  const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3486  const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 3487  const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 3488  const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
 
 3491                            minAmplitude, maxAmplitude, seed );
 
 3500  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3505  const double wavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3506  const double amplitude = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3507  const bool strict = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 3518  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3523  const double minWavelength = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3524  const double maxWavelength = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3525  const double minAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 3526  const double maxAmplitude = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 3527  const long long seed = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
 
 3530                            minAmplitude, maxAmplitude, seed );
 
 3539  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3544  const QVariantList pattern = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
 
 3545  QVector< double > dashPattern;
 
 3546  dashPattern.reserve( pattern.size() );
 
 3547  for ( 
const QVariant &value : std::as_const( pattern ) )
 
 3550    double v = value.toDouble( &ok );
 
 3557      parent->
setEvalErrorString( QStringLiteral( 
"Dash pattern must be an array of numbers" ) );
 
 3562  if ( dashPattern.size() % 2 != 0 )
 
 3564    parent->
setEvalErrorString( QStringLiteral( 
"Dash pattern must contain an even number of elements" ) );
 
 3568  const QString startRuleString = QgsExpressionUtils::getStringValue( values.at( 2 ), parent ).trimmed();
 
 3570  if ( startRuleString.compare( QLatin1String( 
"no_rule" ), Qt::CaseInsensitive ) == 0 )
 
 3572  else if ( startRuleString.compare( QLatin1String( 
"full_dash" ), Qt::CaseInsensitive ) == 0 )
 
 3574  else if ( startRuleString.compare( QLatin1String( 
"half_dash" ), Qt::CaseInsensitive ) == 0 )
 
 3576  else if ( startRuleString.compare( QLatin1String( 
"full_gap" ), Qt::CaseInsensitive ) == 0 )
 
 3578  else if ( startRuleString.compare( QLatin1String( 
"half_gap" ), Qt::CaseInsensitive ) == 0 )
 
 3582    parent->
setEvalErrorString( QStringLiteral( 
"'%1' is not a valid dash pattern rule" ).arg( startRuleString ) );
 
 3586  const QString endRuleString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
 
 3588  if ( endRuleString.compare( QLatin1String( 
"no_rule" ), Qt::CaseInsensitive ) == 0 )
 
 3590  else if ( endRuleString.compare( QLatin1String( 
"full_dash" ), Qt::CaseInsensitive ) == 0 )
 
 3592  else if ( endRuleString.compare( QLatin1String( 
"half_dash" ), Qt::CaseInsensitive ) == 0 )
 
 3594  else if ( endRuleString.compare( QLatin1String( 
"full_gap" ), Qt::CaseInsensitive ) == 0 )
 
 3596  else if ( endRuleString.compare( QLatin1String( 
"half_gap" ), Qt::CaseInsensitive ) == 0 )
 
 3600    parent->
setEvalErrorString( QStringLiteral( 
"'%1' is not a valid dash pattern rule" ).arg( endRuleString ) );
 
 3604  const QString adjustString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
 
 3606  if ( adjustString.compare( QLatin1String( 
"both" ), Qt::CaseInsensitive ) == 0 )
 
 3608  else if ( adjustString.compare( QLatin1String( 
"dash" ), Qt::CaseInsensitive ) == 0 )
 
 3610  else if ( adjustString.compare( QLatin1String( 
"gap" ), Qt::CaseInsensitive ) == 0 )
 
 3614    parent->
setEvalErrorString( QStringLiteral( 
"'%1' is not a valid dash pattern size adjustment" ).arg( adjustString ) );
 
 3618  const double patternOffset = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
 3629  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3634  const long long count = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 3636  if ( densified.
isNull() )
 
 3644  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3649  const double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3651  if ( densified.
isNull() )
 
 3660  if ( values.size() == 1 && QgsExpressionUtils::isList( values.at( 0 ) ) )
 
 3662    list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 3669  QVector< QgsGeometry > parts;
 
 3670  parts.reserve( list.size() );
 
 3671  for ( 
const QVariant &value : std::as_const( list ) )
 
 3673    if ( value.userType() == QMetaType::type( 
"QgsGeometry" ) )
 
 3689  if ( values.count() < 2 || values.count() > 4 )
 
 3691    parent->
setEvalErrorString( QObject::tr( 
"Function make_point requires 2-4 arguments" ) );
 
 3695  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 3696  double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3697  double z = values.count() >= 3 ? QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ) : 0.0;
 
 3698  double m = values.count() >= 4 ? QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ) : 0.0;
 
 3699  switch ( values.count() )
 
 3713  double x = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 3714  double y = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3715  double m = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3721  if ( values.empty() )
 
 3726  QVector<QgsPoint> points;
 
 3727  points.reserve( values.count() );
 
 3729  auto addPoint = [&points]( 
const QgsGeometry & geom )
 
 3737    const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3744  for ( 
const QVariant &value : values )
 
 3746    if ( value.type() == QVariant::List )
 
 3748      const QVariantList list = value.toList();
 
 3749      for ( 
const QVariant &v : list )
 
 3751        addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
 
 3756      addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
 
 3760  if ( points.count() < 2 )
 
 3768  if ( values.count() < 1 )
 
 3770    parent->
setEvalErrorString( QObject::tr( 
"Function make_polygon requires an argument" ) );
 
 3774  QgsGeometry outerRing = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3776  if ( outerRing.
type() == Qgis::GeometryType::Polygon )
 
 3779  if ( outerRing.
type() != Qgis::GeometryType::Line || outerRing.
isNull() )
 
 3782  std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
 
 3784  const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.
constGet() );
 
 3791        exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
 
 3796  if ( !exteriorRing )
 
 3799  polygon->setExteriorRing( exteriorRing->
segmentize() );
 
 3802  for ( 
int i = 1; i < values.count(); ++i )
 
 3804    QgsGeometry ringGeom = QgsExpressionUtils::getGeometry( values.at( i ), parent );
 
 3808    if ( ringGeom.
type() != Qgis::GeometryType::Line || ringGeom.
isNull() )
 
 3811    const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.
constGet() );
 
 3818          ring = qgsgeometry_cast< QgsCurve * >( collection->
geometryN( 0 ) );
 
 3826    polygon->addInteriorRing( ring->
segmentize() );
 
 3829  return QVariant::fromValue( 
QgsGeometry( std::move( polygon ) ) );
 
 3834  std::unique_ptr<QgsTriangle> tr( 
new QgsTriangle() );
 
 3835  std::unique_ptr<QgsLineString> lineString( 
new QgsLineString() );
 
 3836  lineString->clear();
 
 3838  for ( 
const QVariant &value : values )
 
 3840    QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
 
 3847    const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3854          point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 3862    lineString->addVertex( *point );
 
 3865  tr->setExteriorRing( lineString.release() );
 
 3867  return QVariant::fromValue( 
QgsGeometry( tr.release() ) );
 
 3872  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3879  double radius = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3880  int segment = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 3887  const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3894        point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 3902  return QVariant::fromValue( 
QgsGeometry( circ.toPolygon( 
static_cast<unsigned int>( 
segment ) ) ) );
 
 3907  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3914  double majorAxis = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 3915  double minorAxis = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 3916  double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 3917  int segment = QgsExpressionUtils::getNativeIntValue( values.at( 4 ), parent );
 
 3923  const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.
constGet() );
 
 3930        point = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 3937  QgsEllipse elp( *point, majorAxis,  minorAxis, azimuth );
 
 3938  return QVariant::fromValue( 
QgsGeometry( elp.toPolygon( 
static_cast<unsigned int>( 
segment ) ) ) );
 
 3944  QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 3951  QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 3958  unsigned int nbEdges = 
static_cast<unsigned int>( QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) );
 
 3961    parent->
setEvalErrorString( QObject::tr( 
"Number of edges/sides must be greater than 2" ) );
 
 3968    parent->
setEvalErrorString( QObject::tr( 
"Option can be 0 (inscribed) or 1 (circumscribed)" ) );
 
 3972  const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.
constGet() );
 
 3979        center = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 3986  const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.
constGet() );
 
 3993        corner = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 4008  QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4014  QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4020  const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
 
 4021  const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
 
 4029  QgsGeometry pt1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4035  QgsGeometry pt2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4041  QgsGeometry pt3 = QgsExpressionUtils::getGeometry( values.at( 2 ), parent );
 
 4050    parent->
setEvalErrorString( QObject::tr( 
"Option can be 0 (distance) or 1 (projected)" ) );
 
 4053  const QgsPoint *point1 = qgsgeometry_cast< const QgsPoint *>( pt1.
constGet() );
 
 4054  const QgsPoint *point2 = qgsgeometry_cast< const QgsPoint *>( pt2.
constGet() );
 
 4055  const QgsPoint *point3 = qgsgeometry_cast< const QgsPoint *>( pt3.
constGet() );
 
 4074  return QVariant::fromValue( geom.
vertexAt( idx ) );
 
 4082  const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
 
 4084  const QVariant v = pointAt( geom, idx, parent );
 
 4087    return QVariant( v.value<
QgsPoint>().
x() );
 
 4093  if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() ) 
 
 4095    return fcnOldXat( values, f, parent, node );
 
 4097  else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() ) 
 
 4099    return fcnOldXat( QVariantList() << values[1], f, parent, node );
 
 4102  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4108  const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 4110  const QVariant v = pointAt( geom, vertexNumber, parent );
 
 4112    return QVariant( v.value<
QgsPoint>().
x() );
 
 4122  const int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
 
 4124  const QVariant v = pointAt( geom, idx, parent );
 
 4127    return QVariant( v.value<
QgsPoint>().
y() );
 
 4133  if ( values.at( 1 ).isNull() && !values.at( 0 ).isNull() ) 
 
 4135    return fcnOldYat( values, f, parent, node );
 
 4137  else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() ) 
 
 4139    return fcnOldYat( QVariantList() << values[1], f, parent, node );
 
 4142  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4148  const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 4150  const QVariant v = pointAt( geom, vertexNumber, parent );
 
 4152    return QVariant( v.value<
QgsPoint>().
y() );
 
 4159  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4165  const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 4167  const QVariant v = pointAt( geom, vertexNumber, parent );
 
 4169    return QVariant( v.value<
QgsPoint>().
z() );
 
 4176  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4182  const int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 4184  const QVariant v = pointAt( geom, vertexNumber, parent );
 
 4186    return QVariant( v.value<
QgsPoint>().
m() );
 
 4205      return  QVariant::fromValue( geom );
 
 4213  QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 4215  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4221  const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
 
 4227  return !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4232  QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 4239      ogcContext.
layer = mapLayerPtr.data();
 
 4240      ogcContext.
transformContext = context->
variable( QStringLiteral( 
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
 
 4244  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4257    return QVariant( area );
 
 4267  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4269  if ( geom.
type() != Qgis::GeometryType::Polygon )
 
 4272  return QVariant( geom.
area() );
 
 4284    return QVariant( len );
 
 4301    return QVariant( len );
 
 4305    return f.
geometry().
isNull() ? QVariant( 0 ) : QVariant( f.geometry().constGet()->perimeter() );
 
 4311  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4313  if ( geom.
type() != Qgis::GeometryType::Polygon )
 
 4317  return QVariant( geom.
length() );
 
 4322  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4328  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4337  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4346  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4361      curvePolygon = qgsgeometry_cast< const QgsCurvePolygon *>( collection->
geometryN( i ) );
 
 4362      if ( !curvePolygon )
 
 4374  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4381    return QVariant( curvePolygon->
ringCount() );
 
 4383  bool foundPoly = 
false;
 
 4391      curvePolygon = qgsgeometry_cast< QgsCurvePolygon *>( collection->
geometryN( i ) );
 
 4392      if ( !curvePolygon )
 
 4403  return QVariant( ringCount );
 
 4408  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4410  QVariant result = !geomBounds.
isNull() ? QVariant::fromValue( geomBounds ) : QVariant();
 
 4416  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4422  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4428  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4437  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4443  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4449  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4455  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4461  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4469  double max = std::numeric_limits< double >::lowest();
 
 4473    double z = ( *it ).z();
 
 4479  if ( max == std::numeric_limits< double >::lowest() )
 
 4480    return QVariant( QVariant::Double );
 
 4482  return QVariant( max );
 
 4487  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4495  double min = std::numeric_limits< double >::max();
 
 4499    double z = ( *it ).z();
 
 4505  if ( min == std::numeric_limits< double >::max() )
 
 4506    return QVariant( QVariant::Double );
 
 4508  return QVariant( min );
 
 4513  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4521  double min = std::numeric_limits< double >::max();
 
 4525    double m = ( *it ).m();
 
 4531  if ( min == std::numeric_limits< double >::max() )
 
 4532    return QVariant( QVariant::Double );
 
 4534  return QVariant( min );
 
 4539  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4547  double max = std::numeric_limits< double >::lowest();
 
 4551    double m = ( *it ).m();
 
 4557  if ( max == std::numeric_limits< double >::lowest() )
 
 4558    return QVariant( QVariant::Double );
 
 4560  return QVariant( max );
 
 4565  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4566  const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom.
constGet() );
 
 4569    parent->
setEvalErrorString( QObject::tr( 
"Function `sinuosity` requires a line geometry." ) );
 
 4578  const QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4582    parent->
setEvalErrorString( QObject::tr( 
"Function `straight_distance_2d` requires a line geometry or a multi line geometry with a single part." ) );
 
 4591  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4596    parent->
setEvalErrorString( QObject::tr( 
"Function `roundness` requires a polygon geometry or a multi polygon geometry with a single part." ) );
 
 4607  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4611  std::unique_ptr< QgsAbstractGeometry > flipped( geom.
constGet()->
clone() );
 
 4613  return QVariant::fromValue( 
QgsGeometry( std::move( flipped ) ) );
 
 4618  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4622  const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom.
constGet() );
 
 4629        curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
 
 4637  return QVariant::fromValue( curve->
isClosed() );
 
 4642  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4655    std::unique_ptr< QgsLineString > closedLine( line->
clone() );
 
 4656    closedLine->close();
 
 4658    result = QVariant::fromValue( 
QgsGeometry( std::move( closedLine ) ) );
 
 4668      if ( 
const QgsLineString *line = qgsgeometry_cast<const QgsLineString * >( collection->
geometryN( i ) ) )
 
 4670        std::unique_ptr< QgsLineString > closedLine( line->
clone() );
 
 4671        closedLine->close();
 
 4673        closed->addGeometry( closedLine.release() );
 
 4676    result = QVariant::fromValue( 
QgsGeometry( std::move( closed ) ) );
 
 4684  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4688  return QVariant::fromValue( fGeom.
isEmpty() );
 
 4694    return QVariant::fromValue( 
true );
 
 4696  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4697  return QVariant::fromValue( fGeom.
isNull() || fGeom.
isEmpty() );
 
 4702  if ( values.length() < 2 || values.length() > 3 )
 
 4705  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4706  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4713  if ( values.length() == 2 )
 
 4716    QString result = engine->relate( sGeom.
constGet() );
 
 4717    return QVariant::fromValue( result );
 
 4722    QString pattern = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 4723    bool result = engine->relatePattern( sGeom.
constGet(), pattern );
 
 4724    return QVariant::fromValue( result );
 
 4730  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4731  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4736  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4737  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4738  return fGeom.
disjoint( sGeom ) ? TVL_True : TVL_False;
 
 4742  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4743  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4744  return fGeom.
intersects( sGeom ) ? TVL_True : TVL_False;
 
 4748  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4749  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4750  return fGeom.
touches( sGeom ) ? TVL_True : TVL_False;
 
 4754  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4755  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4756  return fGeom.
crosses( sGeom ) ? TVL_True : TVL_False;
 
 4760  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4761  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4762  return fGeom.
contains( sGeom ) ? TVL_True : TVL_False;
 
 4766  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4767  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4768  return fGeom.
overlaps( sGeom ) ? TVL_True : TVL_False;
 
 4772  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4773  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 4774  return fGeom.
within( sGeom ) ? TVL_True : TVL_False;
 
 4779  const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4780  const double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4781  const int seg = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 4782  const QString endCapString = QgsExpressionUtils::getStringValue( values.at( 3 ), parent ).trimmed();
 
 4783  const QString joinString = QgsExpressionUtils::getStringValue( values.at( 4 ), parent ).trimmed();
 
 4784  const double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
 4787  if ( endCapString.compare( QLatin1String( 
"flat" ), Qt::CaseInsensitive ) == 0 )
 
 4788    capStyle = Qgis::EndCapStyle::Flat;
 
 4789  else if ( endCapString.compare( QLatin1String( 
"square" ), Qt::CaseInsensitive ) == 0 )
 
 4790    capStyle = Qgis::EndCapStyle::Square;
 
 4793  if ( joinString.compare( QLatin1String( 
"miter" ), Qt::CaseInsensitive ) == 0 )
 
 4794    joinStyle = Qgis::JoinStyle::Miter;
 
 4795  else if ( joinString.compare( QLatin1String( 
"bevel" ), Qt::CaseInsensitive ) == 0 )
 
 4796    joinStyle = Qgis::JoinStyle::Bevel;
 
 4799  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4805  const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4807  return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
 
 4812  const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4814  return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
 
 4819  const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4821  return !reoriented.
isNull() ? QVariant::fromValue( reoriented ) : QVariant();
 
 4826  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4827  const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.
constGet() );
 
 4834        pt = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 4841    parent->
setEvalErrorString( QObject::tr( 
"Function `wedge_buffer` requires a point value for the center." ) );
 
 4845  double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4846  double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 4847  double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 4848  double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 4851  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4857  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4858  if ( fGeom.
type() != Qgis::GeometryType::Line )
 
 4860    parent->
setEvalErrorString( QObject::tr( 
"Function `tapered_buffer` requires a line geometry." ) );
 
 4864  double startWidth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4865  double endWidth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 4866  int segments = 
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) );
 
 4869  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4875  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4876  if ( fGeom.
type() != Qgis::GeometryType::Line )
 
 4878    parent->
setEvalErrorString( QObject::tr( 
"Function `buffer_by_m` requires a line geometry." ) );
 
 4882  int segments = 
static_cast< int >( QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) );
 
 4885  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4891  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4892  double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4893  int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 4894  const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 4895  if ( joinInt < 1 || joinInt > 3 )
 
 4899  double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 4902  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4908  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4909  double dist = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4910  int segments = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 4912  const int joinInt = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
 
 4913  if ( joinInt < 1 || joinInt > 3 )
 
 4917  double miterLimit = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 4920  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4926  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4927  double distStart = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4928  double distEnd = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 4931  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 4937  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4938  double dx = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4939  double dy = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 4941  return QVariant::fromValue( fGeom );
 
 4946  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4947  const double rotation = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4948  const QgsGeometry center = values.at( 2 ).
isValid() ? QgsExpressionUtils::getGeometry( values.at( 2 ), parent )
 
 4950  const bool perPart = values.value( 3 ).toBool();
 
 4957    std::unique_ptr< QgsGeometryCollection > collection( qgsgeometry_cast< QgsGeometryCollection * >( fGeom.
constGet()->
clone() ) );
 
 4960      const QgsPointXY partCenter = ( *it )->boundingBox().center();
 
 4961      QTransform t = QTransform::fromTranslate( partCenter.
x(), partCenter.
y() );
 
 4962      t.rotate( -rotation );
 
 4963      t.translate( -partCenter.
x(), -partCenter.
y() );
 
 4964      ( *it )->transform( t );
 
 4966    return QVariant::fromValue( 
QgsGeometry( std::move( collection ) ) );
 
 4978      parent->
setEvalErrorString( QObject::tr( 
"Function 'rotate' requires a point value for the center" ) );
 
 4986    fGeom.
rotate( rotation, pt );
 
 4987    return QVariant::fromValue( fGeom );
 
 4993  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 4994  const double xScale = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 4995  const double yScale = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 4996  const QgsGeometry center = values.at( 3 ).isValid() ? QgsExpressionUtils::getGeometry( values.at( 3 ), parent )
 
 5007    parent->
setEvalErrorString( QObject::tr( 
"Function 'scale' requires a point value for the center" ) );
 
 5015  QTransform t = QTransform::fromTranslate( pt.
x(), pt.
y() );
 
 5016  t.scale( xScale, yScale );
 
 5017  t.translate( -pt.
x(), -pt.
y() );
 
 5019  return QVariant::fromValue( fGeom );
 
 5024  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5030  const double deltaX = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5031  const double deltaY = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5033  const double rotationZ = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 5035  const double scaleX = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
 
 5036  const double scaleY = QgsExpressionUtils::getDoubleValue( values.at( 5 ), parent );
 
 5038  const double deltaZ = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
 
 5039  const double deltaM = QgsExpressionUtils::getDoubleValue( values.at( 7 ), parent );
 
 5040  const double scaleZ = QgsExpressionUtils::getDoubleValue( values.at( 8 ), parent );
 
 5041  const double scaleM = QgsExpressionUtils::getDoubleValue( values.at( 9 ), parent );
 
 5052  QTransform transform;
 
 5053  transform.translate( deltaX, deltaY );
 
 5054  transform.rotate( rotationZ );
 
 5055  transform.scale( scaleX, scaleY );
 
 5056  fGeom.
transform( transform, deltaZ, scaleZ, deltaM, scaleM );
 
 5058  return QVariant::fromValue( fGeom );
 
 5064  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5066  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5071  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5073  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5079  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5080  double tolerance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5082  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5088  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5090  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5094#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 ) 
 5099    QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5100    const double targetPercent = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5101    const bool allowHoles = values.value( 2 ).toBool();
 
 5103    QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5116  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5118  if ( values.length() == 2 )
 
 5119    segments = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5127  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5133  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5135  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5141  const QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5147  double area, 
angle, width, height;
 
 5160  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5161  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5163  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5169  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5176    const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.
constGet() );
 
 5181    result = reversed ? QVariant::fromValue( 
QgsGeometry( reversed ) ) : QVariant();
 
 5189      if ( 
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->
geometryN( i ) ) )
 
 5191        reversed->addGeometry( curve->
reversed() );
 
 5198    result = reversed ? QVariant::fromValue( 
QgsGeometry( std::move( reversed ) ) ) : QVariant();
 
 5205  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5216        curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->
geometryN( 0 ) );
 
 5225  QVariant result = exterior ? QVariant::fromValue( 
QgsGeometry( exterior ) ) : QVariant();
 
 5231  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5232  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5233  return QVariant( fGeom.
distance( sGeom ) );
 
 5238  QgsGeometry g1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5239  QgsGeometry g2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5242  if ( values.length() == 3 && values.at( 2 ).isValid() )
 
 5244    double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5245    densify = std::clamp( densify, 0.0, 1.0 );
 
 5253  return res > -1 ? QVariant( res ) : QVariant();
 
 5258  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5259  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5261  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5266  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5267  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5269  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5274  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5275  QgsGeometry sGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5277  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5283  if ( values.length() < 1 || values.length() > 2 )
 
 5286  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5288  if ( values.length() == 2 )
 
 5289    prec = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5290  QString wkt = fGeom.
asWkt( prec );
 
 5291  return QVariant( wkt );
 
 5296  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5297  return fGeom.
isNull() ? QVariant() : QVariant( fGeom.asWkb() );
 
 5302  if ( values.length() != 2 )
 
 5304    parent->
setEvalErrorString( QObject::tr( 
"Function `azimuth` requires exactly two parameters. %n given.", 
nullptr, values.length() ) );
 
 5308  QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5309  QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5311  const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
 
 5318        pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 5323  const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
 
 5330        pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 5337    parent->
setEvalErrorString( QObject::tr( 
"Function `azimuth` requires two points as arguments." ) );
 
 5344    if ( pt1->
y() < pt2->
y() )
 
 5346    else if ( pt1->
y() > pt2->
y() )
 
 5354    if ( pt1->
x() < pt2->
x() )
 
 5356    else if ( pt1->
x() > pt2->
x() )
 
 5357      return M_PI + ( M_PI_2 );
 
 5362  if ( pt1->
x() < pt2->
x() )
 
 5364    if ( pt1->
y() < pt2->
y() )
 
 5366      return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) );
 
 5370      return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
 
 5377    if ( pt1->
y() > pt2->
y() )
 
 5379      return std::atan( std::fabs( pt1->
x() - pt2->
x() ) / std::fabs( pt1->
y() - pt2->
y() ) )
 
 5384      return std::atan( std::fabs( pt1->
y() - pt2->
y() ) / std::fabs( pt1->
x() - pt2->
x() ) )
 
 5385             + ( M_PI + ( M_PI_2 ) );
 
 5392  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5396    parent->
setEvalErrorString( QStringLiteral( 
"'project' requires a point geometry" ) );
 
 5400  double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5401  double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5402  double inclination = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
 
 5405  QgsPoint newPoint = p->
project( distance,  180.0 * azimuth / M_PI, 180.0 * inclination / M_PI );
 
 5412  QgsGeometry fGeom1 = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5413  QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5415  const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1.
constGet() );
 
 5422        pt1 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 5426  const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2.
constGet() );
 
 5433        pt2 = qgsgeometry_cast< const QgsPoint * >( collection->
geometryN( 0 ) );
 
 5438  if ( ( fGeom1.
type() != Qgis::GeometryType::Point ) || ( fGeom2.
type() != Qgis::GeometryType::Point ) ||
 
 5441    parent->
setEvalErrorString( QStringLiteral( 
"Function 'inclination' requires two points as arguments." ) );
 
 5451  if ( values.length() != 3 )
 
 5454  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5455  double x = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5456  double y = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5460  QVariant result = geom.
constGet() ? QVariant::fromValue( geom ) : QVariant();
 
 5466  if ( values.length() < 2 )
 
 5469  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5472    return values.at( 0 );
 
 5474  QString expString = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 5475  QVariant cachedExpression;
 
 5480  if ( cachedExpression.isValid() )
 
 5487  bool asc = values.value( 2 ).toBool();
 
 5505  Q_ASSERT( collection ); 
 
 5509  QgsExpressionSorter sorter( orderBy );
 
 5511  QList<QgsFeature> partFeatures;
 
 5512  partFeatures.reserve( collection->
partCount() );
 
 5513  for ( 
int i = 0; i < collection->
partCount(); ++i )
 
 5519  sorter.sortFeatures( partFeatures, unconstedContext );
 
 5523  Q_ASSERT( orderedGeom );
 
 5528  for ( 
const QgsFeature &feature : std::as_const( partFeatures ) )
 
 5533  QVariant result = QVariant::fromValue( 
QgsGeometry( orderedGeom ) );
 
 5536    delete unconstedContext;
 
 5543  QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5544  QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5548  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5554  QgsGeometry fromGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5555  QgsGeometry toGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5559  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5565  QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5566  double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5570  QVariant result = !geom.
isNull() ? QVariant::fromValue( geom ) : QVariant();
 
 5576  QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5577  if ( lineGeom.
type() != Qgis::GeometryType::Line )
 
 5579    parent->
setEvalErrorString( QObject::tr( 
"line_substring requires a curve geometry input" ) );
 
 5585    curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.
constGet() );
 
 5592        curve = qgsgeometry_cast< const QgsCurve * >( collection->
geometryN( 0 ) );
 
 5599  double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5600  double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5602  std::unique_ptr< QgsCurve > substring( curve->
curveSubstring( startDistance, endDistance ) );
 
 5604  return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
 
 5609  QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5610  double distance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5617  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5618  int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5623    vertex = count + vertex;
 
 5631  QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5632  int vertex = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5637    vertex = count + vertex;
 
 5645  QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 5646  QgsGeometry pointGeom = QgsExpressionUtils::getGeometry( values.at( 1 ), parent );
 
 5650  return distance >= 0 ? distance : QVariant();
 
 5655  if ( values.length() == 2 && values.at( 1 ).toInt() != 0 )
 
 5657    double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 5658    return qgsRound( number, QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
 
 5661  if ( values.length() >= 1 )
 
 5663    double number = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 5664    return QVariant( qlonglong( std::round( number ) ) );
 
 5679  const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
 
 5680  const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5681  const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 5688  const bool omitGroupSeparator = values.value( 3 ).toBool();
 
 5689  const bool trimTrailingZeros = values.value( 4 ).toBool();
 
 5691  QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
 
 5692  if ( !omitGroupSeparator )
 
 5693    locale.setNumberOptions( locale.numberOptions() & ~QLocale::NumberOption::OmitGroupSeparator );
 
 5695    locale.setNumberOptions( locale.numberOptions() | QLocale::NumberOption::OmitGroupSeparator );
 
 5697  QString res = locale.toString( value, 
'f', places );
 
 5699  if ( trimTrailingZeros )
 
 5701#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
 5702    const QChar decimal = locale.decimalPoint();
 
 5703    const QChar zeroDigit = locale.zeroDigit();
 
 5705    const QChar decimal = locale.decimalPoint().at( 0 );
 
 5706    const QChar zeroDigit = locale.zeroDigit().at( 0 );
 
 5709    if ( res.contains( decimal ) )
 
 5711      int trimPoint = res.length() - 1;
 
 5713      while ( res.at( trimPoint ) == zeroDigit )
 
 5716      if ( res.at( trimPoint ) == decimal )
 
 5719      res.truncate( trimPoint + 1 );
 
 5728  const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
 
 5729  const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 5730  const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 5732  QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
 
 5733  return locale.toString( datetime, format );
 
 5739  int avg = ( color.red() + color.green() + color.blue() ) / 3;
 
 5740  int alpha = color.alpha();
 
 5742  color.setRgb( avg, avg, avg, alpha );
 
 5751  double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
 
 5756  else if ( ratio < 0 )
 
 5761  int red = 
static_cast<int>( color1.red() * ( 1 - ratio ) + color2.red() * ratio );
 
 5762  int green = 
static_cast<int>( color1.green() * ( 1 - ratio ) + color2.green() * ratio );
 
 5763  int blue = 
static_cast<int>( color1.blue() * ( 1 - ratio ) + color2.blue() * ratio );
 
 5764  int alpha = 
static_cast<int>( color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio );
 
 5766  QColor newColor( red, green, blue, alpha );
 
 5773  int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
 
 5774  int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5775  int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 5776  QColor color = QColor( red, green, blue );
 
 5777  if ( ! color.isValid() )
 
 5779    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
 
 5780    color = QColor( 0, 0, 0 );
 
 5783  return QStringLiteral( 
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
 
 5788  QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
 
 5789  QVariant value = node->
eval( parent, context );
 
 5793    node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
 5795    value = node->
eval( parent, context );
 
 5803  QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
 
 5805  QVariant value = node->
eval( parent, context );
 
 5807  if ( value.toBool() )
 
 5809    node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
 5811    value = node->
eval( parent, context );
 
 5816    node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
 
 5818    value = node->
eval( parent, context );
 
 5826  int red = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
 
 5827  int green = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 5828  int blue = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 5829  int alpha = QgsExpressionUtils::getNativeIntValue( values.at( 3 ), parent );
 
 5830  QColor color = QColor( red, green, blue, alpha );
 
 5831  if ( ! color.isValid() )
 
 5833    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
 
 5834    color = QColor( 0, 0, 0 );
 
 5843  if ( values.at( 0 ).userType() == QMetaType::type( 
"QgsGradientColorRamp" ) )
 
 5845    expRamp = QgsExpressionUtils::getRamp( values.at( 0 ), parent );
 
 5850    QString rampName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 5854      parent->
setEvalErrorString( QObject::tr( 
"\"%1\" is not a valid color ramp" ).arg( rampName ) );
 
 5859  double value = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
 
 5860  QColor color = ramp->
color( value );
 
 5867  double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
 
 5869  double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5871  double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5873  QColor color = QColor::fromHslF( hue, saturation, lightness );
 
 5875  if ( ! color.isValid() )
 
 5877    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
 
 5878    color = QColor( 0, 0, 0 );
 
 5881  return QStringLiteral( 
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
 
 5887  double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
 
 5889  double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5891  double lightness = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5893  double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
 
 5895  QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
 
 5896  if ( ! color.isValid() )
 
 5898    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
 
 5899    color = QColor( 0, 0, 0 );
 
 5907  double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
 
 5909  double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5911  double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5913  QColor color = QColor::fromHsvF( hue, saturation, value );
 
 5915  if ( ! color.isValid() )
 
 5917    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
 
 5918    color = QColor( 0, 0, 0 );
 
 5921  return QStringLiteral( 
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
 
 5927  double hue = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 360.0;
 
 5929  double saturation = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5931  double value = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5933  double alpha = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 255.0;
 
 5935  QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
 
 5936  if ( ! color.isValid() )
 
 5938    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
 
 5939    color = QColor( 0, 0, 0 );
 
 5947  double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
 
 5949  double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5951  double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5953  double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
 
 5955  QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
 
 5957  if ( ! color.isValid() )
 
 5959    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
 
 5960    color = QColor( 0, 0, 0 );
 
 5963  return QStringLiteral( 
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
 
 5969  double cyan = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ) / 100.0;
 
 5971  double magenta = QgsExpressionUtils::getIntValue( values.at( 1 ), parent ) / 100.0;
 
 5973  double yellow = QgsExpressionUtils::getIntValue( values.at( 2 ), parent ) / 100.0;
 
 5975  double black = QgsExpressionUtils::getIntValue( values.at( 3 ), parent ) / 100.0;
 
 5977  double alpha = QgsExpressionUtils::getIntValue( values.at( 4 ), parent ) / 255.0;
 
 5979  QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
 
 5980  if ( ! color.isValid() )
 
 5982    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
 
 5983    color = QColor( 0, 0, 0 );
 
 5991  if ( ! color.isValid() )
 
 5993    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
 
 5997  QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 5998  if ( part.compare( QLatin1String( 
"red" ), Qt::CaseInsensitive ) == 0 )
 
 6000  else if ( part.compare( QLatin1String( 
"green" ), Qt::CaseInsensitive ) == 0 )
 
 6001    return color.green();
 
 6002  else if ( part.compare( QLatin1String( 
"blue" ), Qt::CaseInsensitive ) == 0 )
 
 6003    return color.blue();
 
 6004  else if ( part.compare( QLatin1String( 
"alpha" ), Qt::CaseInsensitive ) == 0 )
 
 6005    return color.alpha();
 
 6006  else if ( part.compare( QLatin1String( 
"hue" ), Qt::CaseInsensitive ) == 0 )
 
 6007    return static_cast< double >( color.hsvHueF() * 360 );
 
 6008  else if ( part.compare( QLatin1String( 
"saturation" ), Qt::CaseInsensitive ) == 0 )
 
 6009    return static_cast< double >( color.hsvSaturationF() * 100 );
 
 6010  else if ( part.compare( QLatin1String( 
"value" ), Qt::CaseInsensitive ) == 0 )
 
 6011    return static_cast< double >( color.valueF() * 100 );
 
 6012  else if ( part.compare( QLatin1String( 
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
 
 6013    return static_cast< double >( color.hslHueF() * 360 );
 
 6014  else if ( part.compare( QLatin1String( 
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
 
 6015    return static_cast< double >( color.hslSaturationF() * 100 );
 
 6016  else if ( part.compare( QLatin1String( 
"lightness" ), Qt::CaseInsensitive ) == 0 )
 
 6017    return static_cast< double >( color.lightnessF() * 100 );
 
 6018  else if ( part.compare( QLatin1String( 
"cyan" ), Qt::CaseInsensitive ) == 0 )
 
 6019    return static_cast< double >( color.cyanF() * 100 );
 
 6020  else if ( part.compare( QLatin1String( 
"magenta" ), Qt::CaseInsensitive ) == 0 )
 
 6021    return static_cast< double >( color.magentaF() * 100 );
 
 6022  else if ( part.compare( QLatin1String( 
"yellow" ), Qt::CaseInsensitive ) == 0 )
 
 6023    return static_cast< double >( color.yellowF() * 100 );
 
 6024  else if ( part.compare( QLatin1String( 
"black" ), Qt::CaseInsensitive ) == 0 )
 
 6025    return static_cast< double >( color.blackF() * 100 );
 
 6027  parent->
setEvalErrorString( QObject::tr( 
"Unknown color component '%1'" ).arg( part ) );
 
 6033  const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 6036    parent->
setEvalErrorString( QObject::tr( 
"A minimum of two colors is required to create a ramp" ) );
 
 6040  QList< QColor > colors;
 
 6042  for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
 
 6045    if ( !colors.last().isValid() )
 
 6047      parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to color" ).arg( it.value().toString() ) );
 
 6051    double step = it.key().toDouble();
 
 6052    if ( it == map.constBegin() )
 
 6057    else if ( it == map.constEnd() )
 
 6067  bool discrete = values.at( 1 ).toBool();
 
 6069  if ( colors.empty() )
 
 6072  return QVariant::fromValue( 
QgsGradientColorRamp( colors.first(), colors.last(), discrete, stops ) );
 
 6078  if ( ! color.isValid() )
 
 6080    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
 
 6084  QString part = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 6085  int value = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 6086  if ( part.compare( QLatin1String( 
"red" ), Qt::CaseInsensitive ) == 0 )
 
 6087    color.setRed( value );
 
 6088  else if ( part.compare( QLatin1String( 
"green" ), Qt::CaseInsensitive ) == 0 )
 
 6089    color.setGreen( value );
 
 6090  else if ( part.compare( QLatin1String( 
"blue" ), Qt::CaseInsensitive ) == 0 )
 
 6091    color.setBlue( value );
 
 6092  else if ( part.compare( QLatin1String( 
"alpha" ), Qt::CaseInsensitive ) == 0 )
 
 6093    color.setAlpha( value );
 
 6094  else if ( part.compare( QLatin1String( 
"hue" ), Qt::CaseInsensitive ) == 0 )
 
 6095    color.setHsv( value, color.hsvSaturation(), color.value(), color.alpha() );
 
 6096  else if ( part.compare( QLatin1String( 
"saturation" ), Qt::CaseInsensitive ) == 0 )
 
 6097    color.setHsvF( color.hsvHueF(), value / 100.0, color.valueF(), color.alphaF() );
 
 6098  else if ( part.compare( QLatin1String( 
"value" ), Qt::CaseInsensitive ) == 0 )
 
 6099    color.setHsvF( color.hsvHueF(), color.hsvSaturationF(), value / 100.0, color.alphaF() );
 
 6100  else if ( part.compare( QLatin1String( 
"hsl_hue" ), Qt::CaseInsensitive ) == 0 )
 
 6101    color.setHsl( value, color.hslSaturation(), color.lightness(), color.alpha() );
 
 6102  else if ( part.compare( QLatin1String( 
"hsl_saturation" ), Qt::CaseInsensitive ) == 0 )
 
 6103    color.setHslF( color.hslHueF(), value / 100.0, color.lightnessF(), color.alphaF() );
 
 6104  else if ( part.compare( QLatin1String( 
"lightness" ), Qt::CaseInsensitive ) == 0 )
 
 6105    color.setHslF( color.hslHueF(), color.hslSaturationF(), value / 100.0, color.alphaF() );
 
 6106  else if ( part.compare( QLatin1String( 
"cyan" ), Qt::CaseInsensitive ) == 0 )
 
 6107    color.setCmykF( value / 100.0, color.magentaF(), color.yellowF(), color.blackF(), color.alphaF() );
 
 6108  else if ( part.compare( QLatin1String( 
"magenta" ), Qt::CaseInsensitive ) == 0 )
 
 6109    color.setCmykF( color.cyanF(), value / 100.0, color.yellowF(), color.blackF(), color.alphaF() );
 
 6110  else if ( part.compare( QLatin1String( 
"yellow" ), Qt::CaseInsensitive ) == 0 )
 
 6111    color.setCmykF( color.cyanF(), color.magentaF(), value / 100.0, color.blackF(), color.alphaF() );
 
 6112  else if ( part.compare( QLatin1String( 
"black" ), Qt::CaseInsensitive ) == 0 )
 
 6113    color.setCmykF( color.cyanF(), color.magentaF(), color.yellowF(), value / 100.0, color.alphaF() );
 
 6116    parent->
setEvalErrorString( QObject::tr( 
"Unknown color component '%1'" ).arg( part ) );
 
 6125  if ( ! color.isValid() )
 
 6127    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
 
 6131  color = color.darker( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
 
 6139  if ( ! color.isValid() )
 
 6141    parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to color" ).arg( values.at( 0 ).toString() ) );
 
 6145  color = color.lighter( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ) );
 
 6152  QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 6155    return QVariant::fromValue( geom );
 
 6161  const QgsFeature feat = QgsExpressionUtils::getFeature( values.at( 0 ), parent );
 
 6169  QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
 
 6170  QString sAuthId = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 6171  QString dAuthId = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 6175    return QVariant::fromValue( fGeom );
 
 6178    return QVariant::fromValue( fGeom );
 
 6187      return QVariant::fromValue( fGeom );
 
 6200  bool foundLayer = 
false;
 
 6201  std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
 
 6204  if ( !featureSource || !foundLayer )
 
 6209  const QgsFeatureId fid = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
 
 6222    result = QVariant::fromValue( fet );
 
 6230  bool foundLayer = 
false;
 
 6231  std::unique_ptr<QgsVectorLayerFeatureSource> featureSource = QgsExpressionUtils::getFeatureSource( values.at( 0 ), context, parent, foundLayer );
 
 6234  if ( !featureSource || !foundLayer )
 
 6239  QString cacheValueKey;
 
 6240  if ( values.at( 1 ).type() == QVariant::Map )
 
 6242    QVariantMap attributeMap = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
 
 6244    QMap <QString, QVariant>::const_iterator i = attributeMap.constBegin();
 
 6245    QString filterString;
 
 6246    for ( ; i != attributeMap.constEnd(); ++i )
 
 6248      if ( !filterString.isEmpty() )
 
 6250        filterString.append( 
" AND " );
 
 6254    cacheValueKey = QStringLiteral( 
"getfeature:%1:%2" ).arg( featureSource->id(), filterString );
 
 6263    QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 6264    int attributeId = featureSource->fields().lookupField( attribute );
 
 6265    if ( attributeId == -1 )
 
 6270    const QVariant &attVal = values.at( 2 );
 
 6272    cacheValueKey = QStringLiteral( 
"getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
 
 6295    res = QVariant::fromValue( fet );
 
 6310    if ( !values.isEmpty() )
 
 6313      if ( col && ( values.size() == 1 || !values.at( 1 ).isValid() ) )
 
 6314        fieldName = col->
name();
 
 6315      else if ( values.size() == 2 )
 
 6316        fieldName = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 6319    QVariant value = values.at( 0 );
 
 6324    if ( fieldIndex == -1 )
 
 6326      parent->
setEvalErrorString( QCoreApplication::translate( 
"expression", 
"%1: Field not found %2" ).arg( QStringLiteral( 
"represent_value" ), fieldName ) );
 
 6332      QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer( context->
variable( QStringLiteral( 
"layer" ) ), context, parent );
 
 6335      const QString cacheValueKey = QStringLiteral( 
"repvalfcnval:%1:%2:%3" ).arg( layer ? layer->id() : QStringLiteral( 
"[None]" ), fieldName, value.toString() );
 
 6344      const QString cacheKey = QStringLiteral( 
"repvalfcn:%1:%2" ).arg( layer ? layer->id() : QStringLiteral( 
"[None]" ), fieldName );
 
 6355      result = 
formatter->representValue( layer, fieldIndex, setup.
config(), cache, value );
 
 6362    parent->
setEvalErrorString( QCoreApplication::translate( 
"expression", 
"%1: function cannot be evaluated without a context." ).arg( QStringLiteral( 
"represent_value" ), fieldName ) );
 
 6370  const QVariant data = values.at( 0 );
 
 6371  const QMimeDatabase db;
 
 6372  return db.mimeTypeForData( data.toByteArray() ).name();
 
 6377  const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 6379  bool foundLayer = 
false;
 
 6380  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [layerProperty]( 
QgsMapLayer * layer )-> QVariant
 
 6386    if ( QString::compare( layerProperty, QStringLiteral( 
"name" ), Qt::CaseInsensitive ) == 0 )
 
 6387      return layer->name();
 
 6388    else if ( QString::compare( layerProperty, QStringLiteral( 
"id" ), Qt::CaseInsensitive ) == 0 )
 
 6390    else if ( QString::compare( layerProperty, QStringLiteral( 
"title" ), Qt::CaseInsensitive ) == 0 )
 
 6391      return !layer->metadata().title().isEmpty() ? layer->metadata().title() : layer->title();
 
 6392    else if ( QString::compare( layerProperty, QStringLiteral( 
"abstract" ), Qt::CaseInsensitive ) == 0 )
 
 6393      return !layer->metadata().abstract().isEmpty() ? layer->metadata().abstract() : layer->abstract();
 
 6394    else if ( QString::compare( layerProperty, QStringLiteral( 
"keywords" ), Qt::CaseInsensitive ) == 0 )
 
 6396      QStringList keywords;
 
 6397      const QgsAbstractMetadataBase::KeywordMap keywordMap = layer->metadata().keywords();
 
 6398      for ( auto it = keywordMap.constBegin(); it != keywordMap.constEnd(); ++it )
 
 6400        keywords.append( it.value() );
 
 6402      if ( !keywords.isEmpty() )
 
 6404      return layer->keywordList();
 
 6406    else if ( QString::compare( layerProperty, QStringLiteral( 
"data_url" ), Qt::CaseInsensitive ) == 0 )
 
 6408    else if ( QString::compare( layerProperty, QStringLiteral( 
"attribution" ), Qt::CaseInsensitive ) == 0 )
 
 6412    else if ( QString::compare( layerProperty, QStringLiteral( 
"attribution_url" ), Qt::CaseInsensitive ) == 0 )
 
 6414    else if ( QString::compare( layerProperty, QStringLiteral( 
"source" ), Qt::CaseInsensitive ) == 0 )
 
 6416    else if ( QString::compare( layerProperty, QStringLiteral( 
"min_scale" ), Qt::CaseInsensitive ) == 0 )
 
 6418    else if ( QString::compare( layerProperty, QStringLiteral( 
"max_scale" ), Qt::CaseInsensitive ) == 0 )
 
 6420    else if ( QString::compare( layerProperty, QStringLiteral( 
"is_editable" ), Qt::CaseInsensitive ) == 0 )
 
 6422    else if ( QString::compare( layerProperty, QStringLiteral( 
"crs" ), Qt::CaseInsensitive ) == 0 )
 
 6424    else if ( QString::compare( layerProperty, QStringLiteral( 
"crs_definition" ), Qt::CaseInsensitive ) == 0 )
 
 6426    else if ( QString::compare( layerProperty, QStringLiteral( 
"crs_description" ), Qt::CaseInsensitive ) == 0 )
 
 6428    else if ( QString::compare( layerProperty, QStringLiteral( 
"extent" ), Qt::CaseInsensitive ) == 0 )
 
 6431      QVariant result = QVariant::fromValue( extentGeom );
 
 6434    else if ( QString::compare( layerProperty, QStringLiteral( 
"distance_units" ), Qt::CaseInsensitive ) == 0 )
 
 6436    else if ( QString::compare( layerProperty, QStringLiteral( 
"path" ), Qt::CaseInsensitive ) == 0 )
 
 6439      return decodedUri.value( QStringLiteral( 
"path" ) );
 
 6441    else if ( QString::compare( layerProperty, QStringLiteral( 
"type" ), Qt::CaseInsensitive ) == 0 )
 
 6443      switch ( layer->
type() )
 
 6445        case Qgis::LayerType::Vector:
 
 6446          return QCoreApplication::translate( 
"expressions", 
"Vector" );
 
 6447        case Qgis::LayerType::Raster:
 
 6448          return QCoreApplication::translate( 
"expressions", 
"Raster" );
 
 6449        case Qgis::LayerType::Mesh:
 
 6450          return QCoreApplication::translate( 
"expressions", 
"Mesh" );
 
 6451        case Qgis::LayerType::VectorTile:
 
 6452          return QCoreApplication::translate( 
"expressions", 
"Vector Tile" );
 
 6453        case Qgis::LayerType::Plugin:
 
 6454          return QCoreApplication::translate( 
"expressions", 
"Plugin" );
 
 6455        case Qgis::LayerType::Annotation:
 
 6456          return QCoreApplication::translate( 
"expressions", 
"Annotation" );
 
 6457        case Qgis::LayerType::PointCloud:
 
 6458          return QCoreApplication::translate( 
"expressions", 
"Point Cloud" );
 
 6459        case Qgis::LayerType::Group:
 
 6460          return QCoreApplication::translate( 
"expressions", 
"Group" );
 
 6466      QgsVectorLayer *vLayer = qobject_cast< QgsVectorLayer * >( layer );
 
 6469        if ( QString::compare( layerProperty, QStringLiteral( 
"storage_type" ), Qt::CaseInsensitive ) == 0 )
 
 6471        else if ( QString::compare( layerProperty, QStringLiteral( 
"geometry_type" ), Qt::CaseInsensitive ) == 0 )
 
 6473        else if ( QString::compare( layerProperty, QStringLiteral( 
"feature_count" ), Qt::CaseInsensitive ) == 0 )
 
 6489  const QString uriPart = values.at( 1 ).toString();
 
 6491  bool foundLayer = 
false;
 
 6493  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, uriPart]( 
QgsMapLayer * layer )-> QVariant
 
 6495    if ( !layer->dataProvider() )
 
 6497      parent->setEvalErrorString( QObject::tr( 
"Layer %1 has invalid data provider" ).arg( layer->name() ) );
 
 6503    if ( !uriPart.isNull() )
 
 6505      return decodedUri.value( uriPart );
 
 6515    parent->
setEvalErrorString( QObject::tr( 
"Function `decode_uri` requires a valid layer." ) );
 
 6526  const int band = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 6527  const QString layerProperty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 6529  bool foundLayer = 
false;
 
 6530  const QVariant res = QgsExpressionUtils::runMapLayerFunctionThreadSafe( values.at( 0 ), context, parent, [parent, band, layerProperty]( 
QgsMapLayer * layer )-> QVariant
 
 6532    QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer );
 
 6536    if ( band < 1 || band > rl->bandCount() )
 
 6538      parent->setEvalErrorString( QObject::tr( 
"Invalid band number %1 for layer" ).arg( band ) );
 
 6544    if ( QString::compare( layerProperty, QStringLiteral( 
"avg" ), Qt::CaseInsensitive ) == 0 )
 
 6546    else if ( QString::compare( layerProperty, QStringLiteral( 
"stdev" ), Qt::CaseInsensitive ) == 0 )
 
 6548    else if ( QString::compare( layerProperty, QStringLiteral( 
"min" ), Qt::CaseInsensitive ) == 0 )
 
 6550    else if ( QString::compare( layerProperty, QStringLiteral( 
"max" ), Qt::CaseInsensitive ) == 0 )
 
 6552    else if ( QString::compare( layerProperty, QStringLiteral( 
"range" ), Qt::CaseInsensitive ) == 0 )
 
 6554    else if ( QString::compare( layerProperty, QStringLiteral( 
"sum" ), Qt::CaseInsensitive ) == 0 )
 
 6558      parent->
setEvalErrorString( QObject::tr( 
"Invalid raster statistic: '%1'" ).arg( layerProperty ) );
 
 6584    parent->
setEvalErrorString( QObject::tr( 
"Function `raster_statistic` requires a valid raster layer." ) );
 
 6601  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6602  bool ascending = values.value( 1 ).toBool();
 
 6603  std::sort( list.begin(), list.end(), [ascending]( QVariant a, QVariant b ) -> 
bool { return ( !ascending ? qgsVariantLessThan( b, a ) : qgsVariantLessThan( a, b ) ); } );
 
 6609  return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).length();
 
 6614  return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
 
 6619  return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).count( values.at( 1 ) ) );
 
 6624  QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6625  QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
 
 6627  for ( 
const auto &item : listB )
 
 6629    if ( listA.contains( item ) )
 
 6633  return QVariant( match == listB.count() );
 
 6638  return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
 
 6643  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6644  const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 6645  if ( pos < list.length() && pos >= 0 ) 
return list.at( pos );
 
 6646  else if ( pos < 0 && ( list.length() + pos ) >= 0 )
 
 6647    return list.at( list.length() + pos );
 
 6653  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6654  return list.value( 0 );
 
 6659  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6660  return list.value( list.size() - 1 );
 
 6665  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6666  return list.isEmpty() ? QVariant() : *std::min_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return ( 
qgsVariantLessThan( a, b ) ); } );
 
 6671  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6672  return list.isEmpty() ? QVariant() : *std::max_element( list.constBegin(), list.constEnd(), []( QVariant a, QVariant b ) -> bool { return ( 
qgsVariantLessThan( a, b ) ); } );
 
 6677  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6680  for ( 
const QVariant &item : list )
 
 6682    switch ( item.userType() )
 
 6684      case QMetaType::Int:
 
 6685      case QMetaType::UInt:
 
 6686      case QMetaType::LongLong:
 
 6687      case QMetaType::ULongLong:
 
 6688      case QMetaType::Float:
 
 6689      case QMetaType::Double:
 
 6690        total += item.toDouble();
 
 6695  return i == 0 ? QVariant() : total / i;
 
 6700  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6701  QVariantList numbers;
 
 6702  for ( 
const auto &item : list )
 
 6704    switch ( item.userType() )
 
 6706      case QMetaType::Int:
 
 6707      case QMetaType::UInt:
 
 6708      case QMetaType::LongLong:
 
 6709      case QMetaType::ULongLong:
 
 6710      case QMetaType::Float:
 
 6711      case QMetaType::Double:
 
 6712        numbers.append( item );
 
 6716  std::sort( numbers.begin(), numbers.end(), []( QVariant a, QVariant b ) -> 
bool { return ( qgsVariantLessThan( a, b ) ); } );
 
 6717  const int count = numbers.count();
 
 6722  else if ( count % 2 )
 
 6724    return numbers.at( count / 2 );
 
 6728    return ( numbers.at( count / 2 - 1 ).toDouble() + numbers.at( count / 2 ).toDouble() ) / 2;
 
 6734  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6737  for ( 
const QVariant &item : list )
 
 6739    switch ( item.userType() )
 
 6741      case QMetaType::Int:
 
 6742      case QMetaType::UInt:
 
 6743      case QMetaType::LongLong:
 
 6744      case QMetaType::ULongLong:
 
 6745      case QMetaType::Float:
 
 6746      case QMetaType::Double:
 
 6747        total += item.toDouble();
 
 6752  return i == 0 ? QVariant() : total;
 
 6755static QVariant convertToSameType( 
const QVariant &value, QVariant::Type type )
 
 6757  QVariant result = value;
 
 6758  result.convert( 
static_cast<int>( type ) );
 
 6764  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6765  QHash< QVariant, int > hash;
 
 6766  for ( 
const auto &item : list )
 
 6770  const QList< int > occurrences = hash.values();
 
 6771  if ( occurrences.empty() )
 
 6772    return QVariantList();
 
 6774  const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
 
 6776  const QString option = values.at( 1 ).toString();
 
 6777  if ( option.compare( QLatin1String( 
"all" ), Qt::CaseInsensitive ) == 0 )
 
 6779    return convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() );
 
 6781  else if ( option.compare( QLatin1String( 
"any" ), Qt::CaseInsensitive ) == 0 )
 
 6783    if ( hash.isEmpty() )
 
 6786    return QVariant( hash.key( maxValue ) );
 
 6788  else if ( option.compare( QLatin1String( 
"median" ), Qt::CaseInsensitive ) == 0 )
 
 6790    return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( maxValue ), values.at( 0 ).type() ), context, parent, node );
 
 6792  else if ( option.compare( QLatin1String( 
"real_majority" ), Qt::CaseInsensitive ) == 0 )
 
 6794    if ( maxValue * 2 <= list.size() )
 
 6797    return QVariant( hash.key( maxValue ) );
 
 6808  const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6809  QHash< QVariant, int > hash;
 
 6810  for ( 
const auto &item : list )
 
 6814  const QList< int > occurrences = hash.values();
 
 6815  if ( occurrences.empty() )
 
 6816    return QVariantList();
 
 6818  const int minValue = *std::min_element( occurrences.constBegin(), occurrences.constEnd() );
 
 6820  const QString option = values.at( 1 ).toString();
 
 6821  if ( option.compare( QLatin1String( 
"all" ), Qt::CaseInsensitive ) == 0 )
 
 6823    return convertToSameType( hash.keys( minValue ), values.at( 0 ).type() );
 
 6825  else if ( option.compare( QLatin1String( 
"any" ), Qt::CaseInsensitive ) == 0 )
 
 6827    if ( hash.isEmpty() )
 
 6830    return QVariant( hash.key( minValue ) );
 
 6832  else if ( option.compare( QLatin1String( 
"median" ), Qt::CaseInsensitive ) == 0 )
 
 6834    return fcnArrayMedian( QVariantList() << convertToSameType( hash.keys( minValue ), values.at( 0 ).type() ), context, parent, node );
 
 6836  else if ( option.compare( QLatin1String( 
"real_minority" ), Qt::CaseInsensitive ) == 0 )
 
 6838    if ( hash.isEmpty() )
 
 6842    const int maxValue = *std::max_element( occurrences.constBegin(), occurrences.constEnd() );
 
 6843    if ( maxValue * 2 > list.size() )
 
 6844      hash.remove( hash.key( maxValue ) );
 
 6846    return convertToSameType( hash.keys(), values.at( 0 ).type() );
 
 6857  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6858  list.append( values.at( 1 ) );
 
 6859  return convertToSameType( list, values.at( 0 ).type() );
 
 6864  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6865  list.prepend( values.at( 1 ) );
 
 6866  return convertToSameType( list, values.at( 0 ).type() );
 
 6871  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6872  list.insert( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), values.at( 2 ) );
 
 6873  return convertToSameType( list, values.at( 0 ).type() );
 
 6878  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6879  int position = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 6881    position = position + list.length();
 
 6882  if ( position >= 0 && position < list.length() )
 
 6883    list.removeAt( position );
 
 6884  return convertToSameType( list, values.at( 0 ).type() );
 
 6892  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6894  const QVariant toRemove = values.at( 1 );
 
 6897    list.erase( std::remove_if( list.begin(), list.end(), []( 
const QVariant & element )
 
 6899      return QgsVariantUtils::isNull( element );
 
 6904    list.removeAll( toRemove );
 
 6906  return convertToSameType( list, values.at( 0 ).type() );
 
 6911  if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
 
 6913    QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 1 ), parent );
 
 6915    QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6916    for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
 
 6918      int index = list.indexOf( it.key() );
 
 6919      while ( index >= 0 )
 
 6921        list.replace( index, it.value() );
 
 6922        index = list.indexOf( it.key() );
 
 6926    return convertToSameType( list, values.at( 0 ).type() );
 
 6928  else if ( values.count() == 3 )
 
 6930    QVariantList before;
 
 6932    bool isSingleReplacement = 
false;
 
 6934    if ( !QgsExpressionUtils::isList( values.at( 1 ) ) && values.at( 2 ).type() != QVariant::StringList )
 
 6936      before = QVariantList() << values.at( 1 );
 
 6940      before = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
 
 6943    if ( !QgsExpressionUtils::isList( values.at( 2 ) ) )
 
 6945      after = QVariantList() << values.at( 2 );
 
 6946      isSingleReplacement = 
true;
 
 6950      after = QgsExpressionUtils::getListValue( values.at( 2 ), parent );
 
 6953    if ( !isSingleReplacement && before.length() != after.length() )
 
 6955      parent->
setEvalErrorString( QObject::tr( 
"Invalid pair of array, length not identical" ) );
 
 6959    QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6960    for ( 
int i = 0; i < before.length(); i++ )
 
 6962      int index = list.indexOf( before.at( i ) );
 
 6963      while ( index >= 0 )
 
 6965        list.replace( index, after.at( isSingleReplacement ? 0 : i ) );
 
 6966        index = list.indexOf( before.at( i ) );
 
 6970    return convertToSameType( list, values.at( 0 ).type() );
 
 6974    parent->
setEvalErrorString( QObject::tr( 
"Function array_replace requires 2 or 3 arguments" ) );
 
 6981  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 6982  QVariantList list_new;
 
 6984  for ( 
const QVariant &cur : QgsExpressionUtils::getListValue( values.at( 1 ), parent ) )
 
 6986    while ( list.removeOne( cur ) )
 
 6988      list_new.append( cur );
 
 6992  list_new.append( list );
 
 6994  return convertToSameType( list_new, values.at( 0 ).type() );
 
 7000  for ( 
const QVariant &cur : values )
 
 7002    list += QgsExpressionUtils::getListValue( cur, parent );
 
 7004  return convertToSameType( list, values.at( 0 ).type() );
 
 7009  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 7010  int start_pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
 
 7011  const int end_pos = QgsExpressionUtils::getNativeIntValue( values.at( 2 ), parent );
 
 7012  int slice_length = 0;
 
 7014  if ( start_pos < 0 )
 
 7016    start_pos = list.length() + start_pos;
 
 7020    slice_length = end_pos - start_pos + 1;
 
 7024    slice_length = list.length() + end_pos - start_pos + 1;
 
 7027  if ( slice_length < 0 )
 
 7031  list = list.mid( start_pos, slice_length );
 
 7037  QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 7038  std::reverse( list.begin(), list.end() );
 
 7044  const QVariantList array1 = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 7045  const QVariantList array2 = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
 
 7046  for ( 
const QVariant &cur : array2 )
 
 7048    if ( array1.contains( cur ) )
 
 7049      return QVariant( 
true );
 
 7051  return QVariant( 
false );
 
 7056  QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 7058  QVariantList distinct;
 
 7060  for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
 
 7062    if ( !distinct.contains( *it ) )
 
 7064      distinct += ( *it );
 
 7073  QVariantList array = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
 
 7074  QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 7075  QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 7079  for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
 
 7081    str += ( !( *it ).toString().isEmpty() ) ? ( *it ).toString() : empty;
 
 7082    if ( it != ( array.constEnd() - 1 ) )
 
 7088  return QVariant( 
str );
 
 7093  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 7094  QString delimiter = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 7095  QString empty = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
 
 7097  QStringList list = 
str.split( delimiter );
 
 7100  for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
 
 7102    array += ( !( *it ).isEmpty() ) ? *it : empty;
 
 7110  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 7111  QJsonDocument document = QJsonDocument::fromJson( 
str.toUtf8() );
 
 7112  if ( document.isNull() )
 
 7115  return document.toVariant();
 
 7121  QJsonDocument document = QJsonDocument::fromVariant( values.at( 0 ) );
 
 7122  return QString( document.toJson( QJsonDocument::Compact ) );
 
 7127  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 7128  if ( 
str.isEmpty() )
 
 7129    return QVariantMap();
 
 7137  QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 7144  for ( 
int i = 0; i + 1 < values.length(); i += 2 )
 
 7146    result.insert( QgsExpressionUtils::getStringValue( values.at( i ), parent ), values.at( i + 1 ) );
 
 7153  const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 7154  const QString prefix = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
 
 7155  QVariantMap resultMap;
 
 7157  for ( 
auto it = map.cbegin(); it != map.cend(); it++ )
 
 7159    resultMap.insert( QString( it.key() ).prepend( prefix ), it.value() );
 
 7167  return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).value( values.at( 1 ).toString() );
 
 7172  return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).contains( values.at( 1 ).toString() );
 
 7177  QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 7178  map.remove( values.at( 1 ).toString() );
 
 7184  QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 7185  map.insert( values.at( 1 ).toString(),  values.at( 2 ) );
 
 7192  for ( 
const QVariant &cur : values )
 
 7194    const QVariantMap curMap = QgsExpressionUtils::getMapValue( cur, parent );
 
 7195    for ( QVariantMap::const_iterator it = curMap.constBegin(); it != curMap.constEnd(); ++it )
 
 7196      result.insert( it.key(), it.value() );
 
 7203  return QStringList( QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).keys() );
 
 7208  return QgsExpressionUtils::getMapValue( values.at( 0 ), parent ).values();
 
 7213  const QString envVarName = values.at( 0 ).toString();
 
 7214  if ( !QProcessEnvironment::systemEnvironment().contains( envVarName ) )
 
 7217  return QProcessEnvironment::systemEnvironment().value( envVarName );
 
 7222  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7225    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"base_file_name" ) ) );
 
 7228  return QFileInfo( file ).completeBaseName();
 
 7233  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7236    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"file_suffix" ) ) );
 
 7239  return QFileInfo( file ).completeSuffix();
 
 7244  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7247    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"file_exists" ) ) );
 
 7250  return QFileInfo::exists( file );
 
 7255  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7258    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"file_name" ) ) );
 
 7261  return QFileInfo( file ).fileName();
 
 7266  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7269    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"is_file" ) ) );
 
 7272  return QFileInfo( file ).isFile();
 
 7277  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7280    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"is_directory" ) ) );
 
 7283  return QFileInfo( file ).isDir();
 
 7288  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7291    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"file_path" ) ) );
 
 7294  return QDir::toNativeSeparators( QFileInfo( file ).path() );
 
 7299  const QString file = QgsExpressionUtils::getFilePathValue( values.at( 0 ), context, parent );
 
 7302    parent->
setEvalErrorString( QObject::tr( 
"Function `%1` requires a value which represents a possible file path" ).arg( QLatin1String( 
"file_size" ) ) );
 
 7305  return QFileInfo( file ).size();
 
 7308static QVariant fcnHash( 
const QString &
str, 
const QCryptographicHash::Algorithm 
algorithm )
 
 7310  return QString( QCryptographicHash::hash( 
str.toUtf8(), 
algorithm ).toHex() );
 
 7316  QString 
str = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 7317  QString method = QgsExpressionUtils::getStringValue( values.at( 1 ), parent ).toLower();
 
 7319  if ( method == QLatin1String( 
"md4" ) )
 
 7321    hash = fcnHash( 
str, QCryptographicHash::Md4 );
 
 7323  else if ( method == QLatin1String( 
"md5" ) )
 
 7325    hash = fcnHash( 
str, QCryptographicHash::Md5 );
 
 7327  else if ( method == QLatin1String( 
"sha1" ) )
 
 7329    hash = fcnHash( 
str, QCryptographicHash::Sha1 );
 
 7331  else if ( method == QLatin1String( 
"sha224" ) )
 
 7333    hash = fcnHash( 
str, QCryptographicHash::Sha224 );
 
 7335  else if ( method == QLatin1String( 
"sha256" ) )
 
 7337    hash = fcnHash( 
str, QCryptographicHash::Sha256 );
 
 7339  else if ( method == QLatin1String( 
"sha384" ) )
 
 7341    hash = fcnHash( 
str, QCryptographicHash::Sha384 );
 
 7343  else if ( method == QLatin1String( 
"sha512" ) )
 
 7345    hash = fcnHash( 
str, QCryptographicHash::Sha512 );
 
 7347  else if ( method == QLatin1String( 
"sha3_224" ) )
 
 7349    hash = fcnHash( 
str, QCryptographicHash::Sha3_224 );
 
 7351  else if ( method == QLatin1String( 
"sha3_256" ) )
 
 7353    hash = fcnHash( 
str, QCryptographicHash::Sha3_256 );
 
 7355  else if ( method == QLatin1String( 
"sha3_384" ) )
 
 7357    hash = fcnHash( 
str, QCryptographicHash::Sha3_384 );
 
 7359  else if ( method == QLatin1String( 
"sha3_512" ) )
 
 7361    hash = fcnHash( 
str, QCryptographicHash::Sha3_512 );
 
 7363  else if ( method == QLatin1String( 
"keccak_224" ) )
 
 7365    hash = fcnHash( 
str, QCryptographicHash::Keccak_224 );
 
 7367  else if ( method == QLatin1String( 
"keccak_256" ) )
 
 7369    hash = fcnHash( 
str, QCryptographicHash::Keccak_256 );
 
 7371  else if ( method == QLatin1String( 
"keccak_384" ) )
 
 7373    hash = fcnHash( 
str, QCryptographicHash::Keccak_384 );
 
 7375  else if ( method == QLatin1String( 
"keccak_512" ) )
 
 7377    hash = fcnHash( 
str, QCryptographicHash::Keccak_512 );
 
 7381    parent->
setEvalErrorString( QObject::tr( 
"Hash method %1 is not available on this system." ).arg( 
str ) );
 
 7388  return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 );
 
 7393  return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 );
 
 7398  const QByteArray input = values.at( 0 ).toByteArray();
 
 7399  return QVariant( QString( input.toBase64() ) );
 
 7404  const QVariantMap map = QgsExpressionUtils::getMapValue( values.at( 0 ), parent );
 
 7406  for ( 
auto it = map.cbegin(); it != map.cend(); it++ )
 
 7408    query.addQueryItem( it.key(), it.value().toString() );
 
 7410  return query.toString( QUrl::ComponentFormattingOption::FullyEncoded );
 
 7415  const QString value = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
 
 7416  const QByteArray base64 = value.toLocal8Bit();
 
 7417  const QByteArray decoded = QByteArray::fromBase64( base64 );
 
 7418  return QVariant( decoded );
 
 7423static 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 )
 
 7426  const QVariant sourceLayerRef = context->
variable( QStringLiteral( 
"layer" ) ); 
 
 7429  QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer( sourceLayerRef, context, parent );
 
 7438  QgsExpressionNode *node = QgsExpressionUtils::getNode( values.at( 0 ), parent );
 
 7441  const bool layerCanBeCached = node->
isStatic( parent, context );
 
 7442  QVariant targetLayerValue = node->
eval( parent, context );
 
 7446  node = QgsExpressionUtils::getNode( values.at( 1 ), parent );
 
 7448  QString subExpString = node->dump();
 
 7450  bool testOnly = ( subExpString == 
"NULL" );
 
 7453  QgsVectorLayer *targetLayer = QgsExpressionUtils::getVectorLayer( targetLayerValue, context, parent );
 
 7457    parent->
setEvalErrorString( QObject::tr( 
"Layer '%1' could not be loaded." ).arg( targetLayerValue.toString() ) );
 
 7462  node = QgsExpressionUtils::getNode( values.at( 2 ), parent );
 
 7464  QString filterString = node->dump();
 
 7465  if ( filterString != 
"NULL" )
 
 7467    request.setFilterExpression( filterString ); 
 
 7471  node = QgsExpressionUtils::getNode( values.at( 3 ), parent ); 
 
 7473  QVariant limitValue = node->eval( parent, context );
 
 7475  qlonglong limit = QgsExpressionUtils::getIntValue( limitValue, parent );
 
 7478  double max_distance = 0;
 
 7479  if ( isNearestFunc )   
 
 7481    node = QgsExpressionUtils::getNode( values.at( 4 ), parent );
 
 7483    QVariant distanceValue = node->eval( parent, context );
 
 7485    max_distance = QgsExpressionUtils::getDoubleValue( distanceValue, parent );
 
 7489  node = QgsExpressionUtils::getNode( values.at( isNearestFunc ? 5 : 4 ), parent );
 
 7491  QVariant cacheValue = node->eval( parent, context );
 
 7493  bool cacheEnabled = cacheValue.toBool();
 
 7499  double minOverlap { -1 };
 
 7500  double minInscribedCircleRadius { -1 };
 
 7501  bool returnDetails = 
false;  
 
 7502  bool sortByMeasure = 
false;
 
 7503  bool sortAscending = 
false;
 
 7504  bool requireMeasures = 
false;
 
 7505  bool overlapOrRadiusFilter = 
false;
 
 7506  if ( isIntersectsFunc )
 
 7509    node = QgsExpressionUtils::getNode( values.at( 5 ), parent ); 
 
 7511    const QVariant minOverlapValue = node->eval( parent, context );
 
 7513    minOverlap = QgsExpressionUtils::getDoubleValue( minOverlapValue, parent );
 
 7514    node = QgsExpressionUtils::getNode( values.at( 6 ), parent ); 
 
 7516    const QVariant minInscribedCircleRadiusValue = node->eval( parent, context );
 
 7518    minInscribedCircleRadius = QgsExpressionUtils::getDoubleValue( minInscribedCircleRadiusValue, parent );
 
 7519    node = QgsExpressionUtils::getNode( values.at( 7 ), parent );
 
 7521    returnDetails = !testOnly && node->eval( parent, context ).toBool();  
 
 7522    node = QgsExpressionUtils::getNode( values.at( 8 ), parent );
 
 7524    const QString sorting { node->eval( parent, context ).toString().toLower() };
 
 7525    sortByMeasure = !testOnly && ( sorting.startsWith( 
"asc" ) || sorting.startsWith( 
"des" ) );
 
 7526    sortAscending = sorting.startsWith( 
"asc" );
 
 7527    requireMeasures = sortByMeasure || returnDetails;  
 
 7528    overlapOrRadiusFilter = minInscribedCircleRadius != -1 || minOverlap != -1;
 
 7535  if ( sourceLayer && targetLayer->crs() != sourceLayer->crs() )
 
 7538    request.setDestinationCrs( sourceLayer->crs(), TransformContext ); 
 
 7541  bool sameLayers = ( sourceLayer && sourceLayer->id() == targetLayer->id() );
 
 7544  if ( bboxGrow != 0 )
 
 7546    intDomain.
grow( bboxGrow ); 
 
 7549  const QString cacheBase { QStringLiteral( 
"%1:%2:%3" ).arg( targetLayer->id(), subExpString, filterString ) };
 
 7555  QList<QgsFeature> features;
 
 7556  if ( isNearestFunc || ( layerCanBeCached && cacheEnabled ) )
 
 7560    const QString cacheLayer { QStringLiteral( 
"ovrlaylyr:%1" ).arg( cacheBase ) };
 
 7561    const QString cacheIndex { QStringLiteral( 
"ovrlayidx:%1" ).arg( cacheBase ) };
 
 7565      cachedTarget = targetLayer->
materialize( request );
 
 7566      if ( layerCanBeCached )
 
 7567        context->
setCachedValue( cacheLayer, QVariant::fromValue( cachedTarget ) );
 
 7577      if ( layerCanBeCached )
 
 7578        context->
setCachedValue( cacheIndex, QVariant::fromValue( spatialIndex ) );
 
 7585    QList<QgsFeatureId> fidsList;
 
 7586    if ( isNearestFunc )
 
 7588      fidsList = spatialIndex.
nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
 
 7592      fidsList = spatialIndex.
intersects( intDomain );
 
 7595    QListIterator<QgsFeatureId> i( fidsList );
 
 7596    while ( i.hasNext() )
 
 7599      if ( sameLayers && feat.
id() == fId2 )
 
 7601      features.append( cachedTarget->
getFeature( fId2 ) );
 
 7609    request.setFilterRect( intDomain );
 
 7614      if ( sameLayers && feat.
id() == feat2.
id() )
 
 7616      features.append( feat2 );
 
 7624    const QString expCacheKey { QStringLiteral( 
"exp:%1" ).arg( cacheBase ) };
 
 7625    const QString ctxCacheKey { QStringLiteral( 
"ctx:%1" ).arg( cacheBase ) };
 
 7631      subExpression.
prepare( &subContext );
 
 7644  auto testLinestring = [ = ]( 
const QgsGeometry intersection, 
double & overlapValue ) -> 
bool 
 7646    bool testResult { 
false };
 
 7648    QVector<double> overlapValues;
 
 7651      const QgsCurve *geom = qgsgeometry_cast< const QgsCurve * >( *it );
 
 7653      if ( minOverlap != -1  || requireMeasures )
 
 7655        overlapValue = geom->
length();
 
 7656        overlapValues.append( overlapValue );
 
 7657        if ( minOverlap != -1 )
 
 7659          if ( overlapValue >= minOverlap )
 
 7671    if ( ! overlapValues.isEmpty() )
 
 7673      overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
 
 7680  auto testPolygon = [ = ]( 
const QgsGeometry intersection, 
double & radiusValue, 
double & overlapValue ) -> 
bool 
 7683    bool testResult { 
false };
 
 7685    QVector<double> overlapValues;
 
 7686    QVector<double> radiusValues;
 
 7689      const QgsCurvePolygon *geom = qgsgeometry_cast< const QgsCurvePolygon * >( *it );
 
 7691      if ( minOverlap != -1 || requireMeasures )
 
 7693        overlapValue = geom->
area();
 
 7694        overlapValues.append( geom->
area() );
 
 7695        if ( minOverlap != - 1 )
 
 7697          if ( overlapValue >= minOverlap )
 
 7709      if ( minInscribedCircleRadius != -1 || requireMeasures )
 
 7712        const double width = bbox.
width();
 
 7713        const double height = bbox.
height();
 
 7714        const double size = width > height ? width : height;
 
 7715        const double tolerance = size / 100.0;
 
 7717        testResult = radiusValue >= minInscribedCircleRadius;
 
 7718        radiusValues.append( radiusValues );
 
 7723    if ( !radiusValues.isEmpty() )
 
 7725      radiusValue = *std::max_element( radiusValues.cbegin(), radiusValues.cend() );
 
 7728    if ( ! overlapValues.isEmpty() )
 
 7730      overlapValue = *std::max_element( overlapValues.cbegin(), overlapValues.cend() );
 
 7740  QVariantList results;
 
 7742  QListIterator<QgsFeature> i( features );
 
 7743  while ( i.hasNext() && ( sortByMeasure || limit == -1 || foundCount < limit ) )
 
 7749    if ( ! relationFunction || ( geometry.*relationFunction )( feat2.
geometry() ) ) 
 
 7752      double overlapValue = -1;
 
 7753      double radiusValue = -1;
 
 7755      if ( isIntersectsFunc && ( requireMeasures || overlapOrRadiusFilter ) )
 
 7762        switch ( intersection.
type() )
 
 7765          case Qgis::GeometryType::Polygon:
 
 7769            bool testResult { testPolygon( intersection, radiusValue, overlapValue ) };
 
 7771            if ( ! testResult && overlapOrRadiusFilter )
 
 7779          case Qgis::GeometryType::Line:
 
 7784            if ( minInscribedCircleRadius != -1 )
 
 7790            const bool testResult { testLinestring( intersection, overlapValue ) };
 
 7792            if ( ! testResult && overlapOrRadiusFilter )
 
 7800          case Qgis::GeometryType::Point:
 
 7805            if ( minInscribedCircleRadius != -1 )
 
 7810            bool testResult { 
false };
 
 7811            if ( minOverlap != -1 || requireMeasures )
 
 7819              if ( geometry.
type() == Qgis::GeometryType::Point )
 
 7823                  case Qgis::GeometryType::Unknown:
 
 7824                  case Qgis::GeometryType::Null:
 
 7825                  case Qgis::GeometryType::Point:
 
 7829                  case Qgis::GeometryType::Line:
 
 7831                    testResult = testLinestring( feat2.
geometry(), overlapValue );
 
 7834                  case Qgis::GeometryType::Polygon:
 
 7836                    testResult = testPolygon( feat2.
geometry(), radiusValue, overlapValue );
 
 7842              if ( ! testResult && overlapOrRadiusFilter )
 
 7851          case Qgis::GeometryType::Null:
 
 7852          case Qgis::GeometryType::Unknown:
 
 7870        const QVariant expResult = subExpression.
evaluate( &subContext );
 
 7872        if ( requireMeasures )
 
 7874          QVariantMap resultRecord;
 
 7875          resultRecord.insert( QStringLiteral( 
"id" ), feat2.
id() );
 
 7876          resultRecord.insert( QStringLiteral( 
"result" ), expResult );
 
 7878          resultRecord.insert( QStringLiteral( 
"overlap" ), overlapValue );
 
 7880          if ( radiusValue != -1 )
 
 7882            resultRecord.insert( QStringLiteral( 
"radius" ), radiusValue );
 
 7884          results.append( resultRecord );
 
 7888          results.append( expResult );
 
 7894        results.append( feat2.
id() );
 
 7908    if ( requireMeasures )
 
 7910      if ( sortByMeasure )
 
 7912        std::sort( results.begin(), results.end(), [ sortAscending ]( 
const QVariant & recordA, 
const QVariant & recordB ) -> 
bool 
 7914          return sortAscending ?
 
 7915          recordB.toMap().value( QStringLiteral( 
"overlap" ) ).toDouble() > recordA.toMap().value( QStringLiteral( 
"overlap" ) ).toDouble()
 
 7916          : recordA.toMap().value( QStringLiteral( 
"overlap" ) ).toDouble() > recordB.toMap().value( QStringLiteral( 
"overlap" ) ).toDouble();
 
 7920      if ( limit > 0 && results.size() > limit )
 
 7922        results.erase( results.begin() + limit );
 
 7925      if ( ! returnDetails )  
 
 7927        QVariantList expResults;
 
 7928        for ( 
auto it = results.constBegin(); it != results.constEnd(); ++it )
 
 7930          expResults.append( it->toMap().value( QStringLiteral( 
"result" ) ) );
 
 7940  QVariantList disjoint_results;
 
 7949    if ( !results.contains( feat2.
id() ) )
 
 7952      disjoint_results.append( subExpression.
evaluate( &subContext ) );
 
 7955  return disjoint_results;
 
 7998  return executeGeomOverlay( values, context, parent, 
nullptr, 
false, 0, 
true );
 
 8007  static QRecursiveMutex sFunctionsMutex;
 
 8008  QMutexLocker locker( &sFunctionsMutex );
 
 8010  QList<QgsExpressionFunction *> &functions = *sFunctions();
 
 8012  if ( functions.isEmpty() )
 
 8049    functions << randFunc;
 
 8053    functions << randfFunc;
 
 8056        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"max" ), -1, fcnMax, QStringLiteral( 
"Math" ), QString(), 
false, QSet<QString>(), 
false, QStringList(),  
true )
 
 8057        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"min" ), -1, fcnMin, QStringLiteral( 
"Math" ), QString(), 
false, QSet<QString>(), 
false, QStringList(),  
true )
 
 8064        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"pi" ), 0, fcnPi, QStringLiteral( 
"Math" ), QString(), 
false, QSet<QString>(), 
false, QStringList() << QStringLiteral( 
"$pi" ) )
 
 8068        << 
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" ) )
 
 8069        << 
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" ) )
 
 8070        << 
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" ) )
 
 8075        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"coalesce" ), -1, fcnCoalesce, QStringLiteral( 
"Conditionals" ), QString(), 
false, QSet<QString>(), 
false, QStringList(), 
true )
 
 8089                                            QStringLiteral( 
"Aggregates" ),
 
 8098      if ( !node->
args() )
 
 8101      QSet<QString> referencedVars;
 
 8104        QgsExpressionNode *subExpressionNode = node->args()->at( 2 );
 
 8105        referencedVars = subExpressionNode->referencedVariables();
 
 8110        QgsExpressionNode *filterNode = node->args()->at( 3 );
 
 8111        referencedVars.unite( filterNode->referencedVariables() );
 
 8113      return referencedVars.contains( QStringLiteral( 
"parent" ) ) || referencedVars.contains( QString() );
 
 8122      if ( !node->
args() )
 
 8123        return QSet<QString>();
 
 8125      QSet<QString> referencedCols;
 
 8126      QSet<QString> referencedVars;
 
 8141      if ( referencedVars.contains( QStringLiteral( 
"parent" ) ) || referencedVars.contains( QString() ) )
 
 8144        return referencedCols;
 
 8157        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"count" ), aggParams, fcnAggregateCount, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8158        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"count_distinct" ), aggParams, fcnAggregateCountDistinct, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8159        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"count_missing" ), aggParams, fcnAggregateCountMissing, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8160        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"minimum" ), aggParams, fcnAggregateMin, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8161        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"maximum" ), aggParams, fcnAggregateMax, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8162        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"sum" ), aggParams, fcnAggregateSum, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8163        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"mean" ), aggParams, fcnAggregateMean, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8164        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"median" ), aggParams, fcnAggregateMedian, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8165        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"stdev" ), aggParams, fcnAggregateStdev, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8166        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"range" ), aggParams, fcnAggregateRange, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8167        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"minority" ), aggParams, fcnAggregateMinority, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8168        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"majority" ), aggParams, fcnAggregateMajority, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8169        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"q1" ), aggParams, fcnAggregateQ1, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8170        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"q3" ), aggParams, fcnAggregateQ3, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8171        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"iqr" ), aggParams, fcnAggregateIQR, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8172        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"min_length" ), aggParams, fcnAggregateMinLength, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8173        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"max_length" ), aggParams, fcnAggregateMaxLength, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8174        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"collect" ), aggParams, fcnAggregateCollectGeometry, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8175        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"concatenate" ), aggParamsConcat, fcnAggregateStringConcat, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8176        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"concatenate_unique" ), aggParamsConcat, fcnAggregateStringConcatUnique, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8177        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"array_agg" ), aggParamsArray, fcnAggregateArray, QStringLiteral( 
"Aggregates" ), QString(), 
false, QSet<QString>(), true )
 
 8182        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"now" ), 0, fcnNow, QStringLiteral( 
"Date and Time" ), QString(), 
false, QSet<QString>(), 
false, QStringList() << QStringLiteral( 
"$now" ) )
 
 8185                                            fcnAge, QStringLiteral( 
"Date and Time" ) )
 
 8199                                            fcnMakeDate, QStringLiteral( 
"Date and Time" ) )
 
 8203                                            fcnMakeTime, QStringLiteral( 
"Date and Time" ) )
 
 8210                                            fcnMakeDateTime, QStringLiteral( 
"Date and Time" ) )
 
 8218                                            fcnMakeInterval, QStringLiteral( 
"Date and Time" ) )
 
 8243                                            false, QSet< QString >(), 
false, QStringList(), true )
 
 8244        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"concat" ), -1, fcnConcat, QStringLiteral( 
"String" ), QString(), 
false, QSet<QString>(), 
false, QStringList(), true )
 
 8262                                            fcnColorMixRgb, QStringLiteral( 
"Color" ) )
 
 8266                                            fcnColorRgb, QStringLiteral( 
"Color" ) )
 
 8271                                            fncColorRgba, QStringLiteral( 
"Color" ) )
 
 8277                                            fcnCreateRamp, QStringLiteral( 
"Color" ) )
 
 8281                                            fcnColorHsl, QStringLiteral( 
"Color" ) )
 
 8286                                            fncColorHsla, QStringLiteral( 
"Color" ) )
 
 8290                                            fcnColorHsv, QStringLiteral( 
"Color" ) )
 
 8295                                            fncColorHsva, QStringLiteral( 
"Color" ) )
 
 8300                                            fcnColorCmyk, QStringLiteral( 
"Color" ) )
 
 8306                                            fncColorCmyka, QStringLiteral( 
"Color" ) )
 
 8309                                            fncColorPart, QStringLiteral( 
"Color" ) )
 
 8312                                            fncDarker, QStringLiteral( 
"Color" ) )
 
 8315                                            fncLighter, QStringLiteral( 
"Color" ) )
 
 8320                                            fcnBaseFileName, QStringLiteral( 
"Files and Paths" ) )
 
 8322                                            fcnFileSuffix, QStringLiteral( 
"Files and Paths" ) )
 
 8324                                            fcnFileExists, QStringLiteral( 
"Files and Paths" ) )
 
 8326                                            fcnFileName, QStringLiteral( 
"Files and Paths" ) )
 
 8328                                            fcnPathIsFile, QStringLiteral( 
"Files and Paths" ) )
 
 8330                                            fcnPathIsDir, QStringLiteral( 
"Files and Paths" ) )
 
 8332                                            fcnFilePath, QStringLiteral( 
"Files and Paths" ) )
 
 8334                                            fcnFileSize, QStringLiteral( 
"Files and Paths" ) )
 
 8337                                            fcnExif, QStringLiteral( 
"Files and Paths" ) )
 
 8339                                            fcnExifGeoTag, QStringLiteral( 
"GeometryGroup" ) )
 
 8343                                            fcnGenericHash, QStringLiteral( 
"Conversions" ) )
 
 8345                                            fcnHashMd5, QStringLiteral( 
"Conversions" ) )
 
 8347                                            fcnHashSha256, QStringLiteral( 
"Conversions" ) )
 
 8351                                            fcnToBase64, QStringLiteral( 
"Conversions" ) )
 
 8353                                            fcnFromBase64, QStringLiteral( 
"Conversions" ) )
 
 8359    geomFunc->setIsStatic( 
false );
 
 8360    functions << geomFunc;
 
 8364    functions << areaFunc;
 
 8370    functions << lengthFunc;
 
 8374    functions << perimeterFunc;
 
 8380              fcnRoundness, QStringLiteral( 
"GeometryGroup" ) );
 
 8394    QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
 
 8396      { QStringLiteral( 
"overlay_intersects" ), fcnGeomOverlayIntersects },
 
 8397      { QStringLiteral( 
"overlay_contains" ), fcnGeomOverlayContains },
 
 8398      { QStringLiteral( 
"overlay_crosses" ), fcnGeomOverlayCrosses },
 
 8399      { QStringLiteral( 
"overlay_equals" ), fcnGeomOverlayEquals },
 
 8400      { QStringLiteral( 
"overlay_touches" ), fcnGeomOverlayTouches },
 
 8401      { QStringLiteral( 
"overlay_disjoint" ), fcnGeomOverlayDisjoint },
 
 8402      { QStringLiteral( 
"overlay_within" ), fcnGeomOverlayWithin },
 
 8404    QMapIterator< QString, QgsExpressionFunction::FcnEval > i( geometry_overlay_definitions );
 
 8405    while ( i.hasNext() )
 
 8422      functions << fcnGeomOverlayFunc;
 
 8435    functions << fcnGeomOverlayNearestFunc;
 
 8448                                            fcnNodesToPoints, QStringLiteral( 
"GeometryGroup" ) )
 
 8450        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"collect_geometries" ), -1, fcnCollectGeometries, QStringLiteral( 
"GeometryGroup" ) )
 
 8455                                            fcnMakePointM, QStringLiteral( 
"GeometryGroup" ) )
 
 8461                                            fcnMakeTriangle, QStringLiteral( 
"GeometryGroup" ) )
 
 8466                                            fcnMakeCircle, QStringLiteral( 
"GeometryGroup" ) )
 
 8473                                            fcnMakeEllipse, QStringLiteral( 
"GeometryGroup" ) )
 
 8479                                            fcnMakeRegularPolygon, QStringLiteral( 
"GeometryGroup" ) )
 
 8483                                            fcnMakeSquare, QStringLiteral( 
"GeometryGroup" ) )
 
 8489                                            fcnMakeRectangleFrom3Points, QStringLiteral( 
"GeometryGroup" ) )
 
 8493#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<10 
 8499    }, fcnGeomMakeValid, QStringLiteral( 
"GeometryGroup" ) );
 
 8508    functions << xAtFunc;
 
 8513    functions << yAtFunc;
 
 8529                                            fcnDisjoint, QStringLiteral( 
"GeometryGroup" ) )
 
 8532                                            fcnIntersects, QStringLiteral( 
"GeometryGroup" ) )
 
 8535                                            fcnTouches, QStringLiteral( 
"GeometryGroup" ) )
 
 8538                                            fcnCrosses, QStringLiteral( 
"GeometryGroup" ) )
 
 8541                                            fcnContains, QStringLiteral( 
"GeometryGroup" ) )
 
 8544                                            fcnOverlaps, QStringLiteral( 
"GeometryGroup" ) )
 
 8547                                            fcnWithin, QStringLiteral( 
"GeometryGroup" ) )
 
 8551                                            fcnTranslate, QStringLiteral( 
"GeometryGroup" ) )
 
 8556                                            fcnRotate, QStringLiteral( 
"GeometryGroup" ) )
 
 8561                                            fcnScale, QStringLiteral( 
"GeometryGroup" ) )
 
 8572                                            fcnAffineTransform, QStringLiteral( 
"GeometryGroup" ) )
 
 8579                                            fcnBuffer, QStringLiteral( 
"GeometryGroup" ) )
 
 8581                                            fcnForceRHR, QStringLiteral( 
"GeometryGroup" ) )
 
 8583                                            fcnForcePolygonCW, QStringLiteral( 
"GeometryGroup" ) )
 
 8585                                            fcnForcePolygonCCW, QStringLiteral( 
"GeometryGroup" ) )
 
 8595                                            , fcnTaperedBuffer, QStringLiteral( 
"GeometryGroup" ) )
 
 8598                                            , fcnBufferByM, QStringLiteral( 
"GeometryGroup" ) )
 
 8604                                            fcnOffsetCurve, QStringLiteral( 
"GeometryGroup" ) )
 
 8610                                            fcnSingleSidedBuffer, QStringLiteral( 
"GeometryGroup" ) )
 
 8614                                            fcnExtend, QStringLiteral( 
"GeometryGroup" ) )
 
 8623                                            fcnInteriorRingN, QStringLiteral( 
"GeometryGroup" ) )
 
 8626                                            fcnGeometryN, QStringLiteral( 
"GeometryGroup" ) )
 
 8633    }, fcnSharedPaths, QStringLiteral( 
"GeometryGroup" ) )
 
 8647    }, fcnTriangularWave, QStringLiteral( 
"GeometryGroup" ) )
 
 8656    }, fcnTriangularWaveRandomized, QStringLiteral( 
"GeometryGroup" ) )
 
 8663    }, fcnSquareWave, QStringLiteral( 
"GeometryGroup" ) )
 
 8672    }, fcnSquareWaveRandomized, QStringLiteral( 
"GeometryGroup" ) )
 
 8679    }, fcnRoundWave, QStringLiteral( 
"GeometryGroup" ) )
 
 8688    }, fcnRoundWaveRandomized, QStringLiteral( 
"GeometryGroup" ) )
 
 8697    }, fcnApplyDashPattern, QStringLiteral( 
"GeometryGroup" ) )
 
 8702    }, fcnDensifyByCount, QStringLiteral( 
"GeometryGroup" ) )
 
 8707    }, fcnDensifyByDistance, QStringLiteral( 
"GeometryGroup" ) )
 
 8719#
if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=11 )
 
 8726                                            fcnOrientedBBox, QStringLiteral( 
"GeometryGroup" ) )
 
 8729                                            fcnMainAngle, QStringLiteral( 
"GeometryGroup" ) )
 
 8733                                            fcnMinimalCircle, QStringLiteral( 
"GeometryGroup" ) )
 
 8736                                            fcnDifference, QStringLiteral( 
"GeometryGroup" ) )
 
 8739                                            fcnDistance, QStringLiteral( 
"GeometryGroup" ) )
 
 8742                                            fcnHausdorffDistance, QStringLiteral( 
"GeometryGroup" ) )
 
 8745                                            fcnIntersection, QStringLiteral( 
"GeometryGroup" ) )
 
 8748                                            fcnSymDifference, QStringLiteral( 
"GeometryGroup" ), QString(), 
false, QSet<QString>(), 
false, QStringList() << QStringLiteral( 
"symDifference" ) )
 
 8751                                            fcnCombine, QStringLiteral( 
"GeometryGroup" ) )
 
 8754                                            fcnCombine, QStringLiteral( 
"GeometryGroup" ) )
 
 8757                                            fcnGeomToWKT, QStringLiteral( 
"GeometryGroup" ), QString(), 
false, QSet<QString>(), 
false, QStringList() << QStringLiteral( 
"geomToWKT" ) )
 
 8759                                            fcnGeomToWKB, QStringLiteral( 
"GeometryGroup" ), QString(), 
false, QSet<QString>(), 
false )
 
 8764                                            fcnTransformGeometry, QStringLiteral( 
"GeometryGroup" ) )
 
 8768                                            fcnExtrude, QStringLiteral( 
"GeometryGroup" ), QString() )
 
 8770                                            fcnGeomIsMultipart, QStringLiteral( 
"GeometryGroup" ) )
 
 8772                                            fcnZMax, QStringLiteral( 
"GeometryGroup" ) )
 
 8774                                            fcnZMin, QStringLiteral( 
"GeometryGroup" ) )
 
 8776                                            fcnMMax, QStringLiteral( 
"GeometryGroup" ) )
 
 8778                                            fcnMMin, QStringLiteral( 
"GeometryGroup" ) )
 
 8780                                            fcnSinuosity, QStringLiteral( 
"GeometryGroup" ) )
 
 8782                                            fcnStraightDistance2d, QStringLiteral( 
"GeometryGroup" ) );
 
 8788        fcnOrderParts, QStringLiteral( 
"GeometryGroup" ), QString() );
 
 8793      const QList< QgsExpressionNode *> argList = node->
args()->list();
 
 8796        if ( !argNode->isStatic( parent, context ) )
 
 8802        QgsExpressionNode *argNode = node->args()->at( 1 );
 
 8804        QString expString = argNode->eval( parent, context ).toString();
 
 8806        QgsExpression e( expString );
 
 8808        if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
 
 8819        QgsExpressionNode *argNode = node->args()->at( 1 );
 
 8820        QString expression = argNode->eval( parent, context ).toString();
 
 8821        QgsExpression e( expression );
 
 8822        e.prepare( context );
 
 8823        context->setCachedValue( expression, QVariant::fromValue( e ) );
 
 8828    functions << orderPartsFunc;
 
 8833                                            fcnClosestPoint, QStringLiteral( 
"GeometryGroup" ) )
 
 8836                                            fcnShortestLine, QStringLiteral( 
"GeometryGroup" ) )
 
 8855    functions << idFunc;
 
 8859    functions << currentFeatureFunc;
 
 8861    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" ) );
 
 8863    functions << uuidFunc;
 
 8870                                            fcnGetFeature, QStringLiteral( 
"Record and Attributes" ), QString(), 
false, QSet<QString>(), 
false, QStringList() << QStringLiteral( 
"QgsExpressionUtils::getFeature" ) )
 
 8873                                            fcnGetFeatureById, QStringLiteral( 
"Record and Attributes" ), QString(), 
false, QSet<QString>(), 
false );
 
 8878    functions << attributesFunc;
 
 8882    functions << representAttributesFunc;
 
 8890    functions << validateFeature;
 
 8899    functions << validateAttribute;
 
 8902      QStringLiteral( 
"maptip" ),
 
 8905      QStringLiteral( 
"Record and Attributes" ),
 
 8911    functions << maptipFunc;
 
 8914      QStringLiteral( 
"display_expression" ),
 
 8916      fcnFeatureDisplayExpression,
 
 8917      QStringLiteral( 
"Record and Attributes" ),
 
 8923    functions << displayFunc;
 
 8926      QStringLiteral( 
"is_selected" ),
 
 8929      QStringLiteral( 
"Record and Attributes" ),
 
 8935    functions << isSelectedFunc;
 
 8939          QStringLiteral( 
"num_selected" ),
 
 8942          QStringLiteral( 
"Record and Attributes" ),
 
 8950          QStringLiteral( 
"sqlite_fetch_and_increment" ),
 
 8958          fcnSqliteFetchAndIncrement,
 
 8959          QStringLiteral( 
"Record and Attributes" )
 
 8977          parent->
setEvalErrorString( tr( 
"If represent_value is called with 1 parameter, it must be an attribute." ) );
 
 8987        parent->
setEvalErrorString( tr( 
"represent_value must be called with exactly 1 or 2 parameters." ) );
 
 8993    functions << representValueFunc;
 
 8999                                            fcnGetLayerProperty, QStringLiteral( 
"Map Layers" ) )
 
 9004                                            fcnDecodeUri, QStringLiteral( 
"Map Layers" ) )
 
 9008                                            fcnMimeType, QStringLiteral( 
"General" ) )
 
 9025        QgsExpressionNode *argNode = node->args()->at( 0 );
 
 9027        if ( !argNode->isStatic( parent, context ) )
 
 9030        const QString varName = argNode->eval( parent, context ).toString();
 
 9031        if ( varName == QLatin1String( 
"feature" ) || varName == QLatin1String( 
"id" ) || varName == QLatin1String( 
"geometry" ) )
 
 9034        const QgsExpressionContextScope *scope = context->activeScopeForVariable( varName );
 
 9035        return scope ? scope->isStatic( varName ) : false;
 
 9043      if ( node && node->
args()->
count() > 0 )
 
 9045        QgsExpressionNode *argNode = node->args()->at( 0 );
 
 9046        if ( QgsExpressionNodeLiteral *literal = dynamic_cast<QgsExpressionNodeLiteral *>( argNode ) )
 
 9048          if ( literal->value() == QLatin1String( 
"geometry" ) || literal->value() == QLatin1String( 
"feature" ) )
 
 9067        QgsExpressionNode *argNode = node->args()->at( 0 );
 
 9069        if ( argNode->isStatic( parent, context ) )
 
 9071          QString expString = argNode->eval( parent, context ).toString();
 
 9073          QgsExpression e( expString );
 
 9075          if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
 
 9083    functions << evalFunc;
 
 9089      const QList< QgsExpressionNode *> argList = node->
args()->list();
 
 9092        if ( !argNode->isStatic( parent, context ) )
 
 9104    functions << attributeFunc;
 
 9115        << 
new QgsStaticExpressionFunction( QStringLiteral( 
"array" ), -1, fcnArray, QStringLiteral( 
"Arrays" ), QString(), 
false, QSet<QString>(), 
false, QStringList(), 
true )
 
 9164                                            fcnMapPrefixKeys, QStringLiteral( 
"Maps" ) )
 
 9166                                            fcnMapToHtmlTable, QStringLiteral( 
"Maps" ) )
 
 9168                                            fcnMapToHtmlDefinitionList, QStringLiteral( 
"Maps" ) )
 
 9170                                            fcnToFormUrlEncode, QStringLiteral( 
"Maps" ) )
 
 9179      *sOwnedFunctions() << func;
 
 9180      *sBuiltinFunctions() << func->name();
 
 9181      sBuiltinFunctions()->append( func->aliases() );
 
 9194  sFunctions()->append( function );
 
 9195  if ( transferOwnership )
 
 9196    sOwnedFunctions()->append( function );
 
 9210    sFunctions()->removeAt( fnIdx );
 
 9218  qDeleteAll( *sOwnedFunctions() );
 
 9219  sOwnedFunctions()->clear();
 
 9224  if ( sBuiltinFunctions()->isEmpty() )
 
 9228  return *sBuiltinFunctions();
 
 9236                           QStringLiteral( 
"Arrays" ) )
 
 9247  if ( args->
count() < 2 )
 
 9250  if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
 
 9260  QVariantList result;
 
 9262  if ( args->
count() < 2 )
 
 9266  QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
 
 9269  std::unique_ptr< QgsExpressionContext > tempContext;
 
 9272    tempContext = std::make_unique< QgsExpressionContext >();
 
 9273    subContext = tempContext.get();
 
 9279  for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
 
 9282    result << args->
at( 1 )->
eval( parent, subContext );
 
 9307  if ( args->
count() < 2 )
 
 9311  args->
at( 0 )->
prepare( parent, context );
 
 9315    subContext = *context;
 
 9321  args->
at( 1 )->
prepare( parent, &subContext );
 
 9331                           QStringLiteral( 
"Arrays" ) )
 
 9342  if ( args->
count() < 2 )
 
 9345  if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
 
 9355  QVariantList result;
 
 9357  if ( args->
count() < 2 )
 
 9361  const QVariantList array = args->
at( 0 )->
eval( parent, context ).toList();
 
 9364  std::unique_ptr< QgsExpressionContext > tempContext;
 
 9367    tempContext = std::make_unique< QgsExpressionContext >();
 
 9368    subContext = tempContext.get();
 
 9375  if ( args->
count() >= 3 )
 
 9377    const QVariant limitVar = args->
at( 2 )->
eval( parent, context );
 
 9379    if ( QgsExpressionUtils::isIntSafe( limitVar ) )
 
 9381      limit = limitVar.toInt();
 
 9389  for ( 
const QVariant &value : array )
 
 9392    if ( args->
at( 1 )->
eval( parent, subContext ).toBool() )
 
 9396      if ( limit > 0 && limit == result.size() )
 
 9423  if ( args->
count() < 2 )
 
 9427  args->
at( 0 )->
prepare( parent, context );
 
 9431    subContext = *context;
 
 9437  args->
at( 1 )->
prepare( parent, &subContext );
 
 9446                           QStringLiteral( 
"General" ) )
 
 9457  if ( args->
count() < 3 )
 
 9461  if ( args->
at( 0 )->
isStatic( parent, context ) && args->
at( 1 )->
isStatic( parent, context ) )
 
 9463    QVariant 
name = args->
at( 0 )->
eval( parent, context );
 
 9464    QVariant value = args->
at( 1 )->
eval( parent, context );
 
 9467    appendTemporaryVariable( context, 
name.toString(), value );
 
 9468    if ( args->
at( 2 )->
isStatic( parent, context ) )
 
 9470    popTemporaryVariable( context );
 
 9481  if ( args->
count() < 3 )
 
 9485  QVariant 
name = args->
at( 0 )->
eval( parent, context );
 
 9486  QVariant value = args->
at( 1 )->
eval( parent, context );
 
 9489  std::unique_ptr< QgsExpressionContext > tempContext;
 
 9490  if ( !updatedContext )
 
 9492    tempContext = std::make_unique< QgsExpressionContext >();
 
 9493    updatedContext = tempContext.get();
 
 9496  appendTemporaryVariable( updatedContext, 
name.toString(), value );
 
 9497  result = args->
at( 2 )->
eval( parent, updatedContext );
 
 9500    popTemporaryVariable( updatedContext );
 
 9521  if ( args->
count() < 3 )
 
 9526  QVariant value = args->
at( 1 )->
prepare( parent, context );
 
 9529  std::unique_ptr< QgsExpressionContext > tempContext;
 
 9530  if ( !updatedContext )
 
 9532    tempContext = std::make_unique< QgsExpressionContext >();
 
 9533    updatedContext = tempContext.get();
 
 9536  appendTemporaryVariable( updatedContext, 
name.toString(), value );
 
 9537  args->
at( 2 )->
prepare( parent, updatedContext );
 
 9540    popTemporaryVariable( updatedContext );
 
 9545void QgsWithVariableExpressionFunction::popTemporaryVariable( 
const QgsExpressionContext *context )
 const 
 9551void QgsWithVariableExpressionFunction::appendTemporaryVariable( 
const QgsExpressionContext *context, 
const QString &name, 
const QVariant &value )
 const 
DashPatternSizeAdjustment
Dash pattern size adjustment options.
 
@ ScaleDashOnly
Only dash lengths are adjusted.
 
@ ScaleBothDashAndGap
Both the dash and gap lengths are adjusted equally.
 
@ ScaleGapOnly
Only gap lengths are adjusted.
 
@ Success
Operation succeeded.
 
JoinStyle
Join styles for buffers.
 
EndCapStyle
End cap styles for buffers.
 
DashPatternLineEndingRule
Dash pattern line ending rules.
 
@ HalfDash
Start or finish the pattern with a half length dash.
 
@ HalfGap
Start or finish the pattern with a half length gap.
 
@ FullGap
Start or finish the pattern with a full gap.
 
@ FullDash
Start or finish the pattern with a full dash.
 
MakeValidMethod
Algorithms to use when repairing invalid geometries.
 
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
 
@ Structure
Structured method, first makes all rings valid and then merges shells and subtracts holes from shells...
 
Abstract base class for all geometries.
 
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
 
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
 
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
 
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
 
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
 
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
 
part_iterator parts_end()
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
 
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
 
virtual const QgsAbstractGeometry * simplifiedTypeRef() const SIP_HOLDGIL
Returns a reference to the simplest lossless representation of this geometry, e.g.
 
virtual QgsCoordinateSequence coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
 
virtual int partCount() const =0
Returns count of parts contained in the geometry.
 
Qgis::WkbType wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
 
part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
 
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
 
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
 
Aggregate
Available aggregates to calculate.
 
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
 
@ StringMaximumLength
Maximum length of string (string fields only)
 
@ ThirdQuartile
Third quartile (numeric fields only)
 
@ Range
Range of values (max - min) (numeric and datetime fields only)
 
@ ArrayAggregate
Create an array of values.
 
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only)
 
@ FirstQuartile
First quartile (numeric fields only)
 
@ Median
Median of values (numeric fields only)
 
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
 
@ CountMissing
Number of missing (null) values.
 
@ StDevSample
Sample standard deviation of values (numeric fields only)
 
@ Majority
Majority of values.
 
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
 
@ Mean
Mean of values (numeric fields only)
 
@ StringMinimumLength
Minimum length of string (string fields only)
 
@ CountDistinct
Number of distinct values.
 
@ Minority
Minority of values.
 
static Aggregate stringToAggregate(const QString &string, bool *ok=nullptr)
Converts a string to a aggregate type.
 
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
 
Handles the array_filter(array, expression) expression function.
 
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
 
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
 
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
 
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
 
QgsArrayFilterExpressionFunction()
 
Handles the array loopingarray_Foreach(array, expression) expression function.
 
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
 
QgsArrayForeachExpressionFunction()
 
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
 
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
 
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
 
Abstract base class for color ramps.
 
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
 
This class represents a coordinate reference system (CRS).
 
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
 
Q_GADGET Qgis::DistanceUnit mapUnits
 
QString toProj() const
Returns a Proj string representation of this CRS.
 
Contains information about the context in which a coordinate transform is executed.
 
Custom exception class for Coordinate Reference System related exceptions.
 
Curve polygon geometry type.
 
int ringCount(int part=0) const override SIP_HOLDGIL
Returns the number of rings of which this geometry is built.
 
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
 
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
 
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
 
double roundness() const
Returns the roundness of the curve polygon.
 
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
 
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
 
Abstract base class for curved geometry type.
 
double sinuosity() const
Returns the curve sinuosity, which is the ratio of the curve length() to curve straightDistance2d().
 
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
 
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
 
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
 
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
 
double straightDistance2d() const
Returns the straight distance of the curve, i.e.
 
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
 
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
 
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
 
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
 
double convertLengthMeasurement(double length, Qgis::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
 
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, Qgis::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
 
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
 
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
 
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
 
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
 
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
 
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
 
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
 
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
 
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
 
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
 
bool hasGeometry() const
Returns true if the context has a geometry associated with it.
 
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
 
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
 
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
 
bool hasFeature() const
Returns true if the context has a feature associated with it.
 
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
 
Represents a single parameter passed to a function.
 
A abstract base class for defining QgsExpression functions.
 
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
 
bool operator==(const QgsExpressionFunction &other) const
 
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...
 
virtual bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
Will be called during prepare to determine if the function is static.
 
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
 
bool lazyEval() const
true if this function should use lazy evaluation.
 
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
 
QString name() const
The name of the function.
 
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
 
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)=0
Returns result of evaluating the function.
 
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
 
virtual bool handlesNull() const
Returns true if the function handles NULL values in arguments by itself, and the default NULL value h...
 
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
 
virtual bool usesGeometry(const QgsExpressionNodeFunction *node) const
Does this function use a geometry object.
 
An expression node which takes it value from a feature's field.
 
QString name() const
The name of the column.
 
An expression node for expression functions.
 
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
 
An expression node for literal values.
 
A list of expression nodes.
 
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
 
QgsExpressionNode * at(int i)
Gets the node at position i in the list.
 
int count() const
Returns the number of nodes in the list.
 
Abstract base class for all nodes that can appear in an expression.
 
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
 
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
 
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
 
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
 
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
 
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
 
A set of expression-related functions.
 
Class for parsing and evaluation of expressions (formerly called "search strings").
 
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
 
static const QList< QgsExpressionFunction * > & Functions()
 
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
 
Qgis::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
 
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...
 
static PRIVATE 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.
 
Qgis::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
 
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 & 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.
 
QgsVectorLayer * materialize(const QgsFeatureRequest &request, QgsFeedback *feedback=nullptr)
Materializes a request (query) made against this feature source, by running it over the source and re...
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
bool hasGeometry() const
Returns true if the feature has an associated geometry.
 
bool isValid() const
Returns the validity of this feature.
 
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
 
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
 
ConstraintStrength
Strength of constraints.
 
@ ConstraintStrengthNotSet
Constraint is not set.
 
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
 
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
 
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
 
Container of fields for a vector layer.
 
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
 
int count() const
Returns number of items.
 
int size() const
Returns number of items.
 
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
 
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
 
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
 
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
 
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
 
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
 
int partCount() const override
Returns count of parts contained in the geometry.
 
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
 
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
 
A geometry is the spatial representation of a feature.
 
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
 
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
 
double lineLocatePoint(const QgsGeometry &point) const
Returns a distance representing the location along this linestring of the closest point on this lines...
 
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
 
double length() const
Returns the planar, 2-dimensional length of geometry.
 
QgsGeometry offsetCurve(double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
 
QgsGeometry densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
 
QgsGeometry poleOfInaccessibility(double precision, double *distanceToBoundary=nullptr) const
Calculates the approximate pole of inaccessibility for a surface, which is the most distant internal ...
 
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
 
QgsGeometry squareWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs square waves along the boundary of the geometry, with the specified wavelength and amplitu...
 
QgsGeometry triangularWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs triangular waves along the boundary of the geometry, with the specified wavelength and amp...
 
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
 
QgsGeometry concaveHull(double targetPercent, bool allowHoles=false) const SIP_THROW(QgsNotSupportedException)
Returns a possibly concave polygon that contains all the points in the geometry.
 
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
 
bool touches(const QgsGeometry &geometry) const
Returns true if the geometry touches another geometry.
 
QgsGeometry applyDashPattern(const QVector< double > &pattern, Qgis::DashPatternLineEndingRule startRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternLineEndingRule endRule=Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternSizeAdjustment adjustment=Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap, double patternOffset=0) const
Applies a dash pattern to a geometry, returning a MultiLineString geometry which is the input geometr...
 
QgsGeometry roundWaves(double wavelength, double amplitude, bool strictWavelength=false) const
Constructs rounded (sine-like) waves along the boundary of the geometry, with the specified wavelengt...
 
QgsGeometry nearestPoint(const QgsGeometry &other) const
Returns the nearest (closest) point on this geometry to another geometry.
 
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
 
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
 
QgsGeometry combine(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
 
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer for a (multi)linestring geometry, where the width at each node is ...
 
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
 
bool disjoint(const QgsGeometry &geometry) const
Returns true if the geometry is disjoint of another geometry.
 
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
 
QgsGeometry roundWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized rounded (sine-like) waves along the boundary of the geometry,...
 
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
 
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
 
QgsGeometry extrude(double x, double y)
Returns an extruded version of this geometry.
 
QgsGeometry singleSidedBuffer(double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle=Qgis::JoinStyle::Round, double miterLimit=2.0) const
Returns a single sided buffer for a (multi)line geometry.
 
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
 
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
 
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
 
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
 
QgsGeometry forceRHR() const
Forces geometries to respect the Right-Hand-Rule, in which the area that is bounded by a polygon is t...
 
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
 
bool equals(const QgsGeometry &geometry) const
Test if this geometry is exactly equal to another geometry.
 
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
 
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a variable width buffer ("tapered buffer") for a (multi)curve geometry.
 
bool within(const QgsGeometry &geometry) const
Returns true if the geometry is completely within another geometry.
 
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
 
double area() const
Returns the planar, 2-dimensional area of the geometry.
 
QgsGeometry centroid() const
Returns the center of mass of a geometry.
 
bool crosses(const QgsGeometry &geometry) const
Returns true if the geometry crosses another geometry.
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
 
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
 
QString lastError() const SIP_HOLDGIL
Returns an error string referring to the last error encountered either when this geometry was created...
 
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false) const SIP_THROW(QgsNotSupportedException)
Attempts to make an invalid geometry valid without losing vertices.
 
QgsGeometry convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry.
 
QgsGeometry sharedPaths(const QgsGeometry &other) const
Find paths shared between the two given lineal geometries (this and other).
 
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
 
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
 
QgsGeometry symDifference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
 
QgsGeometry minimalEnclosingCircle(QgsPointXY ¢er, double &radius, unsigned int segments=36) const
Returns the minimal enclosing circle for the geometry.
 
QgsGeometry mergeLines() const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
 
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
 
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
 
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
 
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
 
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
 
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
 
QgsGeometry forcePolygonClockwise() const
Forces geometries to respect the exterior ring is clockwise, interior rings are counter-clockwise con...
 
static QgsGeometry createWedgeBuffer(const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
 
QgsGeometry extendLine(double startDistance, double endDistance) const
Extends a (multi)line geometry by extrapolating out the start or end of the line by a specified dista...
 
QgsGeometry triangularWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized triangular waves along the boundary of the geometry, with the specified wavelen...
 
QgsGeometry squareWavesRandomized(double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed=0) const
Constructs randomized square waves along the boundary of the geometry, with the specified wavelength ...
 
QgsGeometry simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
 
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
 
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
 
double interpolateAngle(double distance) const
Returns the angle parallel to the linestring or polygon boundary at the specified distance along the ...
 
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
 
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
 
QgsGeometry forcePolygonCounterClockwise() const
Forces geometries to respect the exterior ring is counter-clockwise, interior rings are clockwise con...
 
QString asWkt(int precision=17) const
Exports the geometry to WKT.
 
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
 
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
 
bool overlaps(const QgsGeometry &geometry) const
Returns true if the geometry overlaps another geometry.
 
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
 
Does vector analysis using the geos library and handles import, export, exception handling*.
 
std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle(double tolerance, QString *errorMsg=nullptr) const
Returns the maximum inscribed circle.
 
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
 
Represents a color stop within a QgsGradientColorRamp color ramp.
 
A representation of the interval between two datetime values.
 
bool isValid() const
Returns true if the interval is valid.
 
double days() const
Returns the interval duration in days.
 
double weeks() const
Returns the interval duration in weeks.
 
double months() const
Returns the interval duration in months (based on a 30 day month).
 
double seconds() const
Returns the interval duration in seconds.
 
double years() const
Returns the interval duration in years (based on an average year length)
 
double hours() const
Returns the interval duration in hours.
 
double minutes() const
Returns the interval duration in minutes.
 
Line string geometry type, with support for z-dimension and m-values.
 
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
 
Base class for all map layer types.
 
virtual QgsRectangle extent() const
Returns the extent of the layer.
 
QString source() const
Returns the source for the layer.
 
QString providerType() const
Returns the provider type (provider key) for this layer.
 
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
 
QgsCoordinateReferenceSystem crs
 
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
 
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
 
QgsLayerMetadata metadata
 
virtual bool isEditable() const
Returns true if the layer can be edited.
 
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.
 
Implementation of GeometrySimplifier using the "MapToPixel" algorithm.
 
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
 
@ SimplifyGeometry
The geometries can be simplified using the current map2pixel context state.
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
 
Multi line string geometry collection.
 
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
 
Multi point geometry collection.
 
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
 
Custom exception class which is raised when an operation is not supported.
 
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
 
A class to represent a 2D point.
 
Point geometry type, with support for z-dimension and m-values.
 
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override SIP_HOLDGIL
Checks validity of the geometry, and returns true if the geometry is valid.
 
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
 
double inclination(const QgsPoint &other) const SIP_HOLDGIL
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
 
QgsRelationManager * relationManager
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
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 Field class represents a Raster Attribute Table field, including its name, usage and type.
 
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.
 
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.
 
void setUsesGeometryFunction(const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry)
Set a function that will be called when determining if the function requires feature geometry 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(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
 
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
 
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
 
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
 
Represents a vector layer which manages a vector based data sets.
 
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.
 
QgsFields fields() const FINAL
Returns the list of fields of this layer.
 
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.
 
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
 
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(Qgis::GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.
 
static Qgis::WkbType flatType(Qgis::WkbType 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).
 
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.
 
#define Q_NOWARN_DEPRECATED_POP
 
#define Q_NOWARN_DEPRECATED_PUSH
 
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< QgsRingSequence > QgsCoordinateSequence
 
QVector< QgsPointSequence > QgsRingSequence
 
QVector< QgsPoint > QgsPointSequence
 
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
 
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
 
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
 
QList< QgsExpressionFunction * > ExpressionFunctionList
 
#define ENSURE_GEOM_TYPE(f, g, geomtype)
 
QVariant fcnRampColor(const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction *)
 
bool(QgsGeometry::* RelationFunction)(const QgsGeometry &geometry) const
 
#define ENSURE_NO_EVAL_ERROR
 
#define FEAT_FROM_CONTEXT(c, f)
 
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
 
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
 
QLineF segment(int index, QRectF rect, double radius)
 
A bundle of parameters controlling aggregate calculation.
 
QString filter
Optional filter for calculating aggregate over a subset of features, or an empty string to use all fe...
 
QString delimiter
Delimiter to use for joining values with the StringConcatenate aggregate.
 
QgsFeatureRequest::OrderBy orderBy
Optional order by clauses.
 
Single variable definition for use within a QgsExpressionContextScope.
 
The Context struct stores the current layer and coordinate transform context.
 
const QgsMapLayer * layer
 
QgsCoordinateTransformContext transformContext
 
Utility class for identifying a unique vertex within a geometry.