QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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 }
160 pointCount++;
161 break;
163 if ( lineSink )
164 {
165 if ( !lineSink->addFeature( f, QgsFeatureSink::FastInsert ) )
166 throw QgsProcessingException( writeFeatureError( lineSink.get(), parameters, u"LINES"_s ) );
167 }
168 lineCount++;
169 break;
171 if ( polygonSink )
172 {
173 if ( !polygonSink->addFeature( f, QgsFeatureSink::FastInsert ) )
174 throw QgsProcessingException( writeFeatureError( polygonSink.get(), parameters, u"POLYGONS"_s ) );
175 }
176 polygonCount++;
177 break;
180 break;
181 }
182 }
183 else
184 {
185 if ( noGeomSink )
186 {
187 if ( !noGeomSink->addFeature( f, QgsFeatureSink::FastInsert ) )
188 throw QgsProcessingException( writeFeatureError( noGeomSink.get(), parameters, u"NO_GEOMETRY"_s ) );
189 }
190 nullCount++;
191 }
192
193 feedback->setProgress( current * step );
194 current++;
195 }
196
197 QVariantMap outputs;
198
199 if ( pointSink )
200 {
201 pointSink->finalize();
202 outputs.insert( u"POINTS"_s, pointSinkId );
203 }
204 if ( lineSink )
205 {
206 lineSink->finalize();
207 outputs.insert( u"LINES"_s, lineSinkId );
208 }
209 if ( polygonSink )
210 {
211 polygonSink->finalize();
212 outputs.insert( u"POLYGONS"_s, polygonSinkId );
213 }
214 if ( noGeomSink )
215 {
216 noGeomSink->finalize();
217 outputs.insert( u"NO_GEOMETRY"_s, noGeomSinkId );
218 }
219
220 outputs.insert( u"POINT_COUNT"_s, pointCount );
221 outputs.insert( u"LINE_COUNT"_s, lineCount );
222 outputs.insert( u"POLYGON_COUNT"_s, polygonCount );
223 outputs.insert( u"NO_GEOMETRY_COUNT"_s, nullCount );
224
225 return outputs;
226}
227
228
229//
230// QgsFilterByLayerTypeAlgorithm
231//
232
233QString QgsFilterByLayerTypeAlgorithm::name() const
234{
235 return u"filterlayersbytype"_s;
236}
237
238QString QgsFilterByLayerTypeAlgorithm::displayName() const
239{
240 return QObject::tr( "Filter layers by type" );
241}
242
243QStringList QgsFilterByLayerTypeAlgorithm::tags() const
244{
245 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
246}
247
248QString QgsFilterByLayerTypeAlgorithm::group() const
249{
250 return QObject::tr( "Modeler tools" );
251}
252
253QString QgsFilterByLayerTypeAlgorithm::groupId() const
254{
255 return u"modelertools"_s;
256}
257
258Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
259{
262 return f;
263}
264
265void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
266{
267 addParameter( new QgsProcessingParameterMapLayer( u"INPUT"_s, QObject::tr( "Input layer" ) ) );
268
269 addParameter( new QgsProcessingParameterVectorDestination( u"VECTOR"_s, QObject::tr( "Vector features" ), Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
270
271 addParameter( new QgsProcessingParameterRasterDestination( u"RASTER"_s, QObject::tr( "Raster layer" ), QVariant(), true, false ) );
272}
273
274QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
275{
276 return QObject::tr(
277 "This algorithm filters layer by their type. Incoming layers will be directed to different "
278 "outputs based on whether they are a vector or raster layer."
279 );
280}
281
282QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
283{
284 return QObject::tr( "Filters layers by type." );
285}
286
287QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
288{
289 return new QgsFilterByLayerTypeAlgorithm();
290}
291
292QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
293{
294 const QgsMapLayer *layer = parameterAsLayer( parameters, u"INPUT"_s, context );
295 if ( !layer )
296 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
297
298 QVariantMap outputs;
299
300 switch ( layer->type() )
301 {
303 outputs.insert( u"VECTOR"_s, parameters.value( u"INPUT"_s ) );
304 break;
305
307 outputs.insert( u"RASTER"_s, parameters.value( u"INPUT"_s ) );
308 break;
309
317 break;
318 }
319
320 return outputs;
321}
322
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition qgis.h:3653
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3647
@ VectorPoint
Vector point layers.
Definition qgis.h:3648
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3650
@ VectorLine
Vector line layers.
Definition qgis.h:3649
@ 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:3724
@ 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:3698
@ PruneModelBranchesBasedOnAlgorithmResults
Algorithm results will cause remaining model branches to be pruned based on the results of running th...
Definition qgis.h:3708
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: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.
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.