QGIS API Documentation 4.1.0-Master (ca2ac17535b)
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 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
90 if ( !source )
91 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
92
93 const bool hasM = QgsWkbTypes::hasM( source->wkbType() );
94 const bool hasZ = QgsWkbTypes::hasZ( source->wkbType() );
95
99 if ( hasM )
100 {
101 pointType = QgsWkbTypes::addM( pointType );
102 lineType = QgsWkbTypes::addM( lineType );
103 polygonType = QgsWkbTypes::addM( polygonType );
104 }
105 if ( hasZ )
106 {
107 pointType = QgsWkbTypes::addZ( pointType );
108 lineType = QgsWkbTypes::addZ( lineType );
109 polygonType = QgsWkbTypes::addZ( polygonType );
110 }
111
112 QString pointSinkId;
113 std::unique_ptr<QgsFeatureSink> pointSink( parameterAsSink( parameters, u"POINTS"_s, context, pointSinkId, source->fields(), pointType, source->sourceCrs() ) );
114 if ( parameters.value( u"POINTS"_s, QVariant() ).isValid() && !pointSink )
115 throw QgsProcessingException( invalidSinkError( parameters, u"POINTS"_s ) );
116
117 QString lineSinkId;
118 std::unique_ptr<QgsFeatureSink> lineSink( parameterAsSink( parameters, u"LINES"_s, context, lineSinkId, source->fields(), lineType, source->sourceCrs() ) );
119 if ( parameters.value( u"LINES"_s, QVariant() ).isValid() && !lineSink )
120 throw QgsProcessingException( invalidSinkError( parameters, u"LINES"_s ) );
121
122 QString polygonSinkId;
123 std::unique_ptr<QgsFeatureSink> polygonSink( parameterAsSink( parameters, u"POLYGONS"_s, context, polygonSinkId, source->fields(), polygonType, source->sourceCrs() ) );
124 if ( parameters.value( u"POLYGONS"_s, QVariant() ).isValid() && !polygonSink )
125 throw QgsProcessingException( invalidSinkError( parameters, u"POLYGONS"_s ) );
126
127 QString noGeomSinkId;
128 std::unique_ptr<QgsFeatureSink> noGeomSink( parameterAsSink( parameters, u"NO_GEOMETRY"_s, context, noGeomSinkId, source->fields(), Qgis::WkbType::NoGeometry ) );
129 if ( parameters.value( u"NO_GEOMETRY"_s, QVariant() ).isValid() && !noGeomSink )
130 throw QgsProcessingException( invalidSinkError( parameters, u"NO_GEOMETRY"_s ) );
131
132 const long count = source->featureCount();
133 long long pointCount = 0;
134 long long lineCount = 0;
135 long long polygonCount = 0;
136 long long nullCount = 0;
137
138 const double step = count > 0 ? 100.0 / count : 1;
139 int current = 0;
140
141 QgsFeatureIterator it = source->getFeatures();
142 QgsFeature f;
143 while ( it.nextFeature( f ) )
144 {
145 if ( feedback->isCanceled() )
146 {
147 break;
148 }
149
150 if ( f.hasGeometry() )
151 {
152 switch ( f.geometry().type() )
153 {
155 if ( pointSink )
156 {
157 if ( !pointSink->addFeature( f, QgsFeatureSink::FastInsert ) )
158 throw QgsProcessingException( writeFeatureError( pointSink.get(), parameters, u"POINTS"_s ) );
159 else
160 feedback->featureAddedToSink( u"POINTS"_s );
161 }
162 pointCount++;
163 break;
165 if ( lineSink )
166 {
167 if ( !lineSink->addFeature( f, QgsFeatureSink::FastInsert ) )
168 throw QgsProcessingException( writeFeatureError( lineSink.get(), parameters, u"LINES"_s ) );
169 else
170 feedback->featureAddedToSink( u"LINES"_s );
171 }
172 lineCount++;
173 break;
175 if ( polygonSink )
176 {
177 if ( !polygonSink->addFeature( f, QgsFeatureSink::FastInsert ) )
178 throw QgsProcessingException( writeFeatureError( polygonSink.get(), parameters, u"POLYGONS"_s ) );
179 else
180 feedback->featureAddedToSink( u"POLYGONS"_s );
181 }
182 polygonCount++;
183 break;
186 break;
187 }
188 }
189 else
190 {
191 if ( noGeomSink )
192 {
193 if ( !noGeomSink->addFeature( f, QgsFeatureSink::FastInsert ) )
194 throw QgsProcessingException( writeFeatureError( noGeomSink.get(), parameters, u"NO_GEOMETRY"_s ) );
195 else
196 feedback->featureAddedToSink( u"NO_GEOMETRY"_s );
197 }
198 nullCount++;
199 }
200
201 feedback->setProgress( current * step );
202 current++;
203 }
204
205 QVariantMap outputs;
206
207 if ( pointSink )
208 {
209 pointSink->finalize();
210 feedback->featureSinkFinalized( u"POINTS"_s );
211 outputs.insert( u"POINTS"_s, pointSinkId );
212 }
213 if ( lineSink )
214 {
215 lineSink->finalize();
216 feedback->featureSinkFinalized( u"LINES"_s );
217 outputs.insert( u"LINES"_s, lineSinkId );
218 }
219 if ( polygonSink )
220 {
221 polygonSink->finalize();
222 feedback->featureSinkFinalized( u"POLYGONS"_s );
223 outputs.insert( u"POLYGONS"_s, polygonSinkId );
224 }
225 if ( noGeomSink )
226 {
227 feedback->featureSinkFinalized( u"NO_GEOMETRY"_s );
228 noGeomSink->finalize();
229 outputs.insert( u"NO_GEOMETRY"_s, noGeomSinkId );
230 }
231
232 outputs.insert( u"POINT_COUNT"_s, pointCount );
233 outputs.insert( u"LINE_COUNT"_s, lineCount );
234 outputs.insert( u"POLYGON_COUNT"_s, polygonCount );
235 outputs.insert( u"NO_GEOMETRY_COUNT"_s, nullCount );
236
237 return outputs;
238}
239
240
241//
242// QgsFilterByLayerTypeAlgorithm
243//
244
245QString QgsFilterByLayerTypeAlgorithm::name() const
246{
247 return u"filterlayersbytype"_s;
248}
249
250QString QgsFilterByLayerTypeAlgorithm::displayName() const
251{
252 return QObject::tr( "Filter layers by type" );
253}
254
255QStringList QgsFilterByLayerTypeAlgorithm::tags() const
256{
257 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
258}
259
260QString QgsFilterByLayerTypeAlgorithm::group() const
261{
262 return QObject::tr( "Modeler tools" );
263}
264
265QString QgsFilterByLayerTypeAlgorithm::groupId() const
266{
267 return u"modelertools"_s;
268}
269
270Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
271{
274 return f;
275}
276
277void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
278{
279 addParameter( new QgsProcessingParameterMapLayer( u"INPUT"_s, QObject::tr( "Input layer" ) ) );
280
281 addParameter( new QgsProcessingParameterVectorDestination( u"VECTOR"_s, QObject::tr( "Vector features" ), Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
282
283 addParameter( new QgsProcessingParameterRasterDestination( u"RASTER"_s, QObject::tr( "Raster layer" ), QVariant(), true, false ) );
284}
285
286QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
287{
288 return QObject::tr(
289 "This algorithm filters layer by their type. Incoming layers will be directed to different "
290 "outputs based on whether they are a vector or raster layer."
291 );
292}
293
294QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
295{
296 return QObject::tr( "Filters layers by type." );
297}
298
299QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
300{
301 return new QgsFilterByLayerTypeAlgorithm();
302}
303
304QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
305{
306 const QgsMapLayer *layer = parameterAsLayer( parameters, u"INPUT"_s, context );
307 if ( !layer )
308 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
309
310 QVariantMap outputs;
311
312 switch ( layer->type() )
313 {
315 outputs.insert( u"VECTOR"_s, parameters.value( u"INPUT"_s ) );
316 break;
317
319 outputs.insert( u"RASTER"_s, parameters.value( u"INPUT"_s ) );
320 break;
321
329 break;
330 }
331
332 return outputs;
333}
334
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3720
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3714
@ VectorPoint
Vector point layers.
Definition qgis.h:3715
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3717
@ VectorLine
Vector line layers.
Definition qgis.h:3716
@ 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:3791
@ 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:3765
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
Definition qgis.h:3775
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.