QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
qgsalgorithmkeepnbiggestparts.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmkeepnbiggestparts.cpp
3 ---------------------
4 begin : July 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 "qgsmultipolygon.h"
22#include "qgsmultisurface.h"
23
24#include <queue>
25
27
28QString QgsKeepNBiggestPartsAlgorithm::name() const
29{
30 return QStringLiteral( "keepnbiggestparts" );
31}
32
33QString QgsKeepNBiggestPartsAlgorithm::displayName() const
34{
35 return QObject::tr( "Keep N biggest parts" );
36}
37
38QStringList QgsKeepNBiggestPartsAlgorithm::tags() const
39{
40 return QObject::tr( "remove,delete,drop,largest,area,filter" ).split( ',' );
41}
42
43QString QgsKeepNBiggestPartsAlgorithm::group() const
44{
45 return QObject::tr( "Vector geometry" );
46}
47
48QString QgsKeepNBiggestPartsAlgorithm::groupId() const
49{
50 return QStringLiteral( "vectorgeometry" );
51}
52
53QString QgsKeepNBiggestPartsAlgorithm::outputName() const
54{
55 return QObject::tr( "Parts" );
56}
57
58QList<int> QgsKeepNBiggestPartsAlgorithm::inputLayerTypes() const
59{
60 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorPolygon );
61}
62
63Qgis::ProcessingSourceType QgsKeepNBiggestPartsAlgorithm::outputLayerType() const
64{
66}
67
68QString QgsKeepNBiggestPartsAlgorithm::shortHelpString() const
69{
70 return QObject::tr( "This algorithm takes a polygon layer and creates a new polygon layer in which multipart "
71 "geometries have been removed, leaving only the n largest (in terms of area) parts." );
72}
73
74QString QgsKeepNBiggestPartsAlgorithm::shortDescription() const
75{
76 return QObject::tr( "Creates a polygon layer in which multipart geometries have been removed, "
77 "leaving only the n largest (in terms of area) parts." );
78}
79
80QgsKeepNBiggestPartsAlgorithm *QgsKeepNBiggestPartsAlgorithm::createInstance() const
81{
82 return new QgsKeepNBiggestPartsAlgorithm();
83}
84
85Qgis::ProcessingFeatureSourceFlags QgsKeepNBiggestPartsAlgorithm::sourceFlags() const
86{
87 // skip geometry checks - this algorithm can be used to repair geometries
89}
90
91void QgsKeepNBiggestPartsAlgorithm::initParameters( const QVariantMap & )
92{
93 auto partsToKeep = std::make_unique<QgsProcessingParameterNumber>( QStringLiteral( "PARTS" ), QObject::tr( "Parts to keep" ), Qgis::ProcessingNumberParameterType::Integer, 1.0, false, 1.0 );
94 partsToKeep->setIsDynamic( true );
95 partsToKeep->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "PARTS" ), QObject::tr( "Parts to keep" ), QgsPropertyDefinition::IntegerPositive ) );
96 partsToKeep->setDynamicLayerParameterName( QStringLiteral( "POLYGONS" ) );
97 addParameter( partsToKeep.release() );
98}
99
100QString QgsKeepNBiggestPartsAlgorithm::inputParameterName() const
101{
102 return QStringLiteral( "POLYGONS" );
103}
104
105bool QgsKeepNBiggestPartsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
106{
107 mPartsToKeep = parameterAsInt( parameters, QStringLiteral( "PARTS" ), context );
108 mDynamicPartsToKeep = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "PARTS" ) );
109 if ( mDynamicPartsToKeep )
110 mPartsToKeepProperty = parameters.value( QStringLiteral( "PARTS" ) ).value<QgsProperty>();
111
112 return true;
113}
114
115QgsFeatureList QgsKeepNBiggestPartsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
116{
117 QgsFeature f = feature;
118 if ( f.hasGeometry() )
119 {
120 const QgsGeometry geometry = f.geometry();
121
122 QgsGeometry outputGeometry;
123
125 {
126 int nPartsToKeep = mPartsToKeep;
127 if ( mDynamicPartsToKeep )
128 nPartsToKeep = mPartsToKeepProperty.valueAsInt( context.expressionContext(), nPartsToKeep );
129
130 const int numParts = collection->numGeometries();
131 if ( nPartsToKeep >= numParts )
132 {
133 // nothing to do
134 outputGeometry = geometry;
135 }
136 else
137 {
138 struct GreaterThanByArea
139 {
140 bool operator()( const QgsAbstractGeometry *lhs, const QgsAbstractGeometry *rhs ) const
141 {
142 return lhs->area() < rhs->area();
143 }
144 };
145
146 std::unique_ptr<QgsMultiSurface> res = QgsWkbTypes::isCurvedType( collection->wkbType() ) ? std::make_unique<QgsMultiSurface>() : std::make_unique<QgsMultiPolygon>();
147 std::priority_queue<const QgsAbstractGeometry *, std::vector<const QgsAbstractGeometry *>, GreaterThanByArea> areaQueue;
148 for ( int i = 0; i < numParts; ++i )
149 {
150 areaQueue.push( collection->geometryN( i ) );
151 }
152
153 for ( int i = 0; i < nPartsToKeep; ++i )
154 {
155 const QgsAbstractGeometry *part = areaQueue.top();
156 areaQueue.pop();
157 res->addGeometry( part->clone() );
158 }
159
160 outputGeometry = QgsGeometry( std::move( res ) );
161 }
162 }
163 else
164 {
165 outputGeometry = geometry;
166 outputGeometry.convertToMultiType();
167 }
168
169 f.setGeometry( outputGeometry );
170 }
171 return QgsFeatureList() << f;
172}
173
174
ProcessingSourceType
Processing data source types.
Definition qgis.h:3531
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3536
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3711
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3722
Abstract base class for all geometries.
virtual double area() const
Returns the planar, 2-dimensional area of the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Multi polygon geometry collection.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
Base class for providing feedback from a processing algorithm.
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...
Definition for a property.
Definition qgsproperty.h:45
@ IntegerPositive
Positive integer values (including 0).
Definition qgsproperty.h:53
A store for object properties.
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QList< QgsFeature > QgsFeatureList