QGIS API Documentation 3.99.0-Master (26c88405ac0)
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
37
39{
40 return mLayer;
41}
42
44{
45 mFilterExpression = parameters.filter;
46 mDelimiter = parameters.delimiter;
47 mOrderBy = parameters.orderBy;
48}
49
51{
52 mFidsSet = true;
53 mFidsFilter = fids;
54}
55
57 const QString &fieldOrExpression, QgsExpressionContext *context, bool *ok, QgsFeedback *feedback ) const
58{
59 mLastError.clear();
60 if ( ok )
61 *ok = false;
62
64
65 if ( !mLayer )
66 return QVariant();
67
68 QgsExpressionContext defaultContext = mLayer->createExpressionContext();
69 context = context ? context : &defaultContext;
70
71 std::unique_ptr<QgsExpression> expression;
72
73 const int attrNum = QgsExpression::expressionToLayerFieldIndex( fieldOrExpression, mLayer );
74 if ( attrNum == -1 )
75 {
76 Q_ASSERT( context );
77 context->setFields( mLayer->fields() );
78 // try to use expression
79 expression = std::make_unique<QgsExpression>( fieldOrExpression );
80
81 if ( expression->hasParserError() || !expression->prepare( context ) )
82 {
83 mLastError = !expression->parserErrorString().isEmpty() ? expression->parserErrorString() : expression->evalErrorString();
84 return QVariant();
85 }
86 }
87
88 QSet<QString> lst;
89 if ( !expression )
90 lst.insert( mLayer->fields().at( attrNum ).name() );
91 else
92 lst = expression->referencedColumns();
93
94 bool expressionNeedsGeometry { expression &&expression->needsGeometry() };
95
96 if ( !mOrderBy.empty() )
97 {
98 request.setOrderBy( mOrderBy );
99 for ( const QgsFeatureRequest::OrderByClause &orderBy : std::as_const( mOrderBy ) )
100 {
101 if ( orderBy.expression().needsGeometry() )
102 {
103 expressionNeedsGeometry = true;
104 break;
105 }
106 }
107 }
108
109 request.setFlags( expressionNeedsGeometry ?
112 .setSubsetOfAttributes( lst, mLayer->fields() );
113
114 if ( mFidsSet )
115 request.setFilterFids( mFidsFilter );
116
117 if ( !mFilterExpression.isEmpty() )
118 request.setFilterExpression( mFilterExpression );
119 if ( context )
120 request.setExpressionContext( *context );
121
122 request.setFeedback( feedback ? feedback : context->feedback() );
123
124 //determine result type
125 QMetaType::Type resultType = QMetaType::Type::Double;
126 if ( attrNum == -1 )
127 {
128 if ( aggregate == Qgis::Aggregate::GeometryCollect )
129 {
130 // in this case we know the result should be a geometry value, so no need to sniff it out...
131 resultType = QMetaType::Type::User;
132 }
133 else
134 {
135 // check expression result type
136 bool foundFeatures = false;
137 std::tuple<QMetaType::Type, int> returnType = QgsExpressionUtils::determineResultType( fieldOrExpression, mLayer, request, *context, &foundFeatures );
138 if ( !foundFeatures )
139 {
140 if ( ok )
141 *ok = true;
142 return defaultValue( aggregate );
143 }
144
145 resultType = std::get<0>( returnType );
146 if ( resultType == QMetaType::Type::UnknownType )
147 {
148 QVariant v;
149 switch ( aggregate )
150 {
151 // string
156 v = QString();
157 break;
158
159 // numerical
169 // mixed type, fallback to numerical
177 v = 0.0;
178 break;
179
180 // geometry
182 v = QgsGeometry();
183 break;
184
185 // list, fallback to string
187 v = QString();
188 break;
189 }
190 resultType = static_cast<QMetaType::Type>( v.userType() );
191 }
192 }
193 }
194 else
195 resultType = mLayer->fields().at( attrNum ).type();
196
197 QgsFeatureIterator fit = mLayer->getFeatures( request );
198 return calculate( aggregate, fit, resultType, attrNum, expression.get(), mDelimiter, context, ok, &mLastError );
199}
200
202{
203 const QString normalized = string.trimmed().toLower();
204
205 if ( ok )
206 *ok = true;
207
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" ) )
252
253 if ( ok )
254 *ok = false;
255
257}
258
260{
261 switch ( aggregate )
262 {
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)" );
307 }
308 return QString();
309}
310
311QList<QgsAggregateCalculator::AggregateInfo> QgsAggregateCalculator::aggregates()
312{
313 QList< AggregateInfo > aggregates;
316 {
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
327 }
329 {
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
340 }
342 {
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
352 }
354 {
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
366 }
368 {
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
380 }
382 {
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
391 }
393 {
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
402 }
404 {
405 QStringLiteral( "median" ),
406 QCoreApplication::tr( "Median" ),
407 QSet<QMetaType::Type>()
408 << QMetaType::Type::Int
409 << QMetaType::Type::UInt
410 << QMetaType::Type::Double
411 }
413 {
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
422 }
424 {
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
433 }
435 {
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
446 }
448 {
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
458 }
460 {
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
470 }
472 {
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
481 }
483 {
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
492 }
494 {
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
503 }
505 {
506 QStringLiteral( "min_length" ),
507 QCoreApplication::tr( "Min Length" ),
508 QSet<QMetaType::Type>()
509 << QMetaType::Type::QString
510 }
512 {
513 QStringLiteral( "max_length" ),
514 QCoreApplication::tr( "Max Length" ),
515 QSet<QMetaType::Type>()
516 << QMetaType::Type::QString
517 }
519 {
520 QStringLiteral( "concatenate" ),
521 QCoreApplication::tr( "Concatenate" ),
522 QSet<QMetaType::Type>()
523 << QMetaType::Type::QString
524 }
526 {
527 QStringLiteral( "collect" ),
528 QCoreApplication::tr( "Collect" ),
529 QSet<QMetaType::Type>()
530 }
532 {
533 QStringLiteral( "array_agg" ),
534 QCoreApplication::tr( "Array Aggregate" ),
535 QSet<QMetaType::Type>()
536 };
537
538 return aggregates;
539}
540
541QVariant QgsAggregateCalculator::calculate( Qgis::Aggregate aggregate, QgsFeatureIterator &fit, QMetaType::Type resultType,
542 int attr, QgsExpression *expression, const QString &delimiter, QgsExpressionContext *context, bool *ok, QString *error )
543{
544 if ( ok )
545 *ok = false;
546
547 if ( aggregate == Qgis::Aggregate::ArrayAggregate )
548 {
549 if ( ok )
550 *ok = true;
551 return calculateArrayAggregate( fit, attr, expression, context );
552 }
553
554 switch ( resultType )
555 {
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:
561 {
562 bool statOk = false;
563 const Qgis::Statistic stat = numericStatFromAggregate( aggregate, &statOk );
564 if ( !statOk )
565 {
566 if ( error )
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 ) );
569 return QVariant();
570 }
571
572 if ( ok )
573 *ok = true;
574 return calculateNumericAggregate( fit, attr, expression, context, stat );
575 }
576
577 case QMetaType::Type::QDate:
578 case QMetaType::Type::QDateTime:
579 {
580 bool statOk = false;
581 const Qgis::DateTimeStatistic stat = dateTimeStatFromAggregate( aggregate, &statOk );
582 if ( !statOk )
583 {
584 if ( error )
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" ) );
587 return QVariant();
588 }
589
590 if ( ok )
591 *ok = true;
592 return calculateDateTimeAggregate( fit, attr, expression, context, stat );
593 }
594
595 case QMetaType::Type::User:
596 {
597 if ( aggregate == Qgis::Aggregate::GeometryCollect )
598 {
599 if ( ok )
600 *ok = true;
601 return calculateGeometryAggregate( fit, expression, context );
602 }
603 else
604 {
605 return QVariant();
606 }
607 }
608
609 default:
610 {
611 // treat as string
612 if ( aggregate == Qgis::Aggregate::StringConcatenate )
613 {
614 //special case
615 if ( ok )
616 *ok = true;
617 return concatenateStrings( fit, attr, expression, context, delimiter );
618 }
619 else if ( aggregate == Qgis::Aggregate::StringConcatenateUnique )
620 {
621 //special case
622 if ( ok )
623 *ok = true;
624 return concatenateStrings( fit, attr, expression, context, delimiter, true );
625 }
626
627 bool statOk = false;
628 const Qgis::StringStatistic stat = stringStatFromAggregate( aggregate, &statOk );
629 if ( !statOk )
630 {
631 QString typeString;
632 if ( resultType == QMetaType::Type::UnknownType )
633 typeString = QObject::tr( "null" );
634 else
635 typeString = resultType == QMetaType::Type::QString ? QObject::tr( "string" ) : QVariant::typeToName( resultType );
636
637 if ( error )
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 );
640 return QVariant();
641 }
642
643 if ( ok )
644 *ok = true;
645 return calculateStringAggregate( fit, attr, expression, context, stat );
646 }
647 }
648
649#ifndef _MSC_VER
650 return QVariant();
651#endif
652}
653
654Qgis::Statistic QgsAggregateCalculator::numericStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
655{
656 if ( ok )
657 *ok = true;
658
659 switch ( aggregate )
660 {
699 {
700 if ( ok )
701 *ok = false;
703 }
704 }
705
706 if ( ok )
707 *ok = false;
709}
710
711Qgis::StringStatistic QgsAggregateCalculator::stringStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
712{
713 if ( ok )
714 *ok = true;
715
716 switch ( aggregate )
717 {
736
750 {
751 if ( ok )
752 *ok = false;
754 }
755 }
756
757 if ( ok )
758 *ok = false;
760}
761
762Qgis::DateTimeStatistic QgsAggregateCalculator::dateTimeStatFromAggregate( Qgis::Aggregate aggregate, bool *ok )
763{
764 if ( ok )
765 *ok = true;
766
767 switch ( aggregate )
768 {
781
798 {
799 if ( ok )
800 *ok = false;
802 }
803 }
804
805 if ( ok )
806 *ok = false;
808}
809
810QVariant QgsAggregateCalculator::calculateNumericAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
812{
813 Q_ASSERT( expression || attr >= 0 );
814
815 QgsStatisticalSummary s( stat );
816 QgsFeature f;
817
818 while ( fit.nextFeature( f ) )
819 {
820 if ( expression )
821 {
822 Q_ASSERT( context );
823 context->setFeature( f );
824 const QVariant v = expression->evaluate( context );
825 s.addVariant( v );
826 }
827 else
828 {
829 s.addVariant( f.attribute( attr ) );
830 }
831 }
832 s.finalize();
833 const double val = s.statistic( stat );
834 return std::isnan( val ) ? QVariant() : val;
835}
836
837QVariant QgsAggregateCalculator::calculateStringAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
839{
840 Q_ASSERT( expression || attr >= 0 );
841
842 QgsStringStatisticalSummary s( stat );
843 QgsFeature f;
844
845 while ( fit.nextFeature( f ) )
846 {
847 if ( expression )
848 {
849 Q_ASSERT( context );
850 context->setFeature( f );
851 const QVariant v = expression->evaluate( context );
852 s.addValue( v );
853 }
854 else
855 {
856 s.addValue( f.attribute( attr ) );
857 }
858 }
859 s.finalize();
860 return s.statistic( stat );
861}
862
863QVariant QgsAggregateCalculator::calculateGeometryAggregate( QgsFeatureIterator &fit, QgsExpression *expression, QgsExpressionContext *context )
864{
865 Q_ASSERT( expression );
866
867 QgsFeature f;
868 QVector< QgsGeometry > geometries;
869 while ( fit.nextFeature( f ) )
870 {
871 Q_ASSERT( context );
872 context->setFeature( f );
873 const QVariant v = expression->evaluate( context );
874 if ( v.userType() == qMetaTypeId< QgsGeometry>() )
875 {
876 geometries << v.value<QgsGeometry>();
877 }
878 }
879
880 return QVariant::fromValue( QgsGeometry::collectGeometry( geometries ) );
881}
882
883QVariant QgsAggregateCalculator::concatenateStrings( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
884 QgsExpressionContext *context, const QString &delimiter, bool unique )
885{
886 Q_ASSERT( expression || attr >= 0 );
887
888 QgsFeature f;
889 QStringList results;
890 while ( fit.nextFeature( f ) )
891 {
892 QString result;
893 if ( expression )
894 {
895 Q_ASSERT( context );
896 context->setFeature( f );
897 const QVariant v = expression->evaluate( context );
898 result = v.toString();
899 }
900 else
901 {
902 result = f.attribute( attr ).toString();
903 }
904
905 if ( !unique || !results.contains( result ) )
906 results << result;
907 }
908
909 return results.join( delimiter );
910}
911
912QVariant QgsAggregateCalculator::defaultValue( Qgis::Aggregate aggregate ) const
913{
914 // value to return when NO features are aggregated:
915 switch ( aggregate )
916 {
917 // sensible values:
921 return 0;
922
925 return ""; // zero length string - not null!
926
928 return QVariantList(); // empty list
929
930 // undefined - nothing makes sense here
947 return QVariant();
948 }
949 return QVariant();
950}
951
952QVariant QgsAggregateCalculator::calculateDateTimeAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
954{
955 Q_ASSERT( expression || attr >= 0 );
956
957 QgsDateTimeStatisticalSummary s( stat );
958 QgsFeature f;
959
960 while ( fit.nextFeature( f ) )
961 {
962 if ( expression )
963 {
964 Q_ASSERT( context );
965 context->setFeature( f );
966 const QVariant v = expression->evaluate( context );
967 s.addValue( v );
968 }
969 else
970 {
971 s.addValue( f.attribute( attr ) );
972 }
973 }
974 s.finalize();
975 return s.statistic( stat );
976}
977
978QVariant QgsAggregateCalculator::calculateArrayAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
979 QgsExpressionContext *context )
980{
981 Q_ASSERT( expression || attr >= 0 );
982
983 QgsFeature f;
984
985 QVariantList array;
986
987 while ( fit.nextFeature( f ) )
988 {
989 if ( expression )
990 {
991 Q_ASSERT( context );
992 context->setFeature( f );
993 const QVariant v = expression->evaluate( context );
994 array.append( v );
995 }
996 else
997 {
998 array.append( f.attribute( attr ) );
999 }
1000 }
1001 return array;
1002}
1003
Statistic
Available generic statistics.
Definition qgis.h:5848
@ StDev
Standard deviation of values.
Definition qgis.h:5854
@ FirstQuartile
First quartile.
Definition qgis.h:5862
@ Mean
Mean of values.
Definition qgis.h:5852
@ Median
Median of values.
Definition qgis.h:5853
@ Max
Max of values.
Definition qgis.h:5857
@ Min
Min of values.
Definition qgis.h:5856
@ Range
Range of values (max - min).
Definition qgis.h:5858
@ Sum
Sum of values.
Definition qgis.h:5851
@ Minority
Minority of values.
Definition qgis.h:5859
@ CountMissing
Number of missing (null) values.
Definition qgis.h:5850
@ Majority
Majority of values.
Definition qgis.h:5860
@ Variety
Variety (count of distinct) values.
Definition qgis.h:5861
@ StDevSample
Sample standard deviation of values.
Definition qgis.h:5855
@ Count
Count.
Definition qgis.h:5849
@ ThirdQuartile
Third quartile.
Definition qgis.h:5863
@ InterQuartileRange
Inter quartile range (IQR).
Definition qgis.h:5864
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2196
@ NoFlags
No flags are set.
Definition qgis.h:2195
StringStatistic
Available string statistics.
Definition qgis.h:5910
@ Max
Maximum string value.
Definition qgis.h:5915
@ Min
Minimum string value.
Definition qgis.h:5914
@ MaximumLength
Maximum length of string.
Definition qgis.h:5917
@ Minority
Minority of strings.
Definition qgis.h:5919
@ CountMissing
Number of missing (null) values.
Definition qgis.h:5913
@ Majority
Majority of strings.
Definition qgis.h:5920
@ CountDistinct
Number of distinct string values.
Definition qgis.h:5912
@ MinimumLength
Minimum length of string.
Definition qgis.h:5916
Aggregate
Available aggregates to calculate.
Definition qgis.h:5816
@ StDev
Standard deviation of values (numeric fields only).
Definition qgis.h:5825
@ StringMinimumLength
Minimum length of string (string fields only).
Definition qgis.h:5833
@ FirstQuartile
First quartile (numeric fields only).
Definition qgis.h:5830
@ Mean
Mean of values (numeric fields only).
Definition qgis.h:5823
@ Median
Median of values (numeric fields only).
Definition qgis.h:5824
@ Max
Max of values.
Definition qgis.h:5821
@ Min
Min of values.
Definition qgis.h:5820
@ StringMaximumLength
Maximum length of string (string fields only).
Definition qgis.h:5834
@ Range
Range of values (max - min) (numeric and datetime fields only).
Definition qgis.h:5827
@ StringConcatenateUnique
Concatenate unique values with a joining string (string fields only). Specify the delimiter using set...
Definition qgis.h:5838
@ Sum
Sum of values.
Definition qgis.h:5822
@ Minority
Minority of values.
Definition qgis.h:5828
@ CountMissing
Number of missing (null) values.
Definition qgis.h:5819
@ ArrayAggregate
Create an array of values.
Definition qgis.h:5837
@ Majority
Majority of values.
Definition qgis.h:5829
@ StDevSample
Sample standard deviation of values (numeric fields only).
Definition qgis.h:5826
@ Count
Count.
Definition qgis.h:5817
@ ThirdQuartile
Third quartile (numeric fields only).
Definition qgis.h:5831
@ CountDistinct
Number of distinct values.
Definition qgis.h:5818
@ StringConcatenate
Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimit...
Definition qgis.h:5835
@ GeometryCollect
Create a multipart geometry from aggregated geometries.
Definition qgis.h:5836
@ InterQuartileRange
Inter quartile range (IQR) (numeric fields only).
Definition qgis.h:5832
DateTimeStatistic
Available date/time statistics.
Definition qgis.h:5885
@ Max
Maximum (latest) datetime value.
Definition qgis.h:5890
@ Min
Minimum (earliest) datetime value.
Definition qgis.h:5889
@ Range
Interval between earliest and latest datetime value.
Definition qgis.h:5891
@ CountMissing
Number of missing (null) values.
Definition qgis.h:5888
@ CountDistinct
Number of distinct datetime values.
Definition qgis.h:5887
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.