QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgsaggregatecalculator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsaggregatecalculator.cpp
3 --------------------------
4 begin : May 2016
5 copyright : (C) 2016 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include <memory>
21
23#include "qgsexpressionutils.h"
24#include "qgsfeature.h"
25#include "qgsfeatureiterator.h"
26#include "qgsfeaturerequest.h"
27#include "qgsgeometry.h"
30#include "qgsvectorlayer.h"
31
32#include <QString>
33
34using namespace Qt::StringLiterals;
35
39
41{
42 return mLayer;
43}
44
46{
47 mFilterExpression = parameters.filter;
48 mDelimiter = parameters.delimiter;
49 mOrderBy = parameters.orderBy;
50}
51
53{
54 mFidsSet = true;
55 mFidsFilter = fids;
56}
57
58QVariant QgsAggregateCalculator::calculate( Qgis::Aggregate aggregate, const QString &fieldOrExpression, QgsExpressionContext *context, bool *ok, QgsFeedback *feedback ) const
59{
60 mLastError.clear();
61 if ( ok )
62 *ok = false;
63
65
66 if ( !mLayer )
67 return QVariant();
68
69 QgsExpressionContext defaultContext = mLayer->createExpressionContext();
70 context = context ? context : &defaultContext;
71
72 std::unique_ptr<QgsExpression> expression;
73
74 const int attrNum = QgsExpression::expressionToLayerFieldIndex( fieldOrExpression, mLayer );
75 if ( attrNum == -1 )
76 {
77 Q_ASSERT( context );
78 context->setFields( mLayer->fields() );
79 // try to use expression
80 expression = std::make_unique<QgsExpression>( fieldOrExpression );
81
82 if ( expression->hasParserError() || !expression->prepare( context ) )
83 {
84 mLastError = !expression->parserErrorString().isEmpty() ? expression->parserErrorString() : expression->evalErrorString();
85 return QVariant();
86 }
87 }
88
89 QSet<QString> lst;
90 if ( !expression )
91 lst.insert( mLayer->fields().at( attrNum ).name() );
92 else
93 lst = expression->referencedColumns();
94
95 bool expressionNeedsGeometry { expression && expression->needsGeometry() };
96
97 if ( !mOrderBy.empty() )
98 {
99 request.setOrderBy( mOrderBy );
100 for ( const QgsFeatureRequest::OrderByClause &orderBy : std::as_const( mOrderBy ) )
101 {
102 if ( orderBy.expression().needsGeometry() )
103 {
104 expressionNeedsGeometry = true;
105 break;
106 }
107 }
108 }
109
110 request.setFlags( expressionNeedsGeometry ? Qgis::FeatureRequestFlag::NoFlags : Qgis::FeatureRequestFlag::NoGeometry ).setSubsetOfAttributes( lst, mLayer->fields() );
111
112 if ( mFidsSet )
113 request.setFilterFids( mFidsFilter );
114
115 if ( !mFilterExpression.isEmpty() )
116 request.setFilterExpression( mFilterExpression );
117 if ( context )
118 request.setExpressionContext( *context );
119
120 request.setFeedback( feedback ? feedback : context->feedback() );
121
122 //determine result type
123 QMetaType::Type resultType = QMetaType::Type::Double;
124 if ( attrNum == -1 )
125 {
126 if ( aggregate == Qgis::Aggregate::GeometryCollect )
127 {
128 // in this case we know the result should be a geometry value, so no need to sniff it out...
129 resultType = QMetaType::Type::User;
130 }
131 else
132 {
133 // check expression result type
134 bool foundFeatures = false;
135 std::tuple<QMetaType::Type, int> returnType = QgsExpressionUtils::determineResultType( fieldOrExpression, mLayer, request, *context, &foundFeatures );
136 if ( !foundFeatures )
137 {
138 if ( ok )
139 *ok = true;
140 return defaultValue( aggregate );
141 }
142
143 resultType = std::get<0>( returnType );
144 if ( resultType == QMetaType::Type::UnknownType )
145 {
146 QVariant v;
147 switch ( aggregate )
148 {
149 // string
154 v = QString();
155 break;
156
157 // numerical
167 // mixed type, fallback to numerical
175 v = 0.0;
176 break;
177
178 // geometry
180 v = QgsGeometry();
181 break;
182
183 // list, fallback to string
185 v = QString();
186 break;
187 }
188 resultType = static_cast<QMetaType::Type>( v.userType() );
189 }
190 }
191 }
192 else
193 resultType = mLayer->fields().at( attrNum ).type();
194
195 QgsFeatureIterator fit = mLayer->getFeatures( request );
196 return calculate( aggregate, fit, resultType, attrNum, expression.get(), mDelimiter, context, ok, &mLastError );
197}
198
200{
201 const QString normalized = string.trimmed().toLower();
202
203 if ( ok )
204 *ok = true;
205
206 if ( normalized == "count"_L1 )
208 else if ( normalized == "count_distinct"_L1 )
210 else if ( normalized == "count_missing"_L1 )
212 else if ( normalized == "min"_L1 || normalized == "minimum"_L1 )
214 else if ( normalized == "max"_L1 || normalized == "maximum"_L1 )
216 else if ( normalized == "sum"_L1 )
218 else if ( normalized == "mean"_L1 )
220 else if ( normalized == "median"_L1 )
222 else if ( normalized == "stdev"_L1 )
224 else if ( normalized == "stdevsample"_L1 )
226 else if ( normalized == "range"_L1 )
228 else if ( normalized == "minority"_L1 )
230 else if ( normalized == "majority"_L1 )
232 else if ( normalized == "q1"_L1 )
234 else if ( normalized == "q3"_L1 )
236 else if ( normalized == "iqr"_L1 )
238 else if ( normalized == "min_length"_L1 )
240 else if ( normalized == "max_length"_L1 )
242 else if ( normalized == "concatenate"_L1 )
244 else if ( normalized == "concatenate_unique"_L1 )
246 else if ( normalized == "collect"_L1 )
248 else if ( normalized == "array_agg"_L1 )
250
251 if ( ok )
252 *ok = false;
253
255}
256
258{
259 switch ( aggregate )
260 {
262 return QObject::tr( "count" );
264 return QObject::tr( "count distinct" );
266 return QObject::tr( "count missing" );
268 return QObject::tr( "minimum" );
270 return QObject::tr( "maximum" );
272 return QObject::tr( "sum" );
274 return QObject::tr( "mean" );
276 return QObject::tr( "median" );
278 return QObject::tr( "standard deviation" );
280 return QObject::tr( "standard deviation (sample)" );
282 return QObject::tr( "range" );
284 return QObject::tr( "minority" );
286 return QObject::tr( "majority" );
288 return QObject::tr( "first quartile" );
290 return QObject::tr( "third quartile" );
292 return QObject::tr( "inter quartile range" );
294 return QObject::tr( "minimum length" );
296 return QObject::tr( "maximum length" );
298 return QObject::tr( "concatenate" );
300 return QObject::tr( "collection" );
302 return QObject::tr( "array aggregate" );
304 return QObject::tr( "concatenate (unique)" );
305 }
306 return QString();
307}
308
309QList<QgsAggregateCalculator::AggregateInfo> QgsAggregateCalculator::aggregates()
310{
311 QList< AggregateInfo > aggregates;
313 << AggregateInfo { u"count"_s, QCoreApplication::tr( "Count" ), QSet<QMetaType::Type>() << QMetaType::Type::QDateTime << QMetaType::Type::QDate << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::QString }
314 << AggregateInfo { u"count_distinct"_s, QCoreApplication::tr( "Count Distinct" ), QSet<QMetaType::Type>() << QMetaType::Type::QDateTime << QMetaType::Type::QDate << QMetaType::Type::UInt << QMetaType::Type::Int << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::QString }
315 << AggregateInfo { u"count_missing"_s, QCoreApplication::tr( "Count Missing" ), QSet<QMetaType::Type>() << QMetaType::Type::QDateTime << QMetaType::Type::QDate << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::QString }
316 << AggregateInfo { u"min"_s, QCoreApplication::tr( "Min" ), QSet<QMetaType::Type>() << QMetaType::Type::QDateTime << QMetaType::Type::QDate << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double << QMetaType::Type::QString }
317 << AggregateInfo { u"max"_s, QCoreApplication::tr( "Max" ), QSet<QMetaType::Type>() << QMetaType::Type::QDateTime << QMetaType::Type::QDate << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double << QMetaType::Type::QString }
318 << AggregateInfo { u"sum"_s, QCoreApplication::tr( "Sum" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
319 << AggregateInfo { u"mean"_s, QCoreApplication::tr( "Mean" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
320 << AggregateInfo { u"median"_s, QCoreApplication::tr( "Median" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::Double }
321 << AggregateInfo { u"stdev"_s, QCoreApplication::tr( "Stdev" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
322 << AggregateInfo { u"stdevsample"_s, QCoreApplication::tr( "Stdev Sample" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
323 << AggregateInfo { u"range"_s, QCoreApplication::tr( "Range" ), QSet<QMetaType::Type>() << QMetaType::Type::QDate << QMetaType::Type::QDateTime << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
324 << AggregateInfo { u"minority"_s, QCoreApplication::tr( "Minority" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double << QMetaType::Type::QString }
325 << AggregateInfo { u"majority"_s, QCoreApplication::tr( "Majority" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double << QMetaType::Type::QString }
326 << AggregateInfo { u"q1"_s, QCoreApplication::tr( "Q1" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
327 << AggregateInfo { u"q3"_s, QCoreApplication::tr( "Q3" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
328 << AggregateInfo { u"iqr"_s, QCoreApplication::tr( "InterQuartileRange" ), QSet<QMetaType::Type>() << QMetaType::Type::Int << QMetaType::Type::UInt << QMetaType::Type::LongLong << QMetaType::Type::ULongLong << QMetaType::Type::Double }
329 << AggregateInfo { u"min_length"_s, QCoreApplication::tr( "Min Length" ), QSet<QMetaType::Type>() << QMetaType::Type::QString }
330 << AggregateInfo { u"max_length"_s, QCoreApplication::tr( "Max Length" ), QSet<QMetaType::Type>() << QMetaType::Type::QString }
331 << AggregateInfo { u"concatenate"_s, QCoreApplication::tr( "Concatenate" ), QSet<QMetaType::Type>() << QMetaType::Type::QString }
332 << AggregateInfo { u"collect"_s, QCoreApplication::tr( "Collect" ), QSet<QMetaType::Type>() }
333 << AggregateInfo { u"array_agg"_s, QCoreApplication::tr( "Array Aggregate" ), QSet<QMetaType::Type>() };
334
335 return aggregates;
336}
337
339 Qgis::Aggregate aggregate, QgsFeatureIterator &fit, QMetaType::Type resultType, int attr, QgsExpression *expression, const QString &delimiter, QgsExpressionContext *context, bool *ok, QString *error
340)
341{
342 if ( ok )
343 *ok = false;
344
345 if ( aggregate == Qgis::Aggregate::ArrayAggregate )
346 {
347 if ( ok )
348 *ok = true;
349 return calculateArrayAggregate( fit, attr, expression, context );
350 }
351
352 switch ( resultType )
353 {
354 case QMetaType::Type::Int:
355 case QMetaType::Type::UInt:
356 case QMetaType::Type::LongLong:
357 case QMetaType::Type::ULongLong:
358 case QMetaType::Type::Double:
359 {
360 bool statOk = false;
361 const Qgis::Statistic stat = numericStatFromAggregate( aggregate, &statOk );
362 if ( !statOk )
363 {
364 if ( error )
365 *error = expression ? QObject::tr( "Cannot calculate %1 on numeric values" ).arg( displayName( aggregate ) )
366 : QObject::tr( "Cannot calculate %1 on numeric fields" ).arg( displayName( aggregate ) );
367 return QVariant();
368 }
369
370 if ( ok )
371 *ok = true;
372 return calculateNumericAggregate( fit, attr, expression, context, stat );
373 }
374
375 case QMetaType::Type::QDate:
376 case QMetaType::Type::QDateTime:
377 {
378 bool statOk = false;
379 const Qgis::DateTimeStatistic stat = dateTimeStatFromAggregate( aggregate, &statOk );
380 if ( !statOk )
381 {
382 if ( error )
383 *error = ( expression ? QObject::tr( "Cannot calculate %1 on %2 values" ).arg( displayName( aggregate ) ) : QObject::tr( "Cannot calculate %1 on %2 fields" ).arg( displayName( aggregate ) ) )
384 .arg( resultType == QMetaType::Type::QDate ? QObject::tr( "date" ) : QObject::tr( "datetime" ) );
385 return QVariant();
386 }
387
388 if ( ok )
389 *ok = true;
390 return calculateDateTimeAggregate( fit, attr, expression, context, stat );
391 }
392
393 case QMetaType::Type::User:
394 {
395 if ( aggregate == Qgis::Aggregate::GeometryCollect )
396 {
397 if ( ok )
398 *ok = true;
399 return calculateGeometryAggregate( fit, expression, context );
400 }
401 else
402 {
403 return QVariant();
404 }
405 }
406
407 default:
408 {
409 // treat as string
410 if ( aggregate == Qgis::Aggregate::StringConcatenate )
411 {
412 //special case
413 if ( ok )
414 *ok = true;
415 return concatenateStrings( fit, attr, expression, context, delimiter );
416 }
417 else if ( aggregate == Qgis::Aggregate::StringConcatenateUnique )
418 {
419 //special case
420 if ( ok )
421 *ok = true;
422 return concatenateStrings( fit, attr, expression, context, delimiter, true );
423 }
424
425 bool statOk = false;
426 const Qgis::StringStatistic stat = stringStatFromAggregate( aggregate, &statOk );
427 if ( !statOk )
428 {
429 QString typeString;
430 if ( resultType == QMetaType::Type::UnknownType )
431 typeString = QObject::tr( "null" );
432 else
433 typeString = resultType == QMetaType::Type::QString ? QObject::tr( "string" ) : QVariant::typeToName( resultType );
434
435 if ( error )
436 *error = expression ? QObject::tr( "Cannot calculate %1 on %3 values" ).arg( displayName( aggregate ), typeString )
437 : QObject::tr( "Cannot calculate %1 on %3 fields" ).arg( displayName( aggregate ), typeString );
438 return QVariant();
439 }
440
441 if ( ok )
442 *ok = true;
443 return calculateStringAggregate( fit, attr, expression, context, stat );
444 }
445 }
446
447#ifndef _MSC_VER
448 return QVariant();
449#endif
450}
451
452Qgis::Statistic QgsAggregateCalculator::numericStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
453{
454 if ( ok )
455 *ok = true;
456
457 switch ( aggregate )
458 {
497 {
498 if ( ok )
499 *ok = false;
501 }
502 }
503
504 if ( ok )
505 *ok = false;
507}
508
509Qgis::StringStatistic QgsAggregateCalculator::stringStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
510{
511 if ( ok )
512 *ok = true;
513
514 switch ( aggregate )
515 {
534
548 {
549 if ( ok )
550 *ok = false;
552 }
553 }
554
555 if ( ok )
556 *ok = false;
558}
559
560Qgis::DateTimeStatistic QgsAggregateCalculator::dateTimeStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
561{
562 if ( ok )
563 *ok = true;
564
565 switch ( aggregate )
566 {
579
596 {
597 if ( ok )
598 *ok = false;
600 }
601 }
602
603 if ( ok )
604 *ok = false;
606}
607
608QVariant QgsAggregateCalculator::calculateNumericAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression, QgsExpressionContext *context, Qgis::Statistic stat )
609{
610 Q_ASSERT( expression || attr >= 0 );
611
612 QgsStatisticalSummary s( stat );
613 QgsFeature f;
614
615 while ( fit.nextFeature( f ) )
616 {
617 if ( expression )
618 {
619 Q_ASSERT( context );
620 context->setFeature( f );
621 const QVariant v = expression->evaluate( context );
622 s.addVariant( v );
623 }
624 else
625 {
626 s.addVariant( f.attribute( attr ) );
627 }
628 }
629 s.finalize();
630 const double val = s.statistic( stat );
631 return std::isnan( val ) ? QVariant() : val;
632}
633
634QVariant QgsAggregateCalculator::calculateStringAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression, QgsExpressionContext *context, Qgis::StringStatistic stat )
635{
636 Q_ASSERT( expression || attr >= 0 );
637
638 QgsStringStatisticalSummary s( stat );
639 QgsFeature f;
640
641 while ( fit.nextFeature( f ) )
642 {
643 if ( expression )
644 {
645 Q_ASSERT( context );
646 context->setFeature( f );
647 const QVariant v = expression->evaluate( context );
648 s.addValue( v );
649 }
650 else
651 {
652 s.addValue( f.attribute( attr ) );
653 }
654 }
655 s.finalize();
656 return s.statistic( stat );
657}
658
659QVariant QgsAggregateCalculator::calculateGeometryAggregate( QgsFeatureIterator &fit, QgsExpression *expression, QgsExpressionContext *context )
660{
661 Q_ASSERT( expression );
662
663 QgsFeature f;
664 QVector< QgsGeometry > geometries;
665 while ( fit.nextFeature( f ) )
666 {
667 Q_ASSERT( context );
668 context->setFeature( f );
669 const QVariant v = expression->evaluate( context );
670 if ( v.userType() == qMetaTypeId< QgsGeometry>() )
671 {
672 geometries << v.value<QgsGeometry>();
673 }
674 }
675
676 return QVariant::fromValue( QgsGeometry::collectGeometry( geometries ) );
677}
678
679QVariant QgsAggregateCalculator::concatenateStrings( QgsFeatureIterator &fit, int attr, QgsExpression *expression, QgsExpressionContext *context, const QString &delimiter, bool unique )
680{
681 Q_ASSERT( expression || attr >= 0 );
682
683 QgsFeature f;
684 QStringList results;
685 while ( fit.nextFeature( f ) )
686 {
687 QString result;
688 if ( expression )
689 {
690 Q_ASSERT( context );
691 context->setFeature( f );
692 const QVariant v = expression->evaluate( context );
693 result = v.toString();
694 }
695 else
696 {
697 result = f.attribute( attr ).toString();
698 }
699
700 if ( !unique || !results.contains( result ) )
701 results << result;
702 }
703
704 return results.join( delimiter );
705}
706
707QVariant QgsAggregateCalculator::defaultValue( Qgis::Aggregate aggregate ) const
708{
709 // value to return when NO features are aggregated:
710 switch ( aggregate )
711 {
712 // sensible values:
716 return 0;
717
720 return ""; // zero length string - not null!
721
723 return QVariantList(); // empty list
724
725 // undefined - nothing makes sense here
742 return QVariant();
743 }
744 return QVariant();
745}
746
747QVariant QgsAggregateCalculator::calculateDateTimeAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression, QgsExpressionContext *context, Qgis::DateTimeStatistic stat )
748{
749 Q_ASSERT( expression || attr >= 0 );
750
751 QgsDateTimeStatisticalSummary s( stat );
752 QgsFeature f;
753
754 while ( fit.nextFeature( f ) )
755 {
756 if ( expression )
757 {
758 Q_ASSERT( context );
759 context->setFeature( f );
760 const QVariant v = expression->evaluate( context );
761 s.addValue( v );
762 }
763 else
764 {
765 s.addValue( f.attribute( attr ) );
766 }
767 }
768 s.finalize();
769 return s.statistic( stat );
770}
771
772QVariant QgsAggregateCalculator::calculateArrayAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression, QgsExpressionContext *context )
773{
774 Q_ASSERT( expression || attr >= 0 );
775
776 QgsFeature f;
777
778 QVariantList array;
779
780 while ( fit.nextFeature( f ) )
781 {
782 if ( expression )
783 {
784 Q_ASSERT( context );
785 context->setFeature( f );
786 const QVariant v = expression->evaluate( context );
787 array.append( v );
788 }
789 else
790 {
791 array.append( f.attribute( attr ) );
792 }
793 }
794 return array;
795}
Statistic
Available generic statistics.
Definition qgis.h:6206
@ StDev
Standard deviation of values.
Definition qgis.h:6212
@ FirstQuartile
First quartile.
Definition qgis.h:6220
@ Mean
Mean of values.
Definition qgis.h:6210
@ Median
Median of values.
Definition qgis.h:6211
@ Max
Max of values.
Definition qgis.h:6215
@ Min
Min of values.
Definition qgis.h:6214
@ Range
Range of values (max - min).
Definition qgis.h:6216
@ Sum
Sum of values.
Definition qgis.h:6209
@ Minority
Minority of values.
Definition qgis.h:6217
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6208
@ Majority
Majority of values.
Definition qgis.h:6218
@ Variety
Variety (count of distinct) values.
Definition qgis.h:6219
@ StDevSample
Sample standard deviation of values.
Definition qgis.h:6213
@ Count
Count.
Definition qgis.h:6207
@ ThirdQuartile
Third quartile.
Definition qgis.h:6221
@ InterQuartileRange
Inter quartile range (IQR).
Definition qgis.h:6222
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2276
@ NoFlags
No flags are set.
Definition qgis.h:2275
StringStatistic
Available string statistics.
Definition qgis.h:6268
@ Max
Maximum string value.
Definition qgis.h:6273
@ Min
Minimum string value.
Definition qgis.h:6272
@ MaximumLength
Maximum length of string.
Definition qgis.h:6275
@ Minority
Minority of strings.
Definition qgis.h:6277
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6271
@ Majority
Majority of strings.
Definition qgis.h:6278
@ CountDistinct
Number of distinct string values.
Definition qgis.h:6270
@ MinimumLength
Minimum length of string.
Definition qgis.h:6274
Aggregate
Available aggregates to calculate.
Definition qgis.h:6174
@ StDev
Standard deviation of values (numeric fields only).
Definition qgis.h:6183
@ StringMinimumLength
Minimum length of string (string fields only).
Definition qgis.h:6191
@ FirstQuartile
First quartile (numeric fields only).
Definition qgis.h:6188
@ Mean
Mean of values (numeric fields only).
Definition qgis.h:6181
@ Median
Median of values (numeric fields only).
Definition qgis.h:6182
@ Max
Max of values.
Definition qgis.h:6179
@ Min
Min of values.
Definition qgis.h:6178
@ StringMaximumLength
Maximum length of string (string fields only).
Definition qgis.h:6192
@ Range
Range of values (max - min) (numeric and datetime fields only).
Definition qgis.h:6185
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
Definition qgis.h:6196
@ Sum
Sum of values.
Definition qgis.h:6180
@ Minority
Minority of values.
Definition qgis.h:6186
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6177
@ ArrayAggregate
Create an array of values.
Definition qgis.h:6195
@ Majority
Majority of values.
Definition qgis.h:6187
@ StDevSample
Sample standard deviation of values (numeric fields only).
Definition qgis.h:6184
@ Count
Count.
Definition qgis.h:6175
@ ThirdQuartile
Third quartile (numeric fields only).
Definition qgis.h:6189
@ CountDistinct
Number of distinct values.
Definition qgis.h:6176
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
Definition qgis.h:6193
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
Definition qgis.h:6194
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
Definition qgis.h:6190
DateTimeStatistic
Available date/time statistics.
Definition qgis.h:6243
@ Max
Maximum (latest) datetime value.
Definition qgis.h:6248
@ Min
Minimum (earliest) datetime value.
Definition qgis.h:6247
@ Range
Interval between earliest and latest datetime value.
Definition qgis.h:6249
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6246
@ CountDistinct
Number of distinct datetime values.
Definition qgis.h:6245
const QgsVectorLayer * layer() const
Returns the associated vector layer.
void setParameters(const AggregateParameters &parameters)
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.
Definition qgsfeedback.h:44
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.