QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
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 QGS_MARK_ALGORITHM_SOURCE
146
147 std::unique_ptr<QgsProcessingFeatureSource> baseSource( parameterAsSource( parameters, u"INPUT"_s, context ) );
148 if ( !baseSource )
149 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
150
151 std::unique_ptr<QgsProcessingFeatureSource> joinSource( parameterAsSource( parameters, u"JOIN"_s, context ) );
152 if ( !joinSource )
153 throw QgsProcessingException( invalidSourceError( parameters, u"JOIN"_s ) );
154
155 if ( joinSource->hasSpatialIndex() == Qgis::SpatialIndexPresence::NotPresent )
156 feedback->reportError( QObject::tr( "No spatial index exists for join layer, performance will be severely degraded" ) );
157
158 QStringList joinedFieldNames = parameterAsStrings( parameters, u"JOIN_FIELDS"_s, context );
159
160 bool discardNonMatching = parameterAsBoolean( parameters, u"DISCARD_NONMATCHING"_s, context );
161
162 QList<int> summaries = parameterAsEnums( parameters, u"SUMMARIES"_s, context );
163 if ( summaries.empty() )
164 {
165 for ( int i = 0; i < mAllSummaries.size(); ++i )
166 summaries << i;
167 }
168
169 QgsFields sourceFields = baseSource->fields();
170 QgsFields fieldsToJoin;
171 QList<int> joinFieldIndices;
172 if ( joinedFieldNames.empty() )
173 {
174 // no fields selected, use all
175 for ( const QgsField &sourceField : joinSource->fields() )
176 {
177 joinedFieldNames.append( sourceField.name() );
178 }
179 }
180
181 // Adds a field to the output, keeping the same data type as the original
182 auto addFieldKeepType = [&fieldsToJoin]( const QgsField &original, const QString &statistic ) {
183 QgsField field = QgsField( original );
184 field.setName( field.name() + '_' + statistic );
185 fieldsToJoin.append( field );
186 };
187
188 // Adds a field to the output, with a specified type
189 auto addFieldWithType = [&fieldsToJoin]( const QgsField &original, const QString &statistic, QMetaType::Type type ) {
190 QgsField field = QgsField( original );
191 field.setName( field.name() + '_' + statistic );
192 field.setType( type );
193 if ( type == QMetaType::Type::Double )
194 {
195 field.setLength( 20 );
196 field.setPrecision( 6 );
197 }
198 fieldsToJoin.append( field );
199 };
200
201 enum class FieldType
202 {
203 Numeric,
204 DateTime,
205 String
206 };
207 QList<FieldType> fieldTypes;
208
209 struct FieldStatistic
210 {
211 FieldStatistic( int enumIndex, const QString &name, QMetaType::Type type )
212 : enumIndex( enumIndex )
213 , name( name )
214 , type( type )
215 {}
216
217 int enumIndex = 0;
218 QString name;
219 QMetaType::Type type;
220 };
221 static const QVector<FieldStatistic> sNumericStats {
222 FieldStatistic( 0, u"count"_s, QMetaType::Type::LongLong ),
223 FieldStatistic( 1, u"unique"_s, QMetaType::Type::LongLong ),
224 FieldStatistic( 2, u"min"_s, QMetaType::Type::Double ),
225 FieldStatistic( 3, u"max"_s, QMetaType::Type::Double ),
226 FieldStatistic( 4, u"range"_s, QMetaType::Type::Double ),
227 FieldStatistic( 5, u"sum"_s, QMetaType::Type::Double ),
228 FieldStatistic( 6, u"mean"_s, QMetaType::Type::Double ),
229 FieldStatistic( 7, u"median"_s, QMetaType::Type::Double ),
230 FieldStatistic( 8, u"stddev"_s, QMetaType::Type::Double ),
231 FieldStatistic( 9, u"minority"_s, QMetaType::Type::Double ),
232 FieldStatistic( 10, u"majority"_s, QMetaType::Type::Double ),
233 FieldStatistic( 11, u"q1"_s, QMetaType::Type::Double ),
234 FieldStatistic( 12, u"q3"_s, QMetaType::Type::Double ),
235 FieldStatistic( 13, u"iqr"_s, QMetaType::Type::Double ),
236 };
237 static const QVector<FieldStatistic> sDateTimeStats {
238 FieldStatistic( 0, u"count"_s, QMetaType::Type::LongLong ),
239 FieldStatistic( 1, u"unique"_s, QMetaType::Type::LongLong ),
240 FieldStatistic( 14, u"empty"_s, QMetaType::Type::LongLong ),
241 FieldStatistic( 15, u"filled"_s, QMetaType::Type::LongLong ),
242 FieldStatistic( 2, u"min"_s, QMetaType::Type::UnknownType ),
243 FieldStatistic( 3, u"max"_s, QMetaType::Type::UnknownType ),
244 };
245 static const QVector<FieldStatistic> sStringStats {
246 FieldStatistic( 0, u"count"_s, QMetaType::Type::LongLong ),
247 FieldStatistic( 1, u"unique"_s, QMetaType::Type::LongLong ),
248 FieldStatistic( 14, u"empty"_s, QMetaType::Type::LongLong ),
249 FieldStatistic( 15, u"filled"_s, QMetaType::Type::LongLong ),
250 FieldStatistic( 2, u"min"_s, QMetaType::Type::UnknownType ),
251 FieldStatistic( 3, u"max"_s, QMetaType::Type::UnknownType ),
252 FieldStatistic( 16, u"min_length"_s, QMetaType::Type::Int ),
253 FieldStatistic( 17, u"max_length"_s, QMetaType::Type::Int ),
254 FieldStatistic( 18, u"mean_length"_s, QMetaType::Type::Double ),
255 };
256
257 QgsAttributes nonMatchingJoinAttributes;
258
259 for ( const QString &field : std::as_const( joinedFieldNames ) )
260 {
261 const int fieldIndex = joinSource->fields().lookupField( field );
262 if ( fieldIndex >= 0 )
263 {
264 joinFieldIndices.append( fieldIndex );
265
266 const QgsField joinField = joinSource->fields().at( fieldIndex );
267 QVector<FieldStatistic> statisticList;
268 if ( joinField.isNumeric() )
269 {
270 fieldTypes.append( FieldType::Numeric );
271 statisticList = sNumericStats;
272 }
273 else if ( joinField.type() == QMetaType::Type::QDate || joinField.type() == QMetaType::Type::QTime || joinField.type() == QMetaType::Type::QDateTime )
274 {
275 fieldTypes.append( FieldType::DateTime );
276 statisticList = sDateTimeStats;
277 }
278 else
279 {
280 fieldTypes.append( FieldType::String );
281 statisticList = sStringStats;
282 }
283
284 for ( const FieldStatistic &statistic : std::as_const( statisticList ) )
285 {
286 if ( summaries.contains( statistic.enumIndex ) )
287 {
288 if ( statistic.type != QMetaType::Type::UnknownType )
289 addFieldWithType( joinField, statistic.name, statistic.type );
290 else
291 addFieldKeepType( joinField, statistic.name );
292
293 // count, unique, empty and filled values should be 0
294 // see https://github.com/qgis/QGIS/issues/40108
295 if ( statistic.enumIndex == 0 || statistic.enumIndex == 1 || statistic.enumIndex == 14 || statistic.enumIndex == 15 )
296 {
297 nonMatchingJoinAttributes.append( QVariant( 0 ) );
298 }
299 else
300 {
301 nonMatchingJoinAttributes.append( QVariant() );
302 }
303 }
304 }
305 }
306 }
307
308 const QgsFields outputFields = QgsProcessingUtils::combineFields( sourceFields, fieldsToJoin );
309
310 QString destId;
311 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u"OUTPUT"_s, context, destId, outputFields, baseSource->wkbType(), baseSource->sourceCrs() ) );
312
313 if ( !sink )
314 throw QgsProcessingException( invalidSinkError( parameters, u"OUTPUT"_s ) );
315
316
317 QList<int> predicates = parameterAsEnums( parameters, u"PREDICATE"_s, context );
318 QgsJoinByLocationAlgorithm::sortPredicates( predicates );
319
320 QgsFeatureIterator sourceIter = baseSource->getFeatures();
321 QgsFeature f;
322 const double step = baseSource->featureCount() > 0 ? 100.0 / static_cast<double>( baseSource->featureCount() ) : 1;
323 long long i = 0;
324 while ( sourceIter.nextFeature( f ) )
325 {
326 if ( feedback->isCanceled() )
327 break;
328
329 if ( !f.hasGeometry() )
330 {
331 if ( !discardNonMatching )
332 {
333 // ensure consistent count of attributes - otherwise non matching
334 // features will have incorrect attribute length
335 // and provider may reject them
336 QgsAttributes outputAttributes = f.attributes();
337 outputAttributes.append( nonMatchingJoinAttributes );
338 f.setAttributes( outputAttributes );
339 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
340 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, u"OUTPUT"_s ) );
341 else
342 feedback->featureAddedToSink( destId );
343 }
344 continue;
345 }
346
347 std::unique_ptr<QgsGeometryEngine> engine;
348 QVector<QVector<QVariant>> values;
349
350 QgsFeatureRequest request;
351 request.setFilterRect( f.geometry().boundingBox() );
352 request.setSubsetOfAttributes( joinFieldIndices );
353 request.setDestinationCrs( baseSource->sourceCrs(), context.transformContext() );
354
355 QgsFeatureIterator joinIter = joinSource->getFeatures( request );
356 QgsFeature testJoinFeature;
357 while ( joinIter.nextFeature( testJoinFeature ) )
358 {
359 if ( feedback->isCanceled() )
360 break;
361
362 if ( !engine )
363 {
364 engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
365 engine->prepareGeometry();
366 }
367
368 if ( QgsJoinByLocationAlgorithm::featureFilter( testJoinFeature, engine.get(), true, predicates ) )
369 {
370 QgsAttributes joinAttributes;
371 joinAttributes.reserve( joinFieldIndices.size() );
372 for ( int joinIndex : std::as_const( joinFieldIndices ) )
373 {
374 joinAttributes.append( testJoinFeature.attribute( joinIndex ) );
375 }
376 values.append( joinAttributes );
377 }
378 }
379
380 i++;
381 feedback->setProgress( static_cast<double>( i ) * step );
382
383 if ( feedback->isCanceled() )
384 break;
385
386 if ( values.empty() )
387 {
388 if ( discardNonMatching )
389 {
390 continue;
391 }
392 else
393 {
394 // ensure consistent count of attributes - otherwise non matching
395 // features will have incorrect attribute length
396 // and provider may reject them
397 QgsAttributes outputAttributes = f.attributes();
398 outputAttributes.append( nonMatchingJoinAttributes );
399 f.setAttributes( outputAttributes );
400 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
401 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, u"OUTPUT"_s ) );
402 else
403 feedback->featureAddedToSink( destId );
404 }
405 }
406 else
407 {
408 // calculate statistics
409 QgsAttributes outputAttributes = f.attributes();
410 outputAttributes.reserve( outputFields.size() );
411 for ( int fieldIndex = 0; fieldIndex < joinFieldIndices.size(); ++fieldIndex )
412 {
413 const FieldType &fieldType = fieldTypes.at( fieldIndex );
414 switch ( fieldType )
415 {
416 case FieldType::Numeric:
417 {
419 for ( const QVector<QVariant> &value : std::as_const( values ) )
420 {
421 stat.addVariant( value.at( fieldIndex ) );
422 }
423 stat.finalize();
424 for ( const FieldStatistic &statistic : sNumericStats )
425 {
426 if ( summaries.contains( statistic.enumIndex ) )
427 {
428 QVariant val;
429 switch ( statistic.enumIndex )
430 {
431 case 0:
432 val = stat.count();
433 break;
434 case 1:
435 val = stat.variety();
436 break;
437 case 2:
438 val = stat.min();
439 break;
440 case 3:
441 val = stat.max();
442 break;
443 case 4:
444 val = stat.range();
445 break;
446 case 5:
447 val = stat.sum();
448 break;
449 case 6:
450 val = stat.mean();
451 break;
452 case 7:
453 val = stat.median();
454 break;
455 case 8:
456 val = stat.stDev();
457 break;
458 case 9:
459 val = stat.minority();
460 break;
461 case 10:
462 val = stat.majority();
463 break;
464 case 11:
465 val = stat.firstQuartile();
466 break;
467 case 12:
468 val = stat.thirdQuartile();
469 break;
470 case 13:
471 val = stat.interQuartileRange();
472 break;
473 }
474 if ( val.isValid() && std::isnan( val.toDouble() ) )
475 val = QVariant();
476 outputAttributes.append( val );
477 }
478 }
479 break;
480 }
481
482 case FieldType::DateTime:
483 {
485 QVariantList inputValues;
486 inputValues.reserve( values.size() );
487 for ( const QVector<QVariant> &value : std::as_const( values ) )
488 {
489 inputValues << value.at( fieldIndex );
490 }
491 stat.calculate( inputValues );
492 for ( const FieldStatistic &statistic : sDateTimeStats )
493 {
494 if ( summaries.contains( statistic.enumIndex ) )
495 {
496 QVariant val;
497 switch ( statistic.enumIndex )
498 {
499 case 0:
500 val = stat.count();
501 break;
502 case 1:
503 val = stat.countDistinct();
504 break;
505 case 2:
506 val = stat.min();
507 break;
508 case 3:
509 val = stat.max();
510 break;
511 case 14:
512 val = stat.countMissing();
513 break;
514 case 15:
515 val = stat.count() - stat.countMissing();
516 break;
517 }
518 outputAttributes.append( val );
519 }
520 }
521 break;
522 }
523
524 case FieldType::String:
525 {
527 QVariantList inputValues;
528 inputValues.reserve( values.size() );
529 for ( const QVector<QVariant> &value : std::as_const( values ) )
530 {
531 if ( value.at( fieldIndex ).isNull() )
532 stat.addString( QString() );
533 else
534 stat.addString( value.at( fieldIndex ).toString() );
535 }
536 stat.finalize();
537 for ( const FieldStatistic &statistic : sStringStats )
538 {
539 if ( summaries.contains( statistic.enumIndex ) )
540 {
541 QVariant val;
542 switch ( statistic.enumIndex )
543 {
544 case 0:
545 val = stat.count();
546 break;
547 case 1:
548 val = stat.countDistinct();
549 break;
550 case 2:
551 val = stat.min();
552 break;
553 case 3:
554 val = stat.max();
555 break;
556 case 14:
557 val = stat.countMissing();
558 break;
559 case 15:
560 val = stat.count() - stat.countMissing();
561 break;
562 case 16:
563 val = stat.minLength();
564 break;
565 case 17:
566 val = stat.maxLength();
567 break;
568 case 18:
569 val = stat.meanLength();
570 break;
571 }
572 outputAttributes.append( val );
573 }
574 }
575 break;
576 }
577 }
578 }
579
580 f.setAttributes( outputAttributes );
581 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
582 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, u"OUTPUT"_s ) );
583 else
584 feedback->featureAddedToSink( u"OUTPUT"_s );
585 }
586 }
587
588 sink->finalize();
589 feedback->featureSinkFinalized( u"OUTPUT"_s );
590 sink.reset();
591
592 QVariantMap results;
593 results.insert( u"OUTPUT"_s, destId );
594 return results;
595}
596
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3749
@ NotPresent
No spatial index exists for the source.
Definition qgis.h:601
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:45
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.