QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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
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 {
204 pointSink->finalize();
205 outputs.insert( QStringLiteral( "POINTS" ), pointSinkId );
206 }
207 if ( lineSink )
208 {
209 lineSink->finalize();
210 outputs.insert( QStringLiteral( "LINES" ), lineSinkId );
211 }
212 if ( polygonSink )
213 {
214 polygonSink->finalize();
215 outputs.insert( QStringLiteral( "POLYGONS" ), polygonSinkId );
216 }
217 if ( noGeomSink )
218 {
219 noGeomSink->finalize();
220 outputs.insert( QStringLiteral( "NO_GEOMETRY" ), noGeomSinkId );
221 }
222
223 outputs.insert( QStringLiteral( "POINT_COUNT" ), pointCount );
224 outputs.insert( QStringLiteral( "LINE_COUNT" ), lineCount );
225 outputs.insert( QStringLiteral( "POLYGON_COUNT" ), polygonCount );
226 outputs.insert( QStringLiteral( "NO_GEOMETRY_COUNT" ), nullCount );
227
228 return outputs;
229}
230
231
232
233//
234// QgsFilterByLayerTypeAlgorithm
235//
236
237QString QgsFilterByLayerTypeAlgorithm::name() const
238{
239 return QStringLiteral( "filterlayersbytype" );
240}
241
242QString QgsFilterByLayerTypeAlgorithm::displayName() const
243{
244 return QObject::tr( "Filter layers by type" );
245}
246
247QStringList QgsFilterByLayerTypeAlgorithm::tags() const
248{
249 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
250}
251
252QString QgsFilterByLayerTypeAlgorithm::group() const
253{
254 return QObject::tr( "Modeler tools" );
255}
256
257QString QgsFilterByLayerTypeAlgorithm::groupId() const
258{
259 return QStringLiteral( "modelertools" );
260}
261
262Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
263{
266 return f;
267}
268
269void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
270{
271 addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
272
273 addParameter( new QgsProcessingParameterVectorDestination( QStringLiteral( "VECTOR" ), QObject::tr( "Vector features" ),
274 Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
275
276 addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "RASTER" ), QObject::tr( "Raster layer" ), QVariant(), true, false ) );
277}
278
279QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
280{
281 return QObject::tr( "This algorithm filters layer by their type. Incoming layers will be directed to different "
282 "outputs based on whether they are a vector or raster layer." );
283}
284
285QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
286{
287 return QObject::tr( "Filters layers by type" );
288}
289
290QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
291{
292 return new QgsFilterByLayerTypeAlgorithm();
293}
294
295QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
296{
297 const QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context );
298 if ( !layer )
299 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
300
301 QVariantMap outputs;
302
303 switch ( layer->type() )
304 {
306 outputs.insert( QStringLiteral( "VECTOR" ), parameters.value( QStringLiteral( "INPUT" ) ) );
307 break;
308
310 outputs.insert( QStringLiteral( "RASTER" ), parameters.value( QStringLiteral( "INPUT" ) ) );
311 break;
312
320 break;
321 }
322
323 return outputs;
324}
325
327
@ 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:3347
@ 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:256
@ 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:58
QgsGeometry geometry
Definition qgsfeature.h:69
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:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Qgis::GeometryType type
Base class for all map layer types.
Definition qgsmaplayer.h:76
Qgis::LayerType type
Definition qgsmaplayer.h:86
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 bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.