QGIS API Documentation 3.38.0-Grenoble (exported)
Loading...
Searching...
No Matches
qgsalgorithmjoinbylocationsummary.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmjoinbylocationsummary.cpp
3 ---------------------
4 begin : September 2023
5 copyright : (C) 2023 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#include "qgsprocessing.h"
20#include "qgsgeometryengine.h"
21#include "qgsvectorlayer.h"
22#include "qgsapplication.h"
23#include "qgsfeature.h"
24#include "qgsfeaturesource.h"
28
30
31
32void QgsJoinByLocationSummaryAlgorithm::initAlgorithm( const QVariantMap & )
33{
34 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ),
35 QObject::tr( "Join to features in" ), QList< int > () << static_cast< int >( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
36
37 std::unique_ptr< QgsProcessingParameterEnum > predicateParam = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "PREDICATE" ), QObject::tr( "Where the features" ),
38 QgsJoinByLocationAlgorithm::translatedPredicates(), true, 0 );
39 QVariantMap predicateMetadata;
40 QVariantMap widgetMetadata;
41 widgetMetadata.insert( QStringLiteral( "useCheckBoxes" ), true );
42 widgetMetadata.insert( QStringLiteral( "columns" ), 2 );
43 predicateMetadata.insert( QStringLiteral( "widget_wrapper" ), widgetMetadata );
44 predicateParam->setMetadata( predicateMetadata );
45 addParameter( predicateParam.release() );
46
47 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "JOIN" ),
48 QObject::tr( "By comparing to" ), QList< int > () << static_cast< int >( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
49
50 addParameter( new QgsProcessingParameterField( QStringLiteral( "JOIN_FIELDS" ),
51 QObject::tr( "Fields to summarise (leave empty to use all fields)" ),
52 QVariant(), QStringLiteral( "JOIN" ), Qgis::ProcessingFieldParameterDataType::Any, true, true ) );
53
54 mAllSummaries << QObject::tr( "count" )
55 << QObject::tr( "unique" )
56 << QObject::tr( "min" )
57 << QObject::tr( "max" )
58 << QObject::tr( "range" )
59 << QObject::tr( "sum" )
60 << QObject::tr( "mean" )
61 << QObject::tr( "median" )
62 << QObject::tr( "stddev" )
63 << QObject::tr( "minority" )
64 << QObject::tr( "majority" )
65 << QObject::tr( "q1" )
66 << QObject::tr( "q3" )
67 << QObject::tr( "iqr" )
68 << QObject::tr( "empty" )
69 << QObject::tr( "filled" )
70 << QObject::tr( "min_length" )
71 << QObject::tr( "max_length" )
72 << QObject::tr( "mean_length" );
73
74 std::unique_ptr< QgsProcessingParameterEnum > summaryParam = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "SUMMARIES" ), QObject::tr( "Summaries to calculate (leave empty to use all available)" ), mAllSummaries, true, QVariant(), true );
75 addParameter( summaryParam.release() );
76
77 addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "DISCARD_NONMATCHING" ),
78 QObject::tr( "Discard records which could not be joined" ),
79 false ) );
80 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Joined layer" ) ) );
81}
82
83QString QgsJoinByLocationSummaryAlgorithm::name() const
84{
85 return QStringLiteral( "joinbylocationsummary" );
86}
87
88QString QgsJoinByLocationSummaryAlgorithm::displayName() const
89{
90 return QObject::tr( "Join attributes by location (summary)" );
91}
92
93QStringList QgsJoinByLocationSummaryAlgorithm::tags() const
94{
95 return QObject::tr( "summary,aggregate,join,intersects,intersecting,touching,within,contains,overlaps,relation,spatial,"
96 "stats,statistics,sum,maximum,minimum,mean,average,standard,deviation,"
97 "count,distinct,unique,variance,median,quartile,range,majority,minority,histogram,distinct" ).split( ',' );
98}
99
100QString QgsJoinByLocationSummaryAlgorithm::group() const
101{
102 return QObject::tr( "Vector general" );
103}
104
105QString QgsJoinByLocationSummaryAlgorithm::groupId() const
106{
107 return QStringLiteral( "vectorgeneral" );
108}
109
110QString QgsJoinByLocationSummaryAlgorithm::shortHelpString() const
111{
112 return QObject::tr( "This algorithm takes an input vector layer and creates a new vector layer that is an extended version of the input one, with additional attributes in its attribute table.\n\n"
113 "The additional attributes and their values are taken from a second vector layer. A spatial criteria is applied to select the values from the second layer that are added to each feature from the first layer in the resulting one.\n\n"
114 "The algorithm calculates a statistical summary for the values from matching features in the second layer( e.g. maximum value, mean value, etc )." );
115}
116
117QString QgsJoinByLocationSummaryAlgorithm::shortDescription() const
118{
119 return QObject::tr( "Calculate summaries of attributes from one vector layer to another by location." );
120}
121
122QIcon QgsJoinByLocationSummaryAlgorithm::icon() const
123{
124 return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmBasicStatistics.svg" ) );
125}
126
127QString QgsJoinByLocationSummaryAlgorithm::svgIconPath() const
128{
129 return QgsApplication::iconPath( QStringLiteral( "/algorithms/mAlgorithmBasicStatistics.svg" ) );
130}
131
132QgsJoinByLocationSummaryAlgorithm *QgsJoinByLocationSummaryAlgorithm::createInstance() const
133{
134 return new QgsJoinByLocationSummaryAlgorithm();
135}
136
137QVariantMap QgsJoinByLocationSummaryAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
138{
139 std::unique_ptr< QgsProcessingFeatureSource > baseSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
140 if ( !baseSource )
141 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
142
143 std::unique_ptr< QgsProcessingFeatureSource > joinSource( parameterAsSource( parameters, QStringLiteral( "JOIN" ), context ) );
144 if ( !joinSource )
145 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "JOIN" ) ) );
146
147 if ( joinSource->hasSpatialIndex() == Qgis::SpatialIndexPresence::NotPresent )
148 feedback->reportError( QObject::tr( "No spatial index exists for join layer, performance will be severely degraded" ) );
149
150 QStringList joinedFieldNames = parameterAsStrings( parameters, QStringLiteral( "JOIN_FIELDS" ), context );
151
152 bool discardNonMatching = parameterAsBoolean( parameters, QStringLiteral( "DISCARD_NONMATCHING" ), context );
153
154 QList< int > summaries = parameterAsEnums( parameters, QStringLiteral( "SUMMARIES" ), context );
155 if ( summaries.empty() )
156 {
157 for ( int i = 0; i < mAllSummaries.size(); ++i )
158 summaries << i;
159 }
160
161 QgsFields sourceFields = baseSource->fields();
162 QgsFields fieldsToJoin;
163 QList< int > joinFieldIndices;
164 if ( joinedFieldNames.empty() )
165 {
166 // no fields selected, use all
167 for ( const QgsField &sourceField : joinSource->fields() )
168 {
169 joinedFieldNames.append( sourceField.name() );
170 }
171 }
172
173 // Adds a field to the output, keeping the same data type as the original
174 auto addFieldKeepType = [&fieldsToJoin]( const QgsField & original, const QString & statistic )
175 {
176 QgsField field = QgsField( original );
177 field.setName( field.name() + '_' + statistic );
178 fieldsToJoin.append( field );
179 };
180
181 // Adds a field to the output, with a specified type
182 auto addFieldWithType = [&fieldsToJoin]( const QgsField & original, const QString & statistic, QMetaType::Type type )
183 {
184 QgsField field = QgsField( original );
185 field.setName( field.name() + '_' + statistic );
186 field.setType( type );
187 if ( type == QMetaType::Type::Double )
188 {
189 field.setLength( 20 );
190 field.setPrecision( 6 );
191 }
192 fieldsToJoin.append( field );
193 };
194
195 enum class FieldType
196 {
197 Numeric,
198 DateTime,
199 String
200 };
201 QList< FieldType > fieldTypes;
202
203 struct FieldStatistic
204 {
205 FieldStatistic( int enumIndex, const QString &name, QMetaType::Type type )
206 : enumIndex( enumIndex )
207 , name( name )
208 , type( type )
209 {}
210
211 int enumIndex = 0;
212 QString name;
213 QMetaType::Type type;
214 };
215 static const QVector< FieldStatistic > sNumericStats
216 {
217 FieldStatistic( 0, QStringLiteral( "count" ), QMetaType::Type::LongLong ),
218 FieldStatistic( 1, QStringLiteral( "unique" ), QMetaType::Type::LongLong ),
219 FieldStatistic( 2, QStringLiteral( "min" ), QMetaType::Type::Double ),
220 FieldStatistic( 3, QStringLiteral( "max" ), QMetaType::Type::Double ),
221 FieldStatistic( 4, QStringLiteral( "range" ), QMetaType::Type::Double ),
222 FieldStatistic( 5, QStringLiteral( "sum" ), QMetaType::Type::Double ),
223 FieldStatistic( 6, QStringLiteral( "mean" ), QMetaType::Type::Double ),
224 FieldStatistic( 7, QStringLiteral( "median" ), QMetaType::Type::Double ),
225 FieldStatistic( 8, QStringLiteral( "stddev" ), QMetaType::Type::Double ),
226 FieldStatistic( 9, QStringLiteral( "minority" ), QMetaType::Type::Double ),
227 FieldStatistic( 10, QStringLiteral( "majority" ), QMetaType::Type::Double ),
228 FieldStatistic( 11, QStringLiteral( "q1" ), QMetaType::Type::Double ),
229 FieldStatistic( 12, QStringLiteral( "q3" ), QMetaType::Type::Double ),
230 FieldStatistic( 13, QStringLiteral( "iqr" ), QMetaType::Type::Double ),
231 };
232 static const QVector< FieldStatistic > sDateTimeStats
233 {
234 FieldStatistic( 0, QStringLiteral( "count" ), QMetaType::Type::LongLong ),
235 FieldStatistic( 1, QStringLiteral( "unique" ), QMetaType::Type::LongLong ),
236 FieldStatistic( 14, QStringLiteral( "empty" ), QMetaType::Type::LongLong ),
237 FieldStatistic( 15, QStringLiteral( "filled" ), QMetaType::Type::LongLong ),
238 FieldStatistic( 2, QStringLiteral( "min" ), QMetaType::Type::UnknownType ),
239 FieldStatistic( 3, QStringLiteral( "max" ), QMetaType::Type::UnknownType ),
240 };
241 static const QVector< FieldStatistic > sStringStats
242 {
243 FieldStatistic( 0, QStringLiteral( "count" ), QMetaType::Type::LongLong ),
244 FieldStatistic( 1, QStringLiteral( "unique" ), QMetaType::Type::LongLong ),
245 FieldStatistic( 14, QStringLiteral( "empty" ), QMetaType::Type::LongLong ),
246 FieldStatistic( 15, QStringLiteral( "filled" ), QMetaType::Type::LongLong ),
247 FieldStatistic( 2, QStringLiteral( "min" ), QMetaType::Type::UnknownType ),
248 FieldStatistic( 3, QStringLiteral( "max" ), QMetaType::Type::UnknownType ),
249 FieldStatistic( 16, QStringLiteral( "min_length" ), QMetaType::Type::Int ),
250 FieldStatistic( 17, QStringLiteral( "max_length" ), QMetaType::Type::Int ),
251 FieldStatistic( 18, QStringLiteral( "mean_length" ), QMetaType::Type::Double ),
252 };
253
254 for ( const QString &field : std::as_const( joinedFieldNames ) )
255 {
256 const int fieldIndex = joinSource->fields().lookupField( field );
257 if ( fieldIndex >= 0 )
258 {
259 joinFieldIndices.append( fieldIndex );
260
261 const QgsField joinField = joinSource->fields().at( fieldIndex );
262 QVector< FieldStatistic > statisticList;
263 if ( joinField.isNumeric() )
264 {
265 fieldTypes.append( FieldType::Numeric );
266 statisticList = sNumericStats;
267 }
268 else if ( joinField.type() == QMetaType::Type::QDate
269 || joinField.type() == QMetaType::Type::QTime
270 || joinField.type() == QMetaType::Type::QDateTime )
271 {
272 fieldTypes.append( FieldType::DateTime );
273 statisticList = sDateTimeStats;
274 }
275 else
276 {
277 fieldTypes.append( FieldType::String );
278 statisticList = sStringStats;
279 }
280
281 for ( const FieldStatistic &statistic : std::as_const( statisticList ) )
282 {
283 if ( summaries.contains( statistic.enumIndex ) )
284 {
285 if ( statistic.type != QMetaType::Type::UnknownType )
286 addFieldWithType( joinField, statistic.name, statistic.type );
287 else
288 addFieldKeepType( joinField, statistic.name );
289 }
290 }
291 }
292 }
293
294 const QgsFields outputFields = QgsProcessingUtils::combineFields( sourceFields, fieldsToJoin );
295
296 QString destId;
297 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, destId, outputFields,
298 baseSource->wkbType(), baseSource->sourceCrs() ) );
299
300 if ( !sink )
301 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
302
303
304 QList<int> predicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
305 QgsJoinByLocationAlgorithm::sortPredicates( predicates );
306
307 QgsFeatureIterator sourceIter = baseSource->getFeatures();
308 QgsFeature f;
309 const double step = baseSource->featureCount() > 0 ? 100.0 / baseSource->featureCount() : 1;
310 long long i = 0;
311 while ( sourceIter.nextFeature( f ) )
312 {
313 if ( feedback->isCanceled() )
314 break;
315
316 if ( !f.hasGeometry() )
317 {
318 if ( !discardNonMatching )
319 {
320 // ensure consistent count of attributes - otherwise non matching
321 // features will have incorrect attribute length
322 // and provider may reject them
323 f.resizeAttributes( outputFields.size() );
324 sink->addFeature( f, QgsFeatureSink::FastInsert );
325 }
326 continue;
327 }
328
329 std::unique_ptr< QgsGeometryEngine > engine;
330 QVector< QVector< QVariant > > values;
331
332 QgsFeatureRequest request;
333 request.setFilterRect( f.geometry().boundingBox() );
334 request.setSubsetOfAttributes( joinFieldIndices );
335 request.setDestinationCrs( baseSource->sourceCrs(), context.transformContext() );
336
337 QgsFeatureIterator joinIter = joinSource->getFeatures( request );
338 QgsFeature testJoinFeature;
339 while ( joinIter.nextFeature( testJoinFeature ) )
340 {
341 if ( feedback->isCanceled() )
342 break;
343
344 if ( !engine )
345 {
346 engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
347 engine->prepareGeometry();
348 }
349
350 if ( QgsJoinByLocationAlgorithm::featureFilter( testJoinFeature, engine.get(), true, predicates ) )
351 {
352 QgsAttributes joinAttributes;
353 joinAttributes.reserve( joinFieldIndices.size() );
354 for ( int joinIndex : std::as_const( joinFieldIndices ) )
355 {
356 joinAttributes.append( testJoinFeature.attribute( joinIndex ) );
357 }
358 values.append( joinAttributes );
359 }
360 }
361
362 i++;
363 feedback->setProgress( i * step );
364
365 if ( feedback->isCanceled() )
366 break;
367
368 if ( values.empty() )
369 {
370 if ( discardNonMatching )
371 {
372 continue;
373 }
374 else
375 {
376 // ensure consistent count of attributes - otherwise non matching
377 // features will have incorrect attribute length
378 // and provider may reject them
379 f.resizeAttributes( outputFields.size() );
380 sink->addFeature( f, QgsFeatureSink::FastInsert );
381 }
382 }
383 else
384 {
385 // calculate statistics
386 QgsAttributes outputAttributes = f.attributes();
387 outputAttributes.reserve( outputFields.size() );
388 for ( int fieldIndex = 0; fieldIndex < joinFieldIndices.size(); ++fieldIndex )
389 {
390 const FieldType &fieldType = fieldTypes.at( fieldIndex );
391 switch ( fieldType )
392 {
393 case FieldType::Numeric:
394 {
396 for ( const QVector< QVariant > &value : std::as_const( values ) )
397 {
398 stat.addVariant( value.at( fieldIndex ) );
399 }
400 stat.finalize();
401 for ( const FieldStatistic &statistic : sNumericStats )
402 {
403 if ( summaries.contains( statistic.enumIndex ) )
404 {
405 QVariant val;
406 switch ( statistic.enumIndex )
407 {
408 case 0:
409 val = stat.count();
410 break;
411 case 1:
412 val = stat.variety();
413 break;
414 case 2:
415 val = stat.min();
416 break;
417 case 3:
418 val = stat.max();
419 break;
420 case 4:
421 val = stat.range();
422 break;
423 case 5:
424 val = stat.sum();
425 break;
426 case 6:
427 val = stat.mean();
428 break;
429 case 7:
430 val = stat.median();
431 break;
432 case 8:
433 val = stat.stDev();
434 break;
435 case 9:
436 val = stat.minority();
437 break;
438 case 10:
439 val = stat.majority();
440 break;
441 case 11:
442 val = stat.firstQuartile();
443 break;
444 case 12:
445 val = stat.thirdQuartile();
446 break;
447 case 13:
448 val = stat.interQuartileRange();
449 break;
450 }
451 if ( val.isValid() && std::isnan( val.toDouble() ) )
452 val = QVariant();
453 outputAttributes.append( val );
454 }
455 }
456 break;
457 }
458
459 case FieldType::DateTime:
460 {
462 QVariantList inputValues;
463 inputValues.reserve( values.size() );
464 for ( const QVector< QVariant > &value : std::as_const( values ) )
465 {
466 inputValues << value.at( fieldIndex );
467 }
468 stat.calculate( inputValues );
469 for ( const FieldStatistic &statistic : sDateTimeStats )
470 {
471 if ( summaries.contains( statistic.enumIndex ) )
472 {
473 QVariant val;
474 switch ( statistic.enumIndex )
475 {
476 case 0:
477 val = stat.count();
478 break;
479 case 1:
480 val = stat.countDistinct();
481 break;
482 case 2:
483 val = stat.min();
484 break;
485 case 3:
486 val = stat.max();
487 break;
488 case 14:
489 val = stat.countMissing();
490 break;
491 case 15:
492 val = stat.count() - stat.countMissing();
493 break;
494 }
495 outputAttributes.append( val );
496 }
497 }
498 break;
499 }
500
501 case FieldType::String:
502 {
504 QVariantList inputValues;
505 inputValues.reserve( values.size() );
506 for ( const QVector< QVariant > &value : std::as_const( values ) )
507 {
508 if ( value.at( fieldIndex ).isNull() )
509 stat.addString( QString() );
510 else
511 stat.addString( value.at( fieldIndex ).toString() );
512 }
513 stat.finalize();
514 for ( const FieldStatistic &statistic : sStringStats )
515 {
516 if ( summaries.contains( statistic.enumIndex ) )
517 {
518 QVariant val;
519 switch ( statistic.enumIndex )
520 {
521 case 0:
522 val = stat.count();
523 break;
524 case 1:
525 val = stat.countDistinct();
526 break;
527 case 2:
528 val = stat.min();
529 break;
530 case 3:
531 val = stat.max();
532 break;
533 case 14:
534 val = stat.countMissing();
535 break;
536 case 15:
537 val = stat.count() - stat.countMissing();
538 break;
539 case 16:
540 val = stat.minLength();
541 break;
542 case 17:
543 val = stat.maxLength();
544 break;
545 case 18:
546 val = stat.meanLength();
547 break;
548 }
549 outputAttributes.append( val );
550 }
551 }
552 break;
553 }
554 }
555 }
556
557 f.setAttributes( outputAttributes );
558 sink->addFeature( f, QgsFeatureSink::FastInsert );
559 }
560 }
561
562 sink.reset();
563
564 QVariantMap results;
565 results.insert( QStringLiteral( "OUTPUT" ), destId );
566 return results;
567}
568
570
571
572
@ VectorAnyGeometry
Any vector layer with geometry.
@ NotPresent
No spatial index exists for the source.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
A vector of attributes.
Calculator for summary statistics and aggregates for a list of datetimes.
void calculate(const QVariantList &values)
Calculates summary statistics for a list of variants.
QDateTime min() const
Returns the minimum (earliest) non-null datetime value.
int count() const
Returns the calculated count of values.
int countMissing() const
Returns the number of missing (null) datetime values.
int countDistinct() const
Returns the number of distinct datetime values.
QDateTime max() const
Returns the maximum (latest) non-null datetime value.
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.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
void resizeAttributes(int fieldCount)
Resizes the attributes attached to this feature to the given number of fields.
QgsAttributes attributes
Definition qgsfeature.h:67
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
QMetaType::Type type
Definition qgsfield.h:60
QString name
Definition qgsfield.h:62
void setPrecision(int precision)
Set the field precision.
Definition qgsfield.cpp:260
void setName(const QString &name)
Set the field name.
Definition qgsfield.cpp:226
void setType(QMetaType::Type type)
Set variant type.
Definition qgsfield.cpp:231
void setLength(int len)
Set the field length.
Definition qgsfield.cpp:256
bool isNumeric
Definition qgsfield.h:56
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:60
int size() const
Returns number of items.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A boolean parameter for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Calculator for summary statistics for a list of doubles.
void addVariant(const QVariant &value)
Adds a single value to the statistics calculation.
double firstQuartile() const
Returns the first quartile of the values.
double sum() const
Returns calculated sum of values.
double mean() const
Returns calculated mean of values.
double majority() const
Returns majority of values.
double interQuartileRange() const
Returns the inter quartile range of the values.
double median() const
Returns calculated median of values.
double minority() const
Returns minority of values.
double min() const
Returns calculated minimum from values.
double stDev() const
Returns population standard deviation.
double thirdQuartile() const
Returns the third quartile of the values.
int count() const
Returns calculated count of values.
double range() const
Returns calculated range (difference between maximum and minimum values).
double max() const
Returns calculated maximum from values.
void finalize()
Must be called after adding all values with addValues() and before retrieving any calculated statisti...
int variety() const
Returns variety of values.
Calculator for summary statistics and aggregates for a list of strings.
QString max() const
Returns the maximum (non-null) string value.
QString min() const
Returns the minimum (non-null) string value.
int countMissing() const
Returns the number of missing (null) string values.
int count() const
Returns the calculated count of values.
int countDistinct() const
Returns the number of distinct string values.
void finalize()
Must be called after adding all strings with addString() and before retrieving any calculated string ...
void addString(const QString &string)
Adds a single string to the statistics calculation.
int minLength() const
Returns the minimum length of strings.
int maxLength() const
Returns the maximum length of strings.
double meanLength() const
Returns the mean length of strings.