45 mFilterExpression = parameters.
filter;
69 context = context ? context : &defaultContext;
71 std::unique_ptr<QgsExpression> expression;
79 expression = std::make_unique<QgsExpression>( fieldOrExpression );
81 if ( expression->hasParserError() || !expression->prepare( context ) )
83 mLastError = !expression->parserErrorString().isEmpty() ? expression->parserErrorString() : expression->evalErrorString();
90 lst.insert( mLayer->fields().at( attrNum ).name() );
92 lst = expression->referencedColumns();
94 bool expressionNeedsGeometry { expression &&expression->needsGeometry() };
96 if ( !mOrderBy.empty() )
101 if ( orderBy.expression().needsGeometry() )
103 expressionNeedsGeometry =
true;
109 request.
setFlags( expressionNeedsGeometry ?
117 if ( !mFilterExpression.isEmpty() )
125 QMetaType::Type resultType = QMetaType::Type::Double;
131 resultType = QMetaType::Type::User;
136 bool foundFeatures =
false;
138 if ( !foundFeatures )
142 return defaultValue( aggregate );
145 resultType = std::get<0>( returnType );
146 if ( resultType == QMetaType::Type::UnknownType )
190 resultType =
static_cast<QMetaType::Type
>( v.userType() );
195 resultType = mLayer->fields().at( attrNum ).type();
198 return calculate( aggregate, fit, resultType, attrNum, expression.get(), mDelimiter, context, ok, &mLastError );
203 const QString normalized =
string.trimmed().toLower();
208 if ( normalized == QLatin1String(
"count" ) )
210 else if ( normalized == QLatin1String(
"count_distinct" ) )
212 else if ( normalized == QLatin1String(
"count_missing" ) )
214 else if ( normalized == QLatin1String(
"min" ) || normalized == QLatin1String(
"minimum" ) )
216 else if ( normalized == QLatin1String(
"max" ) || normalized == QLatin1String(
"maximum" ) )
218 else if ( normalized == QLatin1String(
"sum" ) )
220 else if ( normalized == QLatin1String(
"mean" ) )
222 else if ( normalized == QLatin1String(
"median" ) )
224 else if ( normalized == QLatin1String(
"stdev" ) )
226 else if ( normalized == QLatin1String(
"stdevsample" ) )
228 else if ( normalized == QLatin1String(
"range" ) )
230 else if ( normalized == QLatin1String(
"minority" ) )
232 else if ( normalized == QLatin1String(
"majority" ) )
234 else if ( normalized == QLatin1String(
"q1" ) )
236 else if ( normalized == QLatin1String(
"q3" ) )
238 else if ( normalized == QLatin1String(
"iqr" ) )
240 else if ( normalized == QLatin1String(
"min_length" ) )
242 else if ( normalized == QLatin1String(
"max_length" ) )
244 else if ( normalized == QLatin1String(
"concatenate" ) )
246 else if ( normalized == QLatin1String(
"concatenate_unique" ) )
248 else if ( normalized == QLatin1String(
"collect" ) )
250 else if ( normalized == QLatin1String(
"array_agg" ) )
264 return QObject::tr(
"count" );
266 return QObject::tr(
"count distinct" );
268 return QObject::tr(
"count missing" );
270 return QObject::tr(
"minimum" );
272 return QObject::tr(
"maximum" );
274 return QObject::tr(
"sum" );
276 return QObject::tr(
"mean" );
278 return QObject::tr(
"median" );
280 return QObject::tr(
"standard deviation" );
282 return QObject::tr(
"standard deviation (sample)" );
284 return QObject::tr(
"range" );
286 return QObject::tr(
"minority" );
288 return QObject::tr(
"majority" );
290 return QObject::tr(
"first quartile" );
292 return QObject::tr(
"third quartile" );
294 return QObject::tr(
"inter quartile range" );
296 return QObject::tr(
"minimum length" );
298 return QObject::tr(
"maximum length" );
300 return QObject::tr(
"concatenate" );
302 return QObject::tr(
"collection" );
304 return QObject::tr(
"array aggregate" );
306 return QObject::tr(
"concatenate (unique)" );
317 QStringLiteral(
"count" ),
318 QCoreApplication::tr(
"Count" ),
319 QSet<QMetaType::Type>()
320 << QMetaType::Type::QDateTime
321 << QMetaType::Type::QDate
322 << QMetaType::Type::Int
323 << QMetaType::Type::UInt
324 << QMetaType::Type::LongLong
325 << QMetaType::Type::ULongLong
326 << QMetaType::Type::QString
330 QStringLiteral(
"count_distinct" ),
331 QCoreApplication::tr(
"Count Distinct" ),
332 QSet<QMetaType::Type>()
333 << QMetaType::Type::QDateTime
334 << QMetaType::Type::QDate
335 << QMetaType::Type::UInt
336 << QMetaType::Type::Int
337 << QMetaType::Type::LongLong
338 << QMetaType::Type::ULongLong
339 << QMetaType::Type::QString
343 QStringLiteral(
"count_missing" ),
344 QCoreApplication::tr(
"Count Missing" ),
345 QSet<QMetaType::Type>()
346 << QMetaType::Type::QDateTime
347 << QMetaType::Type::QDate
348 << QMetaType::Type::Int
349 << QMetaType::Type::UInt
350 << QMetaType::Type::LongLong
351 << QMetaType::Type::QString
355 QStringLiteral(
"min" ),
356 QCoreApplication::tr(
"Min" ),
357 QSet<QMetaType::Type>()
358 << QMetaType::Type::QDateTime
359 << QMetaType::Type::QDate
360 << QMetaType::Type::Int
361 << QMetaType::Type::UInt
362 << QMetaType::Type::LongLong
363 << QMetaType::Type::ULongLong
364 << QMetaType::Type::Double
365 << QMetaType::Type::QString
369 QStringLiteral(
"max" ),
370 QCoreApplication::tr(
"Max" ),
371 QSet<QMetaType::Type>()
372 << QMetaType::Type::QDateTime
373 << QMetaType::Type::QDate
374 << QMetaType::Type::Int
375 << QMetaType::Type::UInt
376 << QMetaType::Type::LongLong
377 << QMetaType::Type::ULongLong
378 << QMetaType::Type::Double
379 << QMetaType::Type::QString
383 QStringLiteral(
"sum" ),
384 QCoreApplication::tr(
"Sum" ),
385 QSet<QMetaType::Type>()
386 << QMetaType::Type::Int
387 << QMetaType::Type::UInt
388 << QMetaType::Type::LongLong
389 << QMetaType::Type::ULongLong
390 << QMetaType::Type::Double
394 QStringLiteral(
"mean" ),
395 QCoreApplication::tr(
"Mean" ),
396 QSet<QMetaType::Type>()
397 << QMetaType::Type::Int
398 << QMetaType::Type::UInt
399 << QMetaType::Type::LongLong
400 << QMetaType::Type::ULongLong
401 << QMetaType::Type::Double
405 QStringLiteral(
"median" ),
406 QCoreApplication::tr(
"Median" ),
407 QSet<QMetaType::Type>()
408 << QMetaType::Type::Int
409 << QMetaType::Type::UInt
410 << QMetaType::Type::Double
414 QStringLiteral(
"stdev" ),
415 QCoreApplication::tr(
"Stdev" ),
416 QSet<QMetaType::Type>()
417 << QMetaType::Type::Int
418 << QMetaType::Type::UInt
419 << QMetaType::Type::LongLong
420 << QMetaType::Type::ULongLong
421 << QMetaType::Type::Double
425 QStringLiteral(
"stdevsample" ),
426 QCoreApplication::tr(
"Stdev Sample" ),
427 QSet<QMetaType::Type>()
428 << QMetaType::Type::Int
429 << QMetaType::Type::UInt
430 << QMetaType::Type::LongLong
431 << QMetaType::Type::ULongLong
432 << QMetaType::Type::Double
436 QStringLiteral(
"range" ),
437 QCoreApplication::tr(
"Range" ),
438 QSet<QMetaType::Type>()
439 << QMetaType::Type::QDate
440 << QMetaType::Type::QDateTime
441 << QMetaType::Type::Int
442 << QMetaType::Type::UInt
443 << QMetaType::Type::LongLong
444 << QMetaType::Type::ULongLong
445 << QMetaType::Type::Double
449 QStringLiteral(
"minority" ),
450 QCoreApplication::tr(
"Minority" ),
451 QSet<QMetaType::Type>()
452 << QMetaType::Type::Int
453 << QMetaType::Type::UInt
454 << QMetaType::Type::LongLong
455 << QMetaType::Type::ULongLong
456 << QMetaType::Type::Double
457 << QMetaType::Type::QString
461 QStringLiteral(
"majority" ),
462 QCoreApplication::tr(
"Majority" ),
463 QSet<QMetaType::Type>()
464 << QMetaType::Type::Int
465 << QMetaType::Type::UInt
466 << QMetaType::Type::LongLong
467 << QMetaType::Type::ULongLong
468 << QMetaType::Type::Double
469 << QMetaType::Type::QString
473 QStringLiteral(
"q1" ),
474 QCoreApplication::tr(
"Q1" ),
475 QSet<QMetaType::Type>()
476 << QMetaType::Type::Int
477 << QMetaType::Type::UInt
478 << QMetaType::Type::LongLong
479 << QMetaType::Type::ULongLong
480 << QMetaType::Type::Double
484 QStringLiteral(
"q3" ),
485 QCoreApplication::tr(
"Q3" ),
486 QSet<QMetaType::Type>()
487 << QMetaType::Type::Int
488 << QMetaType::Type::UInt
489 << QMetaType::Type::LongLong
490 << QMetaType::Type::ULongLong
491 << QMetaType::Type::Double
495 QStringLiteral(
"iqr" ),
496 QCoreApplication::tr(
"InterQuartileRange" ),
497 QSet<QMetaType::Type>()
498 << QMetaType::Type::Int
499 << QMetaType::Type::UInt
500 << QMetaType::Type::LongLong
501 << QMetaType::Type::ULongLong
502 << QMetaType::Type::Double
506 QStringLiteral(
"min_length" ),
507 QCoreApplication::tr(
"Min Length" ),
508 QSet<QMetaType::Type>()
509 << QMetaType::Type::QString
513 QStringLiteral(
"max_length" ),
514 QCoreApplication::tr(
"Max Length" ),
515 QSet<QMetaType::Type>()
516 << QMetaType::Type::QString
520 QStringLiteral(
"concatenate" ),
521 QCoreApplication::tr(
"Concatenate" ),
522 QSet<QMetaType::Type>()
523 << QMetaType::Type::QString
527 QStringLiteral(
"collect" ),
528 QCoreApplication::tr(
"Collect" ),
529 QSet<QMetaType::Type>()
533 QStringLiteral(
"array_agg" ),
534 QCoreApplication::tr(
"Array Aggregate" ),
535 QSet<QMetaType::Type>()
551 return calculateArrayAggregate( fit, attr, expression, context );
554 switch ( resultType )
556 case QMetaType::Type::Int:
557 case QMetaType::Type::UInt:
558 case QMetaType::Type::LongLong:
559 case QMetaType::Type::ULongLong:
560 case QMetaType::Type::Double:
563 const Qgis::Statistic stat = numericStatFromAggregate( aggregate, &statOk );
567 *error = expression ? QObject::tr(
"Cannot calculate %1 on numeric values" ).arg(
displayName( aggregate ) )
568 : QObject::tr(
"Cannot calculate %1 on numeric fields" ).arg(
displayName( aggregate ) );
574 return calculateNumericAggregate( fit, attr, expression, context, stat );
577 case QMetaType::Type::QDate:
578 case QMetaType::Type::QDateTime:
585 *error = ( expression ? QObject::tr(
"Cannot calculate %1 on %2 values" ).arg(
displayName( aggregate ) ) :
586 QObject::tr(
"Cannot calculate %1 on %2 fields" ).arg(
displayName( aggregate ) ) ).arg( resultType == QMetaType::Type::QDate ? QObject::tr(
"date" ) : QObject::tr(
"datetime" ) );
592 return calculateDateTimeAggregate( fit, attr, expression, context, stat );
595 case QMetaType::Type::User:
601 return calculateGeometryAggregate( fit, expression, context );
617 return concatenateStrings( fit, attr, expression, context,
delimiter );
624 return concatenateStrings( fit, attr, expression, context,
delimiter,
true );
632 if ( resultType == QMetaType::Type::UnknownType )
633 typeString = QObject::tr(
"null" );
635 typeString = resultType == QMetaType::Type::QString ? QObject::tr(
"string" ) : QVariant::typeToName( resultType );
638 *error = expression ? QObject::tr(
"Cannot calculate %1 on %3 values" ).arg(
displayName( aggregate ), typeString )
639 : QObject::tr(
"Cannot calculate %1 on %3 fields" ).arg(
displayName( aggregate ), typeString );
645 return calculateStringAggregate( fit, attr, expression, context, stat );
813 Q_ASSERT( expression || attr >= 0 );
815 QgsStatisticalSummary s( stat );
824 const QVariant v = expression->
evaluate( context );
833 const double val = s.statistic( stat );
834 return std::isnan( val ) ? QVariant() : val;
840 Q_ASSERT( expression || attr >= 0 );
842 QgsStringStatisticalSummary s( stat );
851 const QVariant v = expression->
evaluate( context );
860 return s.statistic( stat );
865 Q_ASSERT( expression );
868 QVector< QgsGeometry > geometries;
873 const QVariant v = expression->
evaluate( context );
874 if ( v.userType() == qMetaTypeId< QgsGeometry>() )
876 geometries << v.value<QgsGeometry>();
886 Q_ASSERT( expression || attr >= 0 );
897 const QVariant v = expression->
evaluate( context );
898 result = v.toString();
905 if ( !unique || !results.contains( result ) )
912QVariant QgsAggregateCalculator::defaultValue(
Qgis::Aggregate aggregate )
const
928 return QVariantList();
955 Q_ASSERT( expression || attr >= 0 );
957 QgsDateTimeStatisticalSummary s( stat );
966 const QVariant v = expression->
evaluate( context );
975 return s.statistic( stat );
981 Q_ASSERT( expression || attr >= 0 );
993 const QVariant v = expression->
evaluate( context );
Statistic
Available generic statistics.
@ StDev
Standard deviation of values.
@ FirstQuartile
First quartile.
@ Median
Median of values.
@ Range
Range of values (max - min).
@ Minority
Minority of values.
@ CountMissing
Number of missing (null) values.
@ Majority
Majority of values.
@ Variety
Variety (count of distinct) values.
@ StDevSample
Sample standard deviation of values.
@ ThirdQuartile
Third quartile.
@ InterQuartileRange
Inter quartile range (IQR).
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
StringStatistic
Available string statistics.
@ Max
Maximum string value.
@ Min
Minimum string value.
@ MaximumLength
Maximum length of string.
@ Minority
Minority of strings.
@ CountMissing
Number of missing (null) values.
@ Majority
Majority of strings.
@ CountDistinct
Number of distinct string values.
@ MinimumLength
Minimum length of string.
Aggregate
Available aggregates to calculate.
@ StDev
Standard deviation of values (numeric fields only).
@ StringMinimumLength
Minimum length of string (string fields only).
@ FirstQuartile
First quartile (numeric fields only).
@ Mean
Mean of values (numeric fields only).
@ Median
Median of values (numeric fields only).
@ StringMaximumLength
Maximum length of string (string fields only).
@ Range
Range of values (max - min) (numeric and datetime fields only).
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
@ Minority
Minority of values.
@ CountMissing
Number of missing (null) values.
@ ArrayAggregate
Create an array of values.
@ Majority
Majority of values.
@ StDevSample
Sample standard deviation of values (numeric fields only).
@ ThirdQuartile
Third quartile (numeric fields only).
@ CountDistinct
Number of distinct values.
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
DateTimeStatistic
Available date/time statistics.
@ Max
Maximum (latest) datetime value.
@ Min
Minimum (earliest) datetime value.
@ Range
Interval between earliest and latest datetime value.
@ CountMissing
Number of missing (null) values.
@ CountDistinct
Number of distinct datetime values.
const QgsVectorLayer * layer() const
Returns the associated vector layer.
void setParameters(const AggregateParameters ¶meters)
Sets all aggregate parameters from a parameter bundle.
void setFidsFilter(const QgsFeatureIds &fids)
Sets a filter to limit the features used during the aggregate calculation.
static QList< QgsAggregateCalculator::AggregateInfo > aggregates()
Structured information for available aggregates.
QVariant calculate(Qgis::Aggregate aggregate, const QString &fieldOrExpression, QgsExpressionContext *context=nullptr, bool *ok=nullptr, QgsFeedback *feedback=nullptr) const
Calculates the value of an aggregate.
QString delimiter() const
Returns the delimiter used for joining values with the StringConcatenate aggregate.
static QString displayName(Qgis::Aggregate aggregate)
Returns the friendly display name for a aggregate.
static Qgis::Aggregate stringToAggregate(const QString &string, bool *ok=nullptr)
Converts a string to a aggregate type.
QgsAggregateCalculator(const QgsVectorLayer *layer)
Constructor for QgsAggregateCalculator.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
static std::tuple< QMetaType::Type, int > determineResultType(const QString &expression, const QgsVectorLayer *layer, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsExpressionContext &context=QgsExpressionContext(), bool *foundFeatures=nullptr)
Returns a value type and user type for a given expression.
Handles parsing and evaluation of expressions (formerly called "search strings").
static int expressionToLayerFieldIndex(const QString &expression, const QgsVectorLayer *layer)
Attempts to resolve an expression to a field index from the given layer.
QVariant evaluate()
Evaluate the feature and return the result.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
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...
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setOrderBy(const OrderBy &orderBy)
Set a list of order by clauses.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
A geometry is the spatial representation of a feature.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
Represents a vector layer which manages a vector based dataset.
QSet< QgsFeatureId > QgsFeatureIds
Structured information about the available aggregates.
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.