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