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