QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
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(
72 "This algorithm filters features by their geometry type. Incoming features will be directed to different "
73 "outputs based on whether they have a point, line or polygon geometry."
74 );
75}
76
77QString QgsFilterByGeometryAlgorithm::shortDescription() const
78{
79 return QObject::tr( "Filters features by geometry type." );
80}
81
82QgsFilterByGeometryAlgorithm *QgsFilterByGeometryAlgorithm::createInstance() const
83{
84 return new QgsFilterByGeometryAlgorithm();
85}
86
87QVariantMap QgsFilterByGeometryAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
88{
89 QGS_MARK_ALGORITHM_SOURCE
90
91 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
92 if ( !source )
93 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
94
95 const bool hasM = QgsWkbTypes::hasM( source->wkbType() );
96 const bool hasZ = QgsWkbTypes::hasZ( source->wkbType() );
97
101 if ( hasM )
102 {
103 pointType = QgsWkbTypes::addM( pointType );
104 lineType = QgsWkbTypes::addM( lineType );
105 polygonType = QgsWkbTypes::addM( polygonType );
106 }
107 if ( hasZ )
108 {
109 pointType = QgsWkbTypes::addZ( pointType );
110 lineType = QgsWkbTypes::addZ( lineType );
111 polygonType = QgsWkbTypes::addZ( polygonType );
112 }
113
114 QString pointSinkId;
115 std::unique_ptr<QgsFeatureSink> pointSink( parameterAsSink( parameters, u"POINTS"_s, context, pointSinkId, source->fields(), pointType, source->sourceCrs() ) );
116 if ( parameters.value( u"POINTS"_s, QVariant() ).isValid() && !pointSink )
117 throw QgsProcessingException( invalidSinkError( parameters, u"POINTS"_s ) );
118
119 QString lineSinkId;
120 std::unique_ptr<QgsFeatureSink> lineSink( parameterAsSink( parameters, u"LINES"_s, context, lineSinkId, source->fields(), lineType, source->sourceCrs() ) );
121 if ( parameters.value( u"LINES"_s, QVariant() ).isValid() && !lineSink )
122 throw QgsProcessingException( invalidSinkError( parameters, u"LINES"_s ) );
123
124 QString polygonSinkId;
125 std::unique_ptr<QgsFeatureSink> polygonSink( parameterAsSink( parameters, u"POLYGONS"_s, context, polygonSinkId, source->fields(), polygonType, source->sourceCrs() ) );
126 if ( parameters.value( u"POLYGONS"_s, QVariant() ).isValid() && !polygonSink )
127 throw QgsProcessingException( invalidSinkError( parameters, u"POLYGONS"_s ) );
128
129 QString noGeomSinkId;
130 std::unique_ptr<QgsFeatureSink> noGeomSink( parameterAsSink( parameters, u"NO_GEOMETRY"_s, context, noGeomSinkId, source->fields(), Qgis::WkbType::NoGeometry ) );
131 if ( parameters.value( u"NO_GEOMETRY"_s, QVariant() ).isValid() && !noGeomSink )
132 throw QgsProcessingException( invalidSinkError( parameters, u"NO_GEOMETRY"_s ) );
133
134 const long count = source->featureCount();
135 long long pointCount = 0;
136 long long lineCount = 0;
137 long long polygonCount = 0;
138 long long nullCount = 0;
139
140 const double step = count > 0 ? 100.0 / count : 1;
141 int current = 0;
142
143 QgsFeatureIterator it = source->getFeatures();
144 QgsFeature f;
145 while ( it.nextFeature( f ) )
146 {
147 if ( feedback->isCanceled() )
148 {
149 break;
150 }
151
152 if ( f.hasGeometry() )
153 {
154 switch ( f.geometry().type() )
155 {
157 if ( pointSink )
158 {
159 if ( !pointSink->addFeature( f, QgsFeatureSink::FastInsert ) )
160 throw QgsProcessingException( writeFeatureError( pointSink.get(), parameters, u"POINTS"_s ) );
161 else
162 feedback->featureAddedToSink( u"POINTS"_s );
163 }
164 pointCount++;
165 break;
167 if ( lineSink )
168 {
169 if ( !lineSink->addFeature( f, QgsFeatureSink::FastInsert ) )
170 throw QgsProcessingException( writeFeatureError( lineSink.get(), parameters, u"LINES"_s ) );
171 else
172 feedback->featureAddedToSink( u"LINES"_s );
173 }
174 lineCount++;
175 break;
177 if ( polygonSink )
178 {
179 if ( !polygonSink->addFeature( f, QgsFeatureSink::FastInsert ) )
180 throw QgsProcessingException( writeFeatureError( polygonSink.get(), parameters, u"POLYGONS"_s ) );
181 else
182 feedback->featureAddedToSink( u"POLYGONS"_s );
183 }
184 polygonCount++;
185 break;
188 break;
189 }
190 }
191 else
192 {
193 if ( noGeomSink )
194 {
195 if ( !noGeomSink->addFeature( f, QgsFeatureSink::FastInsert ) )
196 throw QgsProcessingException( writeFeatureError( noGeomSink.get(), parameters, u"NO_GEOMETRY"_s ) );
197 else
198 feedback->featureAddedToSink( u"NO_GEOMETRY"_s );
199 }
200 nullCount++;
201 }
202
203 feedback->setProgress( current * step );
204 current++;
205 }
206
207 QVariantMap outputs;
208
209 if ( pointSink )
210 {
211 pointSink->finalize();
212 feedback->featureSinkFinalized( u"POINTS"_s );
213 outputs.insert( u"POINTS"_s, pointSinkId );
214 }
215 if ( lineSink )
216 {
217 lineSink->finalize();
218 feedback->featureSinkFinalized( u"LINES"_s );
219 outputs.insert( u"LINES"_s, lineSinkId );
220 }
221 if ( polygonSink )
222 {
223 polygonSink->finalize();
224 feedback->featureSinkFinalized( u"POLYGONS"_s );
225 outputs.insert( u"POLYGONS"_s, polygonSinkId );
226 }
227 if ( noGeomSink )
228 {
229 feedback->featureSinkFinalized( u"NO_GEOMETRY"_s );
230 noGeomSink->finalize();
231 outputs.insert( u"NO_GEOMETRY"_s, noGeomSinkId );
232 }
233
234 outputs.insert( u"POINT_COUNT"_s, pointCount );
235 outputs.insert( u"LINE_COUNT"_s, lineCount );
236 outputs.insert( u"POLYGON_COUNT"_s, polygonCount );
237 outputs.insert( u"NO_GEOMETRY_COUNT"_s, nullCount );
238
239 return outputs;
240}
241
242
243//
244// QgsFilterByLayerTypeAlgorithm
245//
246
247QString QgsFilterByLayerTypeAlgorithm::name() const
248{
249 return u"filterlayersbytype"_s;
250}
251
252QString QgsFilterByLayerTypeAlgorithm::displayName() const
253{
254 return QObject::tr( "Filter layers by type" );
255}
256
257QStringList QgsFilterByLayerTypeAlgorithm::tags() const
258{
259 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
260}
261
262QString QgsFilterByLayerTypeAlgorithm::group() const
263{
264 return QObject::tr( "Modeler tools" );
265}
266
267QString QgsFilterByLayerTypeAlgorithm::groupId() const
268{
269 return u"modelertools"_s;
270}
271
272Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
273{
276 return f;
277}
278
279void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
280{
281 addParameter( new QgsProcessingParameterMapLayer( u"INPUT"_s, QObject::tr( "Input layer" ) ) );
282
283 addParameter( new QgsProcessingParameterVectorDestination( u"VECTOR"_s, QObject::tr( "Vector features" ), Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
284
285 addParameter( new QgsProcessingParameterRasterDestination( u"RASTER"_s, QObject::tr( "Raster layer" ), QVariant(), true, false ) );
286}
287
288QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
289{
290 return QObject::tr(
291 "This algorithm filters layer by their type. Incoming layers will be directed to different "
292 "outputs based on whether they are a vector or raster layer."
293 );
294}
295
296QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
297{
298 return QObject::tr( "Filters layers by type." );
299}
300
301QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
302{
303 return new QgsFilterByLayerTypeAlgorithm();
304}
305
306QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
307{
308 const QgsMapLayer *layer = parameterAsLayer( parameters, u"INPUT"_s, context );
309 if ( !layer )
310 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
311
312 QVariantMap outputs;
313
314 switch ( layer->type() )
315 {
317 outputs.insert( u"VECTOR"_s, parameters.value( u"INPUT"_s ) );
318 break;
319
321 outputs.insert( u"RASTER"_s, parameters.value( u"INPUT"_s ) );
322 break;
323
331 break;
332 }
333
334 return outputs;
335}
336
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3755
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3749
@ VectorPoint
Vector point layers.
Definition qgis.h:3750
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3752
@ VectorLine
Vector line layers.
Definition qgis.h:3751
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Unknown
Unknown types.
Definition qgis.h:383
@ Null
No geometry.
Definition qgis.h:384
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3826
@ Group
Composite group layer. Added in QGIS 3.24.
Definition qgis.h:214
@ Plugin
Plugin based layer.
Definition qgis.h:209
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
Definition qgis.h:215
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
Definition qgis.h:212
@ Vector
Vector layer.
Definition qgis.h:207
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
Definition qgis.h:211
@ Mesh
Mesh layer. Added in QGIS 3.2.
Definition qgis.h:210
@ Raster
Raster layer.
Definition qgis.h:208
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
Definition qgis.h:213
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ Point
Point.
Definition qgis.h:296
@ LineString
LineString.
Definition qgis.h:297
@ Polygon
Polygon.
Definition qgis.h:298
@ NoGeometry
No geometry.
Definition qgis.h:312
@ HideFromToolbox
Algorithm should be hidden from the toolbox.
Definition qgis.h:3800
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
Definition qgis.h:3810
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:66
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:56
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:65
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.
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.
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.