QGIS API Documentation 3.99.0-Master (8e76e220402)
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
41
43{
44 return mLayer;
45}
46
48{
49 mFilterExpression = parameters.filter;
50 mDelimiter = parameters.delimiter;
51 mOrderBy = parameters.orderBy;
52}
53
55{
56 mFidsSet = true;
57 mFidsFilter = fids;
58}
59
61 const QString &fieldOrExpression, QgsExpressionContext *context, bool *ok, QgsFeedback *feedback ) const
62{
63 mLastError.clear();
64 if ( ok )
65 *ok = false;
66
68
69 if ( !mLayer )
70 return QVariant();
71
72 QgsExpressionContext defaultContext = mLayer->createExpressionContext();
73 context = context ? context : &defaultContext;
74
75 std::unique_ptr<QgsExpression> expression;
76
77 const int attrNum = QgsExpression::expressionToLayerFieldIndex( fieldOrExpression, mLayer );
78 if ( attrNum == -1 )
79 {
80 Q_ASSERT( context );
81 context->setFields( mLayer->fields() );
82 // try to use expression
83 expression = std::make_unique<QgsExpression>( fieldOrExpression );
84
85 if ( expression->hasParserError() || !expression->prepare( context ) )
86 {
87 mLastError = !expression->parserErrorString().isEmpty() ? expression->parserErrorString() : expression->evalErrorString();
88 return QVariant();
89 }
90 }
91
92 QSet<QString> lst;
93 if ( !expression )
94 lst.insert( mLayer->fields().at( attrNum ).name() );
95 else
96 lst = expression->referencedColumns();
97
98 bool expressionNeedsGeometry { expression &&expression->needsGeometry() };
99
100 if ( !mOrderBy.empty() )
101 {
102 request.setOrderBy( mOrderBy );
103 for ( const QgsFeatureRequest::OrderByClause &orderBy : std::as_const( mOrderBy ) )
104 {
105 if ( orderBy.expression().needsGeometry() )
106 {
107 expressionNeedsGeometry = true;
108 break;
109 }
110 }
111 }
112
113 request.setFlags( expressionNeedsGeometry ?
116 .setSubsetOfAttributes( lst, mLayer->fields() );
117
118 if ( mFidsSet )
119 request.setFilterFids( mFidsFilter );
120
121 if ( !mFilterExpression.isEmpty() )
122 request.setFilterExpression( mFilterExpression );
123 if ( context )
124 request.setExpressionContext( *context );
125
126 request.setFeedback( feedback ? feedback : context->feedback() );
127
128 //determine result type
129 QMetaType::Type resultType = QMetaType::Type::Double;
130 if ( attrNum == -1 )
131 {
132 if ( aggregate == Qgis::Aggregate::GeometryCollect )
133 {
134 // in this case we know the result should be a geometry value, so no need to sniff it out...
135 resultType = QMetaType::Type::User;
136 }
137 else
138 {
139 // check expression result type
140 bool foundFeatures = false;
141 std::tuple<QMetaType::Type, int> returnType = QgsExpressionUtils::determineResultType( fieldOrExpression, mLayer, request, *context, &foundFeatures );
142 if ( !foundFeatures )
143 {
144 if ( ok )
145 *ok = true;
146 return defaultValue( aggregate );
147 }
148
149 resultType = std::get<0>( returnType );
150 if ( resultType == QMetaType::Type::UnknownType )
151 {
152 QVariant v;
153 switch ( aggregate )
154 {
155 // string
160 v = QString();
161 break;
162
163 // numerical
173 // mixed type, fallback to numerical
181 v = 0.0;
182 break;
183
184 // geometry
186 v = QgsGeometry();
187 break;
188
189 // list, fallback to string
191 v = QString();
192 break;
193 }
194 resultType = static_cast<QMetaType::Type>( v.userType() );
195 }
196 }
197 }
198 else
199 resultType = mLayer->fields().at( attrNum ).type();
200
201 QgsFeatureIterator fit = mLayer->getFeatures( request );
202 return calculate( aggregate, fit, resultType, attrNum, expression.get(), mDelimiter, context, ok, &mLastError );
203}
204
206{
207 const QString normalized = string.trimmed().toLower();
208
209 if ( ok )
210 *ok = true;
211
212 if ( normalized == "count"_L1 )
214 else if ( normalized == "count_distinct"_L1 )
216 else if ( normalized == "count_missing"_L1 )
218 else if ( normalized == "min"_L1 || normalized == "minimum"_L1 )
220 else if ( normalized == "max"_L1 || normalized == "maximum"_L1 )
222 else if ( normalized == "sum"_L1 )
224 else if ( normalized == "mean"_L1 )
226 else if ( normalized == "median"_L1 )
228 else if ( normalized == "stdev"_L1 )
230 else if ( normalized == "stdevsample"_L1 )
232 else if ( normalized == "range"_L1 )
234 else if ( normalized == "minority"_L1 )
236 else if ( normalized == "majority"_L1 )
238 else if ( normalized == "q1"_L1 )
240 else if ( normalized == "q3"_L1 )
242 else if ( normalized == "iqr"_L1 )
244 else if ( normalized == "min_length"_L1 )
246 else if ( normalized == "max_length"_L1 )
248 else if ( normalized == "concatenate"_L1 )
250 else if ( normalized == "concatenate_unique"_L1 )
252 else if ( normalized == "collect"_L1 )
254 else if ( normalized == "array_agg"_L1 )
256
257 if ( ok )
258 *ok = false;
259
261}
262
264{
265 switch ( aggregate )
266 {
268 return QObject::tr( "count" );
270 return QObject::tr( "count distinct" );
272 return QObject::tr( "count missing" );
274 return QObject::tr( "minimum" );
276 return QObject::tr( "maximum" );
278 return QObject::tr( "sum" );
280 return QObject::tr( "mean" );
282 return QObject::tr( "median" );
284 return QObject::tr( "standard deviation" );
286 return QObject::tr( "standard deviation (sample)" );
288 return QObject::tr( "range" );
290 return QObject::tr( "minority" );
292 return QObject::tr( "majority" );
294 return QObject::tr( "first quartile" );
296 return QObject::tr( "third quartile" );
298 return QObject::tr( "inter quartile range" );
300 return QObject::tr( "minimum length" );
302 return QObject::tr( "maximum length" );
304 return QObject::tr( "concatenate" );
306 return QObject::tr( "collection" );
308 return QObject::tr( "array aggregate" );
310 return QObject::tr( "concatenate (unique)" );
311 }
312 return QString();
313}
314
315QList<QgsAggregateCalculator::AggregateInfo> QgsAggregateCalculator::aggregates()
316{
317 QList< AggregateInfo > aggregates;
320 {
321 u"count"_s,
322 QCoreApplication::tr( "Count" ),
323 QSet<QMetaType::Type>()
324 << QMetaType::Type::QDateTime
325 << QMetaType::Type::QDate
326 << QMetaType::Type::Int
327 << QMetaType::Type::UInt
328 << QMetaType::Type::LongLong
329 << QMetaType::Type::ULongLong
330 << QMetaType::Type::QString
331 }
333 {
334 u"count_distinct"_s,
335 QCoreApplication::tr( "Count Distinct" ),
336 QSet<QMetaType::Type>()
337 << QMetaType::Type::QDateTime
338 << QMetaType::Type::QDate
339 << QMetaType::Type::UInt
340 << QMetaType::Type::Int
341 << QMetaType::Type::LongLong
342 << QMetaType::Type::ULongLong
343 << QMetaType::Type::QString
344 }
346 {
347 u"count_missing"_s,
348 QCoreApplication::tr( "Count Missing" ),
349 QSet<QMetaType::Type>()
350 << QMetaType::Type::QDateTime
351 << QMetaType::Type::QDate
352 << QMetaType::Type::Int
353 << QMetaType::Type::UInt
354 << QMetaType::Type::LongLong
355 << QMetaType::Type::QString
356 }
358 {
359 u"min"_s,
360 QCoreApplication::tr( "Min" ),
361 QSet<QMetaType::Type>()
362 << QMetaType::Type::QDateTime
363 << QMetaType::Type::QDate
364 << QMetaType::Type::Int
365 << QMetaType::Type::UInt
366 << QMetaType::Type::LongLong
367 << QMetaType::Type::ULongLong
368 << QMetaType::Type::Double
369 << QMetaType::Type::QString
370 }
372 {
373 u"max"_s,
374 QCoreApplication::tr( "Max" ),
375 QSet<QMetaType::Type>()
376 << QMetaType::Type::QDateTime
377 << QMetaType::Type::QDate
378 << QMetaType::Type::Int
379 << QMetaType::Type::UInt
380 << QMetaType::Type::LongLong
381 << QMetaType::Type::ULongLong
382 << QMetaType::Type::Double
383 << QMetaType::Type::QString
384 }
386 {
387 u"sum"_s,
388 QCoreApplication::tr( "Sum" ),
389 QSet<QMetaType::Type>()
390 << QMetaType::Type::Int
391 << QMetaType::Type::UInt
392 << QMetaType::Type::LongLong
393 << QMetaType::Type::ULongLong
394 << QMetaType::Type::Double
395 }
397 {
398 u"mean"_s,
399 QCoreApplication::tr( "Mean" ),
400 QSet<QMetaType::Type>()
401 << QMetaType::Type::Int
402 << QMetaType::Type::UInt
403 << QMetaType::Type::LongLong
404 << QMetaType::Type::ULongLong
405 << QMetaType::Type::Double
406 }
408 {
409 u"median"_s,
410 QCoreApplication::tr( "Median" ),
411 QSet<QMetaType::Type>()
412 << QMetaType::Type::Int
413 << QMetaType::Type::UInt
414 << QMetaType::Type::Double
415 }
417 {
418 u"stdev"_s,
419 QCoreApplication::tr( "Stdev" ),
420 QSet<QMetaType::Type>()
421 << QMetaType::Type::Int
422 << QMetaType::Type::UInt
423 << QMetaType::Type::LongLong
424 << QMetaType::Type::ULongLong
425 << QMetaType::Type::Double
426 }
428 {
429 u"stdevsample"_s,
430 QCoreApplication::tr( "Stdev Sample" ),
431 QSet<QMetaType::Type>()
432 << QMetaType::Type::Int
433 << QMetaType::Type::UInt
434 << QMetaType::Type::LongLong
435 << QMetaType::Type::ULongLong
436 << QMetaType::Type::Double
437 }
439 {
440 u"range"_s,
441 QCoreApplication::tr( "Range" ),
442 QSet<QMetaType::Type>()
443 << QMetaType::Type::QDate
444 << QMetaType::Type::QDateTime
445 << QMetaType::Type::Int
446 << QMetaType::Type::UInt
447 << QMetaType::Type::LongLong
448 << QMetaType::Type::ULongLong
449 << QMetaType::Type::Double
450 }
452 {
453 u"minority"_s,
454 QCoreApplication::tr( "Minority" ),
455 QSet<QMetaType::Type>()
456 << QMetaType::Type::Int
457 << QMetaType::Type::UInt
458 << QMetaType::Type::LongLong
459 << QMetaType::Type::ULongLong
460 << QMetaType::Type::Double
461 << QMetaType::Type::QString
462 }
464 {
465 u"majority"_s,
466 QCoreApplication::tr( "Majority" ),
467 QSet<QMetaType::Type>()
468 << QMetaType::Type::Int
469 << QMetaType::Type::UInt
470 << QMetaType::Type::LongLong
471 << QMetaType::Type::ULongLong
472 << QMetaType::Type::Double
473 << QMetaType::Type::QString
474 }
476 {
477 u"q1"_s,
478 QCoreApplication::tr( "Q1" ),
479 QSet<QMetaType::Type>()
480 << QMetaType::Type::Int
481 << QMetaType::Type::UInt
482 << QMetaType::Type::LongLong
483 << QMetaType::Type::ULongLong
484 << QMetaType::Type::Double
485 }
487 {
488 u"q3"_s,
489 QCoreApplication::tr( "Q3" ),
490 QSet<QMetaType::Type>()
491 << QMetaType::Type::Int
492 << QMetaType::Type::UInt
493 << QMetaType::Type::LongLong
494 << QMetaType::Type::ULongLong
495 << QMetaType::Type::Double
496 }
498 {
499 u"iqr"_s,
500 QCoreApplication::tr( "InterQuartileRange" ),
501 QSet<QMetaType::Type>()
502 << QMetaType::Type::Int
503 << QMetaType::Type::UInt
504 << QMetaType::Type::LongLong
505 << QMetaType::Type::ULongLong
506 << QMetaType::Type::Double
507 }
509 {
510 u"min_length"_s,
511 QCoreApplication::tr( "Min Length" ),
512 QSet<QMetaType::Type>()
513 << QMetaType::Type::QString
514 }
516 {
517 u"max_length"_s,
518 QCoreApplication::tr( "Max Length" ),
519 QSet<QMetaType::Type>()
520 << QMetaType::Type::QString
521 }
523 {
524 u"concatenate"_s,
525 QCoreApplication::tr( "Concatenate" ),
526 QSet<QMetaType::Type>()
527 << QMetaType::Type::QString
528 }
530 {
531 u"collect"_s,
532 QCoreApplication::tr( "Collect" ),
533 QSet<QMetaType::Type>()
534 }
536 {
537 u"array_agg"_s,
538 QCoreApplication::tr( "Array Aggregate" ),
539 QSet<QMetaType::Type>()
540 };
541
542 return aggregates;
543}
544
545QVariant QgsAggregateCalculator::calculate( Qgis::Aggregate aggregate, QgsFeatureIterator &fit, QMetaType::Type resultType,
546 int attr, QgsExpression *expression, const QString &delimiter, QgsExpressionContext *context, bool *ok, QString *error )
547{
548 if ( ok )
549 *ok = false;
550
551 if ( aggregate == Qgis::Aggregate::ArrayAggregate )
552 {
553 if ( ok )
554 *ok = true;
555 return calculateArrayAggregate( fit, attr, expression, context );
556 }
557
558 switch ( resultType )
559 {
560 case QMetaType::Type::Int:
561 case QMetaType::Type::UInt:
562 case QMetaType::Type::LongLong:
563 case QMetaType::Type::ULongLong:
564 case QMetaType::Type::Double:
565 {
566 bool statOk = false;
567 const Qgis::Statistic stat = numericStatFromAggregate( aggregate, &statOk );
568 if ( !statOk )
569 {
570 if ( error )
571 *error = expression ? QObject::tr( "Cannot calculate %1 on numeric values" ).arg( displayName( aggregate ) )
572 : QObject::tr( "Cannot calculate %1 on numeric fields" ).arg( displayName( aggregate ) );
573 return QVariant();
574 }
575
576 if ( ok )
577 *ok = true;
578 return calculateNumericAggregate( fit, attr, expression, context, stat );
579 }
580
581 case QMetaType::Type::QDate:
582 case QMetaType::Type::QDateTime:
583 {
584 bool statOk = false;
585 const Qgis::DateTimeStatistic stat = dateTimeStatFromAggregate( aggregate, &statOk );
586 if ( !statOk )
587 {
588 if ( error )
589 *error = ( expression ? QObject::tr( "Cannot calculate %1 on %2 values" ).arg( displayName( aggregate ) ) :
590 QObject::tr( "Cannot calculate %1 on %2 fields" ).arg( displayName( aggregate ) ) ).arg( resultType == QMetaType::Type::QDate ? QObject::tr( "date" ) : QObject::tr( "datetime" ) );
591 return QVariant();
592 }
593
594 if ( ok )
595 *ok = true;
596 return calculateDateTimeAggregate( fit, attr, expression, context, stat );
597 }
598
599 case QMetaType::Type::User:
600 {
601 if ( aggregate == Qgis::Aggregate::GeometryCollect )
602 {
603 if ( ok )
604 *ok = true;
605 return calculateGeometryAggregate( fit, expression, context );
606 }
607 else
608 {
609 return QVariant();
610 }
611 }
612
613 default:
614 {
615 // treat as string
616 if ( aggregate == Qgis::Aggregate::StringConcatenate )
617 {
618 //special case
619 if ( ok )
620 *ok = true;
621 return concatenateStrings( fit, attr, expression, context, delimiter );
622 }
623 else if ( aggregate == Qgis::Aggregate::StringConcatenateUnique )
624 {
625 //special case
626 if ( ok )
627 *ok = true;
628 return concatenateStrings( fit, attr, expression, context, delimiter, true );
629 }
630
631 bool statOk = false;
632 const Qgis::StringStatistic stat = stringStatFromAggregate( aggregate, &statOk );
633 if ( !statOk )
634 {
635 QString typeString;
636 if ( resultType == QMetaType::Type::UnknownType )
637 typeString = QObject::tr( "null" );
638 else
639 typeString = resultType == QMetaType::Type::QString ? QObject::tr( "string" ) : QVariant::typeToName( resultType );
640
641 if ( error )
642 *error = expression ? QObject::tr( "Cannot calculate %1 on %3 values" ).arg( displayName( aggregate ), typeString )
643 : QObject::tr( "Cannot calculate %1 on %3 fields" ).arg( displayName( aggregate ), typeString );
644 return QVariant();
645 }
646
647 if ( ok )
648 *ok = true;
649 return calculateStringAggregate( fit, attr, expression, context, stat );
650 }
651 }
652
653#ifndef _MSC_VER
654 return QVariant();
655#endif
656}
657
658Qgis::Statistic QgsAggregateCalculator::numericStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
659{
660 if ( ok )
661 *ok = true;
662
663 switch ( aggregate )
664 {
703 {
704 if ( ok )
705 *ok = false;
707 }
708 }
709
710 if ( ok )
711 *ok = false;
713}
714
715Qgis::StringStatistic QgsAggregateCalculator::stringStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
716{
717 if ( ok )
718 *ok = true;
719
720 switch ( aggregate )
721 {
740
754 {
755 if ( ok )
756 *ok = false;
758 }
759 }
760
761 if ( ok )
762 *ok = false;
764}
765
766Qgis::DateTimeStatistic QgsAggregateCalculator::dateTimeStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
767{
768 if ( ok )
769 *ok = true;
770
771 switch ( aggregate )
772 {
785
802 {
803 if ( ok )
804 *ok = false;
806 }
807 }
808
809 if ( ok )
810 *ok = false;
812}
813
814QVariant QgsAggregateCalculator::calculateNumericAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
816{
817 Q_ASSERT( expression || attr >= 0 );
818
819 QgsStatisticalSummary s( stat );
820 QgsFeature f;
821
822 while ( fit.nextFeature( f ) )
823 {
824 if ( expression )
825 {
826 Q_ASSERT( context );
827 context->setFeature( f );
828 const QVariant v = expression->evaluate( context );
829 s.addVariant( v );
830 }
831 else
832 {
833 s.addVariant( f.attribute( attr ) );
834 }
835 }
836 s.finalize();
837 const double val = s.statistic( stat );
838 return std::isnan( val ) ? QVariant() : val;
839}
840
841QVariant QgsAggregateCalculator::calculateStringAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
843{
844 Q_ASSERT( expression || attr >= 0 );
845
846 QgsStringStatisticalSummary s( stat );
847 QgsFeature f;
848
849 while ( fit.nextFeature( f ) )
850 {
851 if ( expression )
852 {
853 Q_ASSERT( context );
854 context->setFeature( f );
855 const QVariant v = expression->evaluate( context );
856 s.addValue( v );
857 }
858 else
859 {
860 s.addValue( f.attribute( attr ) );
861 }
862 }
863 s.finalize();
864 return s.statistic( stat );
865}
866
867QVariant QgsAggregateCalculator::calculateGeometryAggregate( QgsFeatureIterator &fit, QgsExpression *expression, QgsExpressionContext *context )
868{
869 Q_ASSERT( expression );
870
871 QgsFeature f;
872 QVector< QgsGeometry > geometries;
873 while ( fit.nextFeature( f ) )
874 {
875 Q_ASSERT( context );
876 context->setFeature( f );
877 const QVariant v = expression->evaluate( context );
878 if ( v.userType() == qMetaTypeId< QgsGeometry>() )
879 {
880 geometries << v.value<QgsGeometry>();
881 }
882 }
883
884 return QVariant::fromValue( QgsGeometry::collectGeometry( geometries ) );
885}
886
887QVariant QgsAggregateCalculator::concatenateStrings( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
888 QgsExpressionContext *context, const QString &delimiter, bool unique )
889{
890 Q_ASSERT( expression || attr >= 0 );
891
892 QgsFeature f;
893 QStringList results;
894 while ( fit.nextFeature( f ) )
895 {
896 QString result;
897 if ( expression )
898 {
899 Q_ASSERT( context );
900 context->setFeature( f );
901 const QVariant v = expression->evaluate( context );
902 result = v.toString();
903 }
904 else
905 {
906 result = f.attribute( attr ).toString();
907 }
908
909 if ( !unique || !results.contains( result ) )
910 results << result;
911 }
912
913 return results.join( delimiter );
914}
915
916QVariant QgsAggregateCalculator::defaultValue( Qgis::Aggregate aggregate ) const
917{
918 // value to return when NO features are aggregated:
919 switch ( aggregate )
920 {
921 // sensible values:
925 return 0;
926
929 return ""; // zero length string - not null!
930
932 return QVariantList(); // empty list
933
934 // undefined - nothing makes sense here
951 return QVariant();
952 }
953 return QVariant();
954}
955
956QVariant QgsAggregateCalculator::calculateDateTimeAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
958{
959 Q_ASSERT( expression || attr >= 0 );
960
961 QgsDateTimeStatisticalSummary s( stat );
962 QgsFeature f;
963
964 while ( fit.nextFeature( f ) )
965 {
966 if ( expression )
967 {
968 Q_ASSERT( context );
969 context->setFeature( f );
970 const QVariant v = expression->evaluate( context );
971 s.addValue( v );
972 }
973 else
974 {
975 s.addValue( f.attribute( attr ) );
976 }
977 }
978 s.finalize();
979 return s.statistic( stat );
980}
981
982QVariant QgsAggregateCalculator::calculateArrayAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
983 QgsExpressionContext *context )
984{
985 Q_ASSERT( expression || attr >= 0 );
986
987 QgsFeature f;
988
989 QVariantList array;
990
991 while ( fit.nextFeature( f ) )
992 {
993 if ( expression )
994 {
995 Q_ASSERT( context );
996 context->setFeature( f );
997 const QVariant v = expression->evaluate( context );
998 array.append( v );
999 }
1000 else
1001 {
1002 array.append( f.attribute( attr ) );
1003 }
1004 }
1005 return array;
1006}
1007
Statistic
Available generic statistics.
Definition qgis.h:6149
@ StDev
Standard deviation of values.
Definition qgis.h:6155
@ FirstQuartile
First quartile.
Definition qgis.h:6163
@ Mean
Mean of values.
Definition qgis.h:6153
@ Median
Median of values.
Definition qgis.h:6154
@ Max
Max of values.
Definition qgis.h:6158
@ Min
Min of values.
Definition qgis.h:6157
@ Range
Range of values (max - min).
Definition qgis.h:6159
@ Sum
Sum of values.
Definition qgis.h:6152
@ Minority
Minority of values.
Definition qgis.h:6160
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6151
@ Majority
Majority of values.
Definition qgis.h:6161
@ Variety
Variety (count of distinct) values.
Definition qgis.h:6162
@ StDevSample
Sample standard deviation of values.
Definition qgis.h:6156
@ Count
Count.
Definition qgis.h:6150
@ ThirdQuartile
Third quartile.
Definition qgis.h:6164
@ InterQuartileRange
Inter quartile range (IQR).
Definition qgis.h:6165
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2254
@ NoFlags
No flags are set.
Definition qgis.h:2253
StringStatistic
Available string statistics.
Definition qgis.h:6211
@ Max
Maximum string value.
Definition qgis.h:6216
@ Min
Minimum string value.
Definition qgis.h:6215
@ MaximumLength
Maximum length of string.
Definition qgis.h:6218
@ Minority
Minority of strings.
Definition qgis.h:6220
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6214
@ Majority
Majority of strings.
Definition qgis.h:6221
@ CountDistinct
Number of distinct string values.
Definition qgis.h:6213
@ MinimumLength
Minimum length of string.
Definition qgis.h:6217
Aggregate
Available aggregates to calculate.
Definition qgis.h:6117
@ StDev
Standard deviation of values (numeric fields only).
Definition qgis.h:6126
@ StringMinimumLength
Minimum length of string (string fields only).
Definition qgis.h:6134
@ FirstQuartile
First quartile (numeric fields only).
Definition qgis.h:6131
@ Mean
Mean of values (numeric fields only).
Definition qgis.h:6124
@ Median
Median of values (numeric fields only).
Definition qgis.h:6125
@ Max
Max of values.
Definition qgis.h:6122
@ Min
Min of values.
Definition qgis.h:6121
@ StringMaximumLength
Maximum length of string (string fields only).
Definition qgis.h:6135
@ Range
Range of values (max - min) (numeric and datetime fields only).
Definition qgis.h:6128
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
Definition qgis.h:6139
@ Sum
Sum of values.
Definition qgis.h:6123
@ Minority
Minority of values.
Definition qgis.h:6129
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6120
@ ArrayAggregate
Create an array of values.
Definition qgis.h:6138
@ Majority
Majority of values.
Definition qgis.h:6130
@ StDevSample
Sample standard deviation of values (numeric fields only).
Definition qgis.h:6127
@ Count
Count.
Definition qgis.h:6118
@ ThirdQuartile
Third quartile (numeric fields only).
Definition qgis.h:6132
@ CountDistinct
Number of distinct values.
Definition qgis.h:6119
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
Definition qgis.h:6136
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
Definition qgis.h:6137
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
Definition qgis.h:6133
DateTimeStatistic
Available date/time statistics.
Definition qgis.h:6186
@ Max
Maximum (latest) datetime value.
Definition qgis.h:6191
@ Min
Minimum (earliest) datetime value.
Definition qgis.h:6190
@ Range
Interval between earliest and latest datetime value.
Definition qgis.h:6192
@ CountMissing
Number of missing (null) values.
Definition qgis.h:6189
@ CountDistinct
Number of distinct datetime values.
Definition qgis.h:6188
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.