QGIS API Documentation 3.99.0-Master (09f76ad7019)
Loading...
Searching...
No Matches
qgsalgorithmfilterbygeometry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmfilterbygeometry.cpp
3 ---------------------
4 begin : March 2020
5 copyright : (C) 2020 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
20#include <QString>
21
22using namespace Qt::StringLiterals;
23
25
26QString QgsFilterByGeometryAlgorithm::name() const
27{
28 return u"filterbygeometry"_s;
29}
30
31QString QgsFilterByGeometryAlgorithm::displayName() const
32{
33 return QObject::tr( "Filter by geometry type" );
34}
35
36QStringList QgsFilterByGeometryAlgorithm::tags() const
37{
38 return QObject::tr( "extract,filter,geometry,linestring,point,polygon" ).split( ',' );
39}
40
41QString QgsFilterByGeometryAlgorithm::group() const
42{
43 return QObject::tr( "Vector selection" );
44}
45
46QString QgsFilterByGeometryAlgorithm::groupId() const
47{
48 return u"vectorselection"_s;
49}
50
51void QgsFilterByGeometryAlgorithm::initAlgorithm( const QVariantMap & )
52{
53 addParameter( new QgsProcessingParameterFeatureSource( u"INPUT"_s, QObject::tr( "Input layer" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector ) ) );
54
55 addParameter( new QgsProcessingParameterFeatureSink( u"POINTS"_s, QObject::tr( "Point features" ), Qgis::ProcessingSourceType::VectorPoint, QVariant(), true, true ) );
56
57 addParameter( new QgsProcessingParameterFeatureSink( u"LINES"_s, QObject::tr( "Line features" ), Qgis::ProcessingSourceType::VectorLine, QVariant(), true, true ) );
58
59 addParameter( new QgsProcessingParameterFeatureSink( u"POLYGONS"_s, QObject::tr( "Polygon features" ), Qgis::ProcessingSourceType::VectorPolygon, QVariant(), true, true ) );
60
61 addParameter( new QgsProcessingParameterFeatureSink( u"NO_GEOMETRY"_s, QObject::tr( "Features with no geometry" ), Qgis::ProcessingSourceType::Vector, QVariant(), true, true ) );
62
63 addOutput( new QgsProcessingOutputNumber( u"POINT_COUNT"_s, QObject::tr( "Total count of point features" ) ) );
64 addOutput( new QgsProcessingOutputNumber( u"LINE_COUNT"_s, QObject::tr( "Total count of line features" ) ) );
65 addOutput( new QgsProcessingOutputNumber( u"POLYGON_COUNT"_s, QObject::tr( "Total count of polygon features" ) ) );
66 addOutput( new QgsProcessingOutputNumber( u"NO_GEOMETRY_COUNT"_s, QObject::tr( "Total count of features without geometry" ) ) );
67}
68
69QString QgsFilterByGeometryAlgorithm::shortHelpString() const
70{
71 return QObject::tr( "This algorithm filters features by their geometry type. Incoming features will be directed to different "
72 "outputs based on whether they have a point, line or polygon geometry." );
73}
74
75QString QgsFilterByGeometryAlgorithm::shortDescription() const
76{
77 return QObject::tr( "Filters features by geometry type." );
78}
79
80QgsFilterByGeometryAlgorithm *QgsFilterByGeometryAlgorithm::createInstance() const
81{
82 return new QgsFilterByGeometryAlgorithm();
83}
84
85QVariantMap QgsFilterByGeometryAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
86{
87 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
88 if ( !source )
89 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
90
91 const bool hasM = QgsWkbTypes::hasM( source->wkbType() );
92 const bool hasZ = QgsWkbTypes::hasZ( source->wkbType() );
93
97 if ( hasM )
98 {
99 pointType = QgsWkbTypes::addM( pointType );
100 lineType = QgsWkbTypes::addM( lineType );
101 polygonType = QgsWkbTypes::addM( polygonType );
102 }
103 if ( hasZ )
104 {
105 pointType = QgsWkbTypes::addZ( pointType );
106 lineType = QgsWkbTypes::addZ( lineType );
107 polygonType = QgsWkbTypes::addZ( polygonType );
108 }
109
110 QString pointSinkId;
111 std::unique_ptr<QgsFeatureSink> pointSink( parameterAsSink( parameters, u"POINTS"_s, context, pointSinkId, source->fields(), pointType, source->sourceCrs() ) );
112 if ( parameters.value( u"POINTS"_s, QVariant() ).isValid() && !pointSink )
113 throw QgsProcessingException( invalidSinkError( parameters, u"POINTS"_s ) );
114
115 QString lineSinkId;
116 std::unique_ptr<QgsFeatureSink> lineSink( parameterAsSink( parameters, u"LINES"_s, context, lineSinkId, source->fields(), lineType, source->sourceCrs() ) );
117 if ( parameters.value( u"LINES"_s, QVariant() ).isValid() && !lineSink )
118 throw QgsProcessingException( invalidSinkError( parameters, u"LINES"_s ) );
119
120 QString polygonSinkId;
121 std::unique_ptr<QgsFeatureSink> polygonSink( parameterAsSink( parameters, u"POLYGONS"_s, context, polygonSinkId, source->fields(), polygonType, source->sourceCrs() ) );
122 if ( parameters.value( u"POLYGONS"_s, QVariant() ).isValid() && !polygonSink )
123 throw QgsProcessingException( invalidSinkError( parameters, u"POLYGONS"_s ) );
124
125 QString noGeomSinkId;
126 std::unique_ptr<QgsFeatureSink> noGeomSink( parameterAsSink( parameters, u"NO_GEOMETRY"_s, context, noGeomSinkId, source->fields(), Qgis::WkbType::NoGeometry ) );
127 if ( parameters.value( u"NO_GEOMETRY"_s, QVariant() ).isValid() && !noGeomSink )
128 throw QgsProcessingException( invalidSinkError( parameters, u"NO_GEOMETRY"_s ) );
129
130 const long count = source->featureCount();
131 long long pointCount = 0;
132 long long lineCount = 0;
133 long long polygonCount = 0;
134 long long nullCount = 0;
135
136 const double step = count > 0 ? 100.0 / count : 1;
137 int current = 0;
138
139 QgsFeatureIterator it = source->getFeatures();
140 QgsFeature f;
141 while ( it.nextFeature( f ) )
142 {
143 if ( feedback->isCanceled() )
144 {
145 break;
146 }
147
148 if ( f.hasGeometry() )
149 {
150 switch ( f.geometry().type() )
151 {
153 if ( pointSink )
154 {
155 if ( !pointSink->addFeature( f, QgsFeatureSink::FastInsert ) )
156 throw QgsProcessingException( writeFeatureError( pointSink.get(), parameters, u"POINTS"_s ) );
157 }
158 pointCount++;
159 break;
161 if ( lineSink )
162 {
163 if ( !lineSink->addFeature( f, QgsFeatureSink::FastInsert ) )
164 throw QgsProcessingException( writeFeatureError( lineSink.get(), parameters, u"LINES"_s ) );
165 }
166 lineCount++;
167 break;
169 if ( polygonSink )
170 {
171 if ( !polygonSink->addFeature( f, QgsFeatureSink::FastInsert ) )
172 throw QgsProcessingException( writeFeatureError( polygonSink.get(), parameters, u"POLYGONS"_s ) );
173 }
174 polygonCount++;
175 break;
178 break;
179 }
180 }
181 else
182 {
183 if ( noGeomSink )
184 {
185 if ( !noGeomSink->addFeature( f, QgsFeatureSink::FastInsert ) )
186 throw QgsProcessingException( writeFeatureError( noGeomSink.get(), parameters, u"NO_GEOMETRY"_s ) );
187 }
188 nullCount++;
189 }
190
191 feedback->setProgress( current * step );
192 current++;
193 }
194
195 QVariantMap outputs;
196
197 if ( pointSink )
198 {
199 pointSink->finalize();
200 outputs.insert( u"POINTS"_s, pointSinkId );
201 }
202 if ( lineSink )
203 {
204 lineSink->finalize();
205 outputs.insert( u"LINES"_s, lineSinkId );
206 }
207 if ( polygonSink )
208 {
209 polygonSink->finalize();
210 outputs.insert( u"POLYGONS"_s, polygonSinkId );
211 }
212 if ( noGeomSink )
213 {
214 noGeomSink->finalize();
215 outputs.insert( u"NO_GEOMETRY"_s, noGeomSinkId );
216 }
217
218 outputs.insert( u"POINT_COUNT"_s, pointCount );
219 outputs.insert( u"LINE_COUNT"_s, lineCount );
220 outputs.insert( u"POLYGON_COUNT"_s, polygonCount );
221 outputs.insert( u"NO_GEOMETRY_COUNT"_s, nullCount );
222
223 return outputs;
224}
225
226
227//
228// QgsFilterByLayerTypeAlgorithm
229//
230
231QString QgsFilterByLayerTypeAlgorithm::name() const
232{
233 return u"filterlayersbytype"_s;
234}
235
236QString QgsFilterByLayerTypeAlgorithm::displayName() const
237{
238 return QObject::tr( "Filter layers by type" );
239}
240
241QStringList QgsFilterByLayerTypeAlgorithm::tags() const
242{
243 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
244}
245
246QString QgsFilterByLayerTypeAlgorithm::group() const
247{
248 return QObject::tr( "Modeler tools" );
249}
250
251QString QgsFilterByLayerTypeAlgorithm::groupId() const
252{
253 return u"modelertools"_s;
254}
255
256Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
257{
260 return f;
261}
262
263void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
264{
265 addParameter( new QgsProcessingParameterMapLayer( u"INPUT"_s, QObject::tr( "Input layer" ) ) );
266
267 addParameter( new QgsProcessingParameterVectorDestination( u"VECTOR"_s, QObject::tr( "Vector features" ), Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
268
269 addParameter( new QgsProcessingParameterRasterDestination( u"RASTER"_s, QObject::tr( "Raster layer" ), QVariant(), true, false ) );
270}
271
272QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
273{
274 return QObject::tr( "This algorithm filters layer by their type. Incoming layers will be directed to different "
275 "outputs based on whether they are a vector or raster layer." );
276}
277
278QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
279{
280 return QObject::tr( "Filters layers by type." );
281}
282
283QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
284{
285 return new QgsFilterByLayerTypeAlgorithm();
286}
287
288QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
289{
290 const QgsMapLayer *layer = parameterAsLayer( parameters, u"INPUT"_s, context );
291 if ( !layer )
292 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
293
294 QVariantMap outputs;
295
296 switch ( layer->type() )
297 {
299 outputs.insert( u"VECTOR"_s, parameters.value( u"INPUT"_s ) );
300 break;
301
303 outputs.insert( u"RASTER"_s, parameters.value( u"INPUT"_s ) );
304 break;
305
313 break;
314 }
315
316 return outputs;
317}
318
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3610
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3604
@ VectorPoint
Vector point layers.
Definition qgis.h:3605
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3607
@ VectorLine
Vector line layers.
Definition qgis.h:3606
@ Point
Points.
Definition qgis.h:366
@ Line
Lines.
Definition qgis.h:367
@ Polygon
Polygons.
Definition qgis.h:368
@ Unknown
Unknown types.
Definition qgis.h:369
@ Null
No geometry.
Definition qgis.h:370
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3680
@ Group
Composite group layer. Added in QGIS 3.24.
Definition qgis.h:201
@ Plugin
Plugin based layer.
Definition qgis.h:196
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
Definition qgis.h:202
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
Definition qgis.h:199
@ Vector
Vector layer.
Definition qgis.h:194
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
Definition qgis.h:198
@ Mesh
Mesh layer. Added in QGIS 3.2.
Definition qgis.h:197
@ Raster
Raster layer.
Definition qgis.h:195
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
Definition qgis.h:200
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ Point
Point.
Definition qgis.h:282
@ LineString
LineString.
Definition qgis.h:283
@ Polygon
Polygon.
Definition qgis.h:284
@ NoGeometry
No geometry.
Definition qgis.h:298
@ HideFromToolbox
Algorithm should be hidden from the toolbox.
Definition qgis.h:3654
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
Definition qgis.h:3664
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.
@ 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
QgsGeometry geometry
Definition qgsfeature.h:71
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:55
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:63
Qgis::GeometryType type
Base class for all map layer types.
Definition qgsmaplayer.h:83
Qgis::LayerType type
Definition qgsmaplayer.h:93
virtual Qgis::ProcessingAlgorithmFlags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
A numeric output for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A map layer parameter for processing algorithms.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A vector layer destination parameter, for specifying the destination path for a vector layer created ...
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.