32void QgsJoinByLocationSummaryAlgorithm::initAlgorithm(
const QVariantMap & )
37 std::unique_ptr< QgsProcessingParameterEnum > predicateParam = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral(
"PREDICATE" ), QObject::tr(
"Where the features" ),
38 QgsJoinByLocationAlgorithm::translatedPredicates(),
true, 0 );
39 QVariantMap predicateMetadata;
40 QVariantMap widgetMetadata;
41 widgetMetadata.insert( QStringLiteral(
"useCheckBoxes" ),
true );
42 widgetMetadata.insert( QStringLiteral(
"columns" ), 2 );
43 predicateMetadata.insert( QStringLiteral(
"widget_wrapper" ), widgetMetadata );
44 predicateParam->setMetadata( predicateMetadata );
45 addParameter( predicateParam.release() );
51 QObject::tr(
"Fields to summarise (leave empty to use all fields)" ),
54 mAllSummaries << QObject::tr(
"count" )
55 << QObject::tr(
"unique" )
56 << QObject::tr(
"min" )
57 << QObject::tr(
"max" )
58 << QObject::tr(
"range" )
59 << QObject::tr(
"sum" )
60 << QObject::tr(
"mean" )
61 << QObject::tr(
"median" )
62 << QObject::tr(
"stddev" )
63 << QObject::tr(
"minority" )
64 << QObject::tr(
"majority" )
65 << QObject::tr(
"q1" )
66 << QObject::tr(
"q3" )
67 << QObject::tr(
"iqr" )
68 << QObject::tr(
"empty" )
69 << QObject::tr(
"filled" )
70 << QObject::tr(
"min_length" )
71 << QObject::tr(
"max_length" )
72 << QObject::tr(
"mean_length" );
74 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 );
75 addParameter( summaryParam.release() );
78 QObject::tr(
"Discard records which could not be joined" ),
83QString QgsJoinByLocationSummaryAlgorithm::name()
const
85 return QStringLiteral(
"joinbylocationsummary" );
88QString QgsJoinByLocationSummaryAlgorithm::displayName()
const
90 return QObject::tr(
"Join attributes by location (summary)" );
93QStringList QgsJoinByLocationSummaryAlgorithm::tags()
const
95 return QObject::tr(
"summary,aggregate,join,intersects,intersecting,touching,within,contains,overlaps,relation,spatial,"
96 "stats,statistics,sum,maximum,minimum,mean,average,standard,deviation,"
97 "count,distinct,unique,variance,median,quartile,range,majority,minority,histogram,distinct" ).split(
',' );
100QString QgsJoinByLocationSummaryAlgorithm::group()
const
102 return QObject::tr(
"Vector general" );
105QString QgsJoinByLocationSummaryAlgorithm::groupId()
const
107 return QStringLiteral(
"vectorgeneral" );
110QString QgsJoinByLocationSummaryAlgorithm::shortHelpString()
const
112 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"
113 "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"
114 "The algorithm calculates a statistical summary for the values from matching features in the second layer( e.g. maximum value, mean value, etc )." );
117QString QgsJoinByLocationSummaryAlgorithm::shortDescription()
const
119 return QObject::tr(
"Calculate summaries of attributes from one vector layer to another by location." );
122QIcon QgsJoinByLocationSummaryAlgorithm::icon()
const
127QString QgsJoinByLocationSummaryAlgorithm::svgIconPath()
const
132QgsJoinByLocationSummaryAlgorithm *QgsJoinByLocationSummaryAlgorithm::createInstance()
const
134 return new QgsJoinByLocationSummaryAlgorithm();
139 std::unique_ptr< QgsProcessingFeatureSource > baseSource( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
143 std::unique_ptr< QgsProcessingFeatureSource > joinSource( parameterAsSource( parameters, QStringLiteral(
"JOIN" ), context ) );
148 feedback->
reportError( QObject::tr(
"No spatial index exists for join layer, performance will be severely degraded" ) );
150 QStringList joinedFieldNames = parameterAsStrings( parameters, QStringLiteral(
"JOIN_FIELDS" ), context );
152 bool discardNonMatching = parameterAsBoolean( parameters, QStringLiteral(
"DISCARD_NONMATCHING" ), context );
154 QList< int > summaries = parameterAsEnums( parameters, QStringLiteral(
"SUMMARIES" ), context );
155 if ( summaries.empty() )
157 for (
int i = 0; i < mAllSummaries.size(); ++i )
161 QgsFields sourceFields = baseSource->fields();
163 QList< int > joinFieldIndices;
164 if ( joinedFieldNames.empty() )
167 for (
const QgsField &sourceField : joinSource->fields() )
169 joinedFieldNames.
append( sourceField.name() );
174 auto addFieldKeepType = [&fieldsToJoin](
const QgsField & original,
const QString & statistic )
178 fieldsToJoin.
append( field );
182 auto addFieldWithType = [&fieldsToJoin](
const QgsField & original,
const QString & statistic, QMetaType::Type type )
187 if ( type == QMetaType::Type::Double )
192 fieldsToJoin.
append( field );
201 QList< FieldType > fieldTypes;
203 struct FieldStatistic
205 FieldStatistic(
int enumIndex,
const QString &name, QMetaType::Type type )
206 : enumIndex( enumIndex )
213 QMetaType::Type type;
215 static const QVector< FieldStatistic > sNumericStats
217 FieldStatistic( 0, QStringLiteral(
"count" ), QMetaType::Type::LongLong ),
218 FieldStatistic( 1, QStringLiteral(
"unique" ), QMetaType::Type::LongLong ),
219 FieldStatistic( 2, QStringLiteral(
"min" ), QMetaType::Type::Double ),
220 FieldStatistic( 3, QStringLiteral(
"max" ), QMetaType::Type::Double ),
221 FieldStatistic( 4, QStringLiteral(
"range" ), QMetaType::Type::Double ),
222 FieldStatistic( 5, QStringLiteral(
"sum" ), QMetaType::Type::Double ),
223 FieldStatistic( 6, QStringLiteral(
"mean" ), QMetaType::Type::Double ),
224 FieldStatistic( 7, QStringLiteral(
"median" ), QMetaType::Type::Double ),
225 FieldStatistic( 8, QStringLiteral(
"stddev" ), QMetaType::Type::Double ),
226 FieldStatistic( 9, QStringLiteral(
"minority" ), QMetaType::Type::Double ),
227 FieldStatistic( 10, QStringLiteral(
"majority" ), QMetaType::Type::Double ),
228 FieldStatistic( 11, QStringLiteral(
"q1" ), QMetaType::Type::Double ),
229 FieldStatistic( 12, QStringLiteral(
"q3" ), QMetaType::Type::Double ),
230 FieldStatistic( 13, QStringLiteral(
"iqr" ), QMetaType::Type::Double ),
232 static const QVector< FieldStatistic > sDateTimeStats
234 FieldStatistic( 0, QStringLiteral(
"count" ), QMetaType::Type::LongLong ),
235 FieldStatistic( 1, QStringLiteral(
"unique" ), QMetaType::Type::LongLong ),
236 FieldStatistic( 14, QStringLiteral(
"empty" ), QMetaType::Type::LongLong ),
237 FieldStatistic( 15, QStringLiteral(
"filled" ), QMetaType::Type::LongLong ),
238 FieldStatistic( 2, QStringLiteral(
"min" ), QMetaType::Type::UnknownType ),
239 FieldStatistic( 3, QStringLiteral(
"max" ), QMetaType::Type::UnknownType ),
241 static const QVector< FieldStatistic > sStringStats
243 FieldStatistic( 0, QStringLiteral(
"count" ), QMetaType::Type::LongLong ),
244 FieldStatistic( 1, QStringLiteral(
"unique" ), QMetaType::Type::LongLong ),
245 FieldStatistic( 14, QStringLiteral(
"empty" ), QMetaType::Type::LongLong ),
246 FieldStatistic( 15, QStringLiteral(
"filled" ), QMetaType::Type::LongLong ),
247 FieldStatistic( 2, QStringLiteral(
"min" ), QMetaType::Type::UnknownType ),
248 FieldStatistic( 3, QStringLiteral(
"max" ), QMetaType::Type::UnknownType ),
249 FieldStatistic( 16, QStringLiteral(
"min_length" ), QMetaType::Type::Int ),
250 FieldStatistic( 17, QStringLiteral(
"max_length" ), QMetaType::Type::Int ),
251 FieldStatistic( 18, QStringLiteral(
"mean_length" ), QMetaType::Type::Double ),
254 for (
const QString &field : std::as_const( joinedFieldNames ) )
256 const int fieldIndex = joinSource->fields().lookupField( field );
257 if ( fieldIndex >= 0 )
259 joinFieldIndices.append( fieldIndex );
261 const QgsField joinField = joinSource->fields().at( fieldIndex );
262 QVector< FieldStatistic > statisticList;
265 fieldTypes.append( FieldType::Numeric );
266 statisticList = sNumericStats;
268 else if ( joinField.
type() == QMetaType::Type::QDate
269 || joinField.
type() == QMetaType::Type::QTime
270 || joinField.
type() == QMetaType::Type::QDateTime )
272 fieldTypes.append( FieldType::DateTime );
273 statisticList = sDateTimeStats;
277 fieldTypes.append( FieldType::String );
278 statisticList = sStringStats;
281 for (
const FieldStatistic &statistic : std::as_const( statisticList ) )
283 if ( summaries.contains( statistic.enumIndex ) )
285 if ( statistic.type != QMetaType::Type::UnknownType )
286 addFieldWithType( joinField, statistic.name, statistic.type );
288 addFieldKeepType( joinField, statistic.name );
297 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, destId, outputFields,
298 baseSource->wkbType(), baseSource->sourceCrs() ) );
304 QList<int> predicates = parameterAsEnums( parameters, QStringLiteral(
"PREDICATE" ), context );
305 QgsJoinByLocationAlgorithm::sortPredicates( predicates );
309 const double step = baseSource->featureCount() > 0 ? 100.0 / baseSource->featureCount() : 1;
318 if ( !discardNonMatching )
329 std::unique_ptr< QgsGeometryEngine > engine;
330 QVector< QVector< QVariant > > values;
347 engine->prepareGeometry();
350 if ( QgsJoinByLocationAlgorithm::featureFilter( testJoinFeature, engine.get(),
true, predicates ) )
353 joinAttributes.reserve( joinFieldIndices.size() );
354 for (
int joinIndex : std::as_const( joinFieldIndices ) )
356 joinAttributes.append( testJoinFeature.
attribute( joinIndex ) );
358 values.append( joinAttributes );
368 if ( values.empty() )
370 if ( discardNonMatching )
387 outputAttributes.reserve( outputFields.
size() );
388 for (
int fieldIndex = 0; fieldIndex < joinFieldIndices.size(); ++fieldIndex )
390 const FieldType &fieldType = fieldTypes.at( fieldIndex );
393 case FieldType::Numeric:
396 for (
const QVector< QVariant > &value : std::as_const( values ) )
401 for (
const FieldStatistic &statistic : sNumericStats )
403 if ( summaries.contains( statistic.enumIndex ) )
406 switch ( statistic.enumIndex )
451 if ( val.isValid() && std::isnan( val.toDouble() ) )
453 outputAttributes.append( val );
459 case FieldType::DateTime:
462 QVariantList inputValues;
463 inputValues.reserve( values.size() );
464 for (
const QVector< QVariant > &value : std::as_const( values ) )
466 inputValues << value.at( fieldIndex );
469 for (
const FieldStatistic &statistic : sDateTimeStats )
471 if ( summaries.contains( statistic.enumIndex ) )
474 switch ( statistic.enumIndex )
495 outputAttributes.append( val );
501 case FieldType::String:
504 QVariantList inputValues;
505 inputValues.reserve( values.size() );
506 for (
const QVector< QVariant > &value : std::as_const( values ) )
508 if ( value.at( fieldIndex ).isNull() )
511 stat.
addString( value.at( fieldIndex ).toString() );
514 for (
const FieldStatistic &statistic : sStringStats )
516 if ( summaries.contains( statistic.enumIndex ) )
519 switch ( statistic.enumIndex )
549 outputAttributes.append( val );
566 results.insert( QStringLiteral(
"OUTPUT" ), destId );
@ 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.
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...
void resizeAttributes(int fieldCount)
Resizes the attributes attached to this feature to the given number of fields.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
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.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
void setPrecision(int precision)
Set the field precision.
void setName(const QString &name)
Set the field name.
void setType(QMetaType::Type type)
Set variant type.
void setLength(int len)
Set the field length.
Container of fields for a vector layer.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
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.