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