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