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