Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsaggregatecalculator.h
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 : :
18 : : #ifndef QGSAGGREGATECALCULATOR_H
19 : : #define QGSAGGREGATECALCULATOR_H
20 : :
21 : : #include "qgis_core.h"
22 : : #include "qgsstatisticalsummary.h"
23 : : #include "qgsdatetimestatisticalsummary.h"
24 : : #include "qgsstringstatisticalsummary.h"
25 : : #include "qgsfeaturerequest.h"
26 : : #include <QVariant>
27 : : #include "qgsfeatureid.h"
28 : :
29 : :
30 : : class QgsFeatureIterator;
31 : : class QgsExpression;
32 : : class QgsVectorLayer;
33 : : class QgsExpressionContext;
34 : :
35 : : /**
36 : : * \ingroup core
37 : : * \class QgsAggregateCalculator
38 : : * \brief Utility class for calculating aggregates for a field (or expression) over the features
39 : : * from a vector layer. It is recommended that QgsVectorLayer::aggregate() is used rather then
40 : : * directly using this class, as the QgsVectorLayer method can handle delegating aggregate calculation
41 : : * to a data provider for remote calculation.
42 : : * \since QGIS 2.16
43 : : */
44 : 0 : class CORE_EXPORT QgsAggregateCalculator
45 : : {
46 : : public:
47 : :
48 : : /**
49 : : * Structured information about the available aggregates.
50 : : *
51 : : * \since QGIS 3.0
52 : : */
53 : 0 : struct AggregateInfo
54 : : {
55 : : QString function; //!< The expression function
56 : : QString name; //!< A translated, human readable name
57 : : QSet<QVariant::Type> supportedTypes; //!< This aggregate function can only be used with these datatypes
58 : : };
59 : :
60 : : /**
61 : : * Available aggregates to calculate. Not all aggregates are available for all field
62 : : * types.
63 : : */
64 : : enum Aggregate
65 : : {
66 : : Count, //!< Count
67 : : CountDistinct, //!< Number of distinct values
68 : : CountMissing, //!< Number of missing (null) values
69 : : Min, //!< Min of values
70 : : Max, //!< Max of values
71 : : Sum, //!< Sum of values
72 : : Mean, //!< Mean of values (numeric fields only)
73 : : Median, //!< Median of values (numeric fields only)
74 : : StDev, //!< Standard deviation of values (numeric fields only)
75 : : StDevSample, //!< Sample standard deviation of values (numeric fields only)
76 : : Range, //!< Range of values (max - min) (numeric and datetime fields only)
77 : : Minority, //!< Minority of values
78 : : Majority, //!< Majority of values
79 : : FirstQuartile, //!< First quartile (numeric fields only)
80 : : ThirdQuartile, //!< Third quartile (numeric fields only)
81 : : InterQuartileRange, //!< Inter quartile range (IQR) (numeric fields only)
82 : : StringMinimumLength, //!< Minimum length of string (string fields only)
83 : : StringMaximumLength, //!< Maximum length of string (string fields only)
84 : : StringConcatenate, //!< Concatenate values with a joining string (string fields only). Specify the delimiter using setDelimiter().
85 : : GeometryCollect, //!< Create a multipart geometry from aggregated geometries
86 : : ArrayAggregate, //!< Create an array of values
87 : : StringConcatenateUnique //!< Concatenate unique values with a joining string (string fields only). Specify the delimiter using setDelimiter().
88 : : };
89 : :
90 : : //! A bundle of parameters controlling aggregate calculation
91 : 0 : struct AggregateParameters
92 : : {
93 : :
94 : : /**
95 : : * Optional filter for calculating aggregate over a subset of features, or an
96 : : * empty string to use all features.
97 : : * \see QgsAggregateCalculator::setFilter()
98 : : * \see QgsAggregateCalculator::filter()
99 : : */
100 : : QString filter;
101 : :
102 : : /**
103 : : * Delimiter to use for joining values with the StringConcatenate aggregate.
104 : : * \see QgsAggregateCalculator::setDelimiter()
105 : : * \see QgsAggregateCalculator::delimiter()
106 : : */
107 : : QString delimiter;
108 : :
109 : : /**
110 : : * Optional order by clauses.
111 : : * \since QGIS 3.8
112 : : */
113 : : QgsFeatureRequest::OrderBy orderBy;
114 : : };
115 : :
116 : : /**
117 : : * Constructor for QgsAggregateCalculator.
118 : : * \param layer vector layer to calculate aggregate from
119 : : */
120 : : QgsAggregateCalculator( const QgsVectorLayer *layer );
121 : :
122 : : /**
123 : : * Returns the associated vector layer.
124 : : */
125 : : const QgsVectorLayer *layer() const;
126 : :
127 : : /**
128 : : * Sets all aggregate parameters from a parameter bundle.
129 : : * \param parameters aggregate parameters
130 : : */
131 : : void setParameters( const AggregateParameters ¶meters );
132 : :
133 : : /**
134 : : * Sets a filter to limit the features used during the aggregate calculation.
135 : : * \param filterExpression expression for filtering features, or empty string to remove filter
136 : : * \see filter()
137 : : */
138 : : void setFilter( const QString &filterExpression ) { mFilterExpression = filterExpression; }
139 : :
140 : : /**
141 : : * Sets a filter to limit the features used during the aggregate calculation.
142 : : * If an expression filter is set, it will override this filter.
143 : : * \param fids feature ids for feature filtering, and empty list will return no features.
144 : : * \see filter()
145 : : */
146 : : void setFidsFilter( const QgsFeatureIds &fids );
147 : :
148 : : /**
149 : : * Returns the filter which limits the features used during the aggregate calculation.
150 : : * \see setFilter()
151 : : */
152 : : QString filter() const { return mFilterExpression; }
153 : :
154 : : /**
155 : : * Sets the delimiter to use for joining values with the StringConcatenate aggregate.
156 : : * \param delimiter string delimiter
157 : : * \see delimiter()
158 : : */
159 : : void setDelimiter( const QString &delimiter ) { mDelimiter = delimiter; }
160 : :
161 : : /**
162 : : * Returns the delimiter used for joining values with the StringConcatenate aggregate.
163 : : * \see setDelimiter()
164 : : */
165 : : QString delimiter() const { return mDelimiter; }
166 : :
167 : : /**
168 : : * Calculates the value of an aggregate.
169 : : * \param aggregate aggregate to calculate
170 : : * \param fieldOrExpression source field or expression to use as basis for aggregated values.
171 : : * If an expression is used, then the context parameter must be set.
172 : : * \param context expression context for evaluating expressions
173 : : * \param ok if specified, will be set to TRUE if aggregate calculation was successful
174 : : * \returns calculated aggregate value
175 : : */
176 : : QVariant calculate( Aggregate aggregate, const QString &fieldOrExpression,
177 : : QgsExpressionContext *context = nullptr, bool *ok = nullptr ) const;
178 : :
179 : : /**
180 : : * Converts a string to a aggregate type.
181 : : * \param string string to convert
182 : : * \param ok if specified, will be set to TRUE if conversion was successful
183 : : * \returns aggregate type
184 : : */
185 : : static Aggregate stringToAggregate( const QString &string, bool *ok = nullptr );
186 : :
187 : : /**
188 : : * Structured information for available aggregates.
189 : : *
190 : : * \since QGIS 3.2
191 : : */
192 : : static QList< QgsAggregateCalculator::AggregateInfo > aggregates();
193 : :
194 : : private:
195 : :
196 : : //! Source layer
197 : : const QgsVectorLayer *mLayer = nullptr;
198 : :
199 : : //! Filter expression, or empty for no filter
200 : : QString mFilterExpression;
201 : :
202 : : //! Order by clause
203 : : QgsFeatureRequest::OrderBy mOrderBy;
204 : :
205 : : //! Delimiter to use for concatenate aggregate
206 : : QString mDelimiter;
207 : :
208 : : //!list of fids to filter
209 : : QgsFeatureIds mFidsFilter;
210 : :
211 : : //trigger variable
212 : : bool mFidsSet = false;
213 : :
214 : : static QgsStatisticalSummary::Statistic numericStatFromAggregate( Aggregate aggregate, bool *ok = nullptr );
215 : : static QgsStringStatisticalSummary::Statistic stringStatFromAggregate( Aggregate aggregate, bool *ok = nullptr );
216 : : static QgsDateTimeStatisticalSummary::Statistic dateTimeStatFromAggregate( Aggregate aggregate, bool *ok = nullptr );
217 : :
218 : : static QVariant calculateNumericAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
219 : : QgsExpressionContext *context, QgsStatisticalSummary::Statistic stat );
220 : :
221 : : static QVariant calculateStringAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
222 : : QgsExpressionContext *context, QgsStringStatisticalSummary::Statistic stat );
223 : :
224 : : static QVariant calculateDateTimeAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
225 : : QgsExpressionContext *context, QgsDateTimeStatisticalSummary::Statistic stat );
226 : : static QVariant calculateGeometryAggregate( QgsFeatureIterator &fit, QgsExpression *expression, QgsExpressionContext *context );
227 : :
228 : : static QVariant calculateArrayAggregate( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
229 : : QgsExpressionContext *context );
230 : :
231 : : static QVariant calculate( Aggregate aggregate, QgsFeatureIterator &fit, QVariant::Type resultType,
232 : : int attr, QgsExpression *expression,
233 : : const QString &delimiter,
234 : : QgsExpressionContext *context, bool *ok = nullptr );
235 : : static QVariant concatenateStrings( QgsFeatureIterator &fit, int attr, QgsExpression *expression,
236 : : QgsExpressionContext *context, const QString &delimiter, bool unique = false );
237 : :
238 : : QVariant defaultValue( Aggregate aggregate ) const;
239 : : };
240 : :
241 : : #endif //QGSAGGREGATECALCULATOR_H
|