QGIS API Documentation 3.41.0-Master (af5edcb665c)
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" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::Vector ) ) );
50
51 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "POINTS" ), QObject::tr( "Point features" ), Qgis::ProcessingSourceType::VectorPoint, QVariant(), true, true ) );
52
53 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "LINES" ), QObject::tr( "Line features" ), Qgis::ProcessingSourceType::VectorLine, QVariant(), true, true ) );
54
55 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "POLYGONS" ), QObject::tr( "Polygon features" ), Qgis::ProcessingSourceType::VectorPolygon, QVariant(), true, true ) );
56
57 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "NO_GEOMETRY" ), QObject::tr( "Features with no geometry" ), Qgis::ProcessingSourceType::Vector, QVariant(), true, true ) );
58
59 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "POINT_COUNT" ), QObject::tr( "Total count of point features" ) ) );
60 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "LINE_COUNT" ), QObject::tr( "Total count of line features" ) ) );
61 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "POLYGON_COUNT" ), QObject::tr( "Total count of polygon features" ) ) );
62 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "NO_GEOMETRY_COUNT" ), QObject::tr( "Total count of features without geometry" ) ) );
63}
64
65QString QgsFilterByGeometryAlgorithm::shortHelpString() const
66{
67 return QObject::tr( "This algorithm filters features by their geometry type. Incoming features will be directed to different "
68 "outputs based on whether they have a point, line or polygon geometry." );
69}
70
71QString QgsFilterByGeometryAlgorithm::shortDescription() const
72{
73 return QObject::tr( "Filters features by geometry type" );
74}
75
76QgsFilterByGeometryAlgorithm *QgsFilterByGeometryAlgorithm::createInstance() const
77{
78 return new QgsFilterByGeometryAlgorithm();
79}
80
81QVariantMap QgsFilterByGeometryAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
82{
83 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
84 if ( !source )
85 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
86
87 const bool hasM = QgsWkbTypes::hasM( source->wkbType() );
88 const bool hasZ = QgsWkbTypes::hasZ( source->wkbType() );
89
93 if ( hasM )
94 {
95 pointType = QgsWkbTypes::addM( pointType );
96 lineType = QgsWkbTypes::addM( lineType );
97 polygonType = QgsWkbTypes::addM( polygonType );
98 }
99 if ( hasZ )
100 {
101 pointType = QgsWkbTypes::addZ( pointType );
102 lineType = QgsWkbTypes::addZ( lineType );
103 polygonType = QgsWkbTypes::addZ( polygonType );
104 }
105
106 QString pointSinkId;
107 std::unique_ptr<QgsFeatureSink> pointSink( parameterAsSink( parameters, QStringLiteral( "POINTS" ), context, pointSinkId, source->fields(), pointType, source->sourceCrs() ) );
108 if ( parameters.value( QStringLiteral( "POINTS" ), QVariant() ).isValid() && !pointSink )
109 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "POINTS" ) ) );
110
111 QString lineSinkId;
112 std::unique_ptr<QgsFeatureSink> lineSink( parameterAsSink( parameters, QStringLiteral( "LINES" ), context, lineSinkId, source->fields(), lineType, source->sourceCrs() ) );
113 if ( parameters.value( QStringLiteral( "LINES" ), QVariant() ).isValid() && !lineSink )
114 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "LINES" ) ) );
115
116 QString polygonSinkId;
117 std::unique_ptr<QgsFeatureSink> polygonSink( parameterAsSink( parameters, QStringLiteral( "POLYGONS" ), context, polygonSinkId, source->fields(), polygonType, source->sourceCrs() ) );
118 if ( parameters.value( QStringLiteral( "POLYGONS" ), QVariant() ).isValid() && !polygonSink )
119 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "POLYGONS" ) ) );
120
121 QString noGeomSinkId;
122 std::unique_ptr<QgsFeatureSink> noGeomSink( parameterAsSink( parameters, QStringLiteral( "NO_GEOMETRY" ), context, noGeomSinkId, source->fields(), Qgis::WkbType::NoGeometry ) );
123 if ( parameters.value( QStringLiteral( "NO_GEOMETRY" ), QVariant() ).isValid() && !noGeomSink )
124 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "NO_GEOMETRY" ) ) );
125
126 const long count = source->featureCount();
127 long long pointCount = 0;
128 long long lineCount = 0;
129 long long polygonCount = 0;
130 long long nullCount = 0;
131
132 const double step = count > 0 ? 100.0 / count : 1;
133 int current = 0;
134
135 QgsFeatureIterator it = source->getFeatures();
136 QgsFeature f;
137 while ( it.nextFeature( f ) )
138 {
139 if ( feedback->isCanceled() )
140 {
141 break;
142 }
143
144 if ( f.hasGeometry() )
145 {
146 switch ( f.geometry().type() )
147 {
149 if ( pointSink )
150 {
151 if ( !pointSink->addFeature( f, QgsFeatureSink::FastInsert ) )
152 throw QgsProcessingException( writeFeatureError( pointSink.get(), parameters, QStringLiteral( "POINTS" ) ) );
153 }
154 pointCount++;
155 break;
157 if ( lineSink )
158 {
159 if ( !lineSink->addFeature( f, QgsFeatureSink::FastInsert ) )
160 throw QgsProcessingException( writeFeatureError( lineSink.get(), parameters, QStringLiteral( "LINES" ) ) );
161 }
162 lineCount++;
163 break;
165 if ( polygonSink )
166 {
167 if ( !polygonSink->addFeature( f, QgsFeatureSink::FastInsert ) )
168 throw QgsProcessingException( writeFeatureError( polygonSink.get(), parameters, QStringLiteral( "POLYGONS" ) ) );
169 }
170 polygonCount++;
171 break;
174 break;
175 }
176 }
177 else
178 {
179 if ( noGeomSink )
180 {
181 if ( !noGeomSink->addFeature( f, QgsFeatureSink::FastInsert ) )
182 throw QgsProcessingException( writeFeatureError( noGeomSink.get(), parameters, QStringLiteral( "NO_GEOMETRY" ) ) );
183 }
184 nullCount++;
185 }
186
187 feedback->setProgress( current * step );
188 current++;
189 }
190
191 QVariantMap outputs;
192
193 if ( pointSink )
194 {
195 pointSink->finalize();
196 outputs.insert( QStringLiteral( "POINTS" ), pointSinkId );
197 }
198 if ( lineSink )
199 {
200 lineSink->finalize();
201 outputs.insert( QStringLiteral( "LINES" ), lineSinkId );
202 }
203 if ( polygonSink )
204 {
205 polygonSink->finalize();
206 outputs.insert( QStringLiteral( "POLYGONS" ), polygonSinkId );
207 }
208 if ( noGeomSink )
209 {
210 noGeomSink->finalize();
211 outputs.insert( QStringLiteral( "NO_GEOMETRY" ), noGeomSinkId );
212 }
213
214 outputs.insert( QStringLiteral( "POINT_COUNT" ), pointCount );
215 outputs.insert( QStringLiteral( "LINE_COUNT" ), lineCount );
216 outputs.insert( QStringLiteral( "POLYGON_COUNT" ), polygonCount );
217 outputs.insert( QStringLiteral( "NO_GEOMETRY_COUNT" ), nullCount );
218
219 return outputs;
220}
221
222
223//
224// QgsFilterByLayerTypeAlgorithm
225//
226
227QString QgsFilterByLayerTypeAlgorithm::name() const
228{
229 return QStringLiteral( "filterlayersbytype" );
230}
231
232QString QgsFilterByLayerTypeAlgorithm::displayName() const
233{
234 return QObject::tr( "Filter layers by type" );
235}
236
237QStringList QgsFilterByLayerTypeAlgorithm::tags() const
238{
239 return QObject::tr( "filter,vector,raster,select" ).split( ',' );
240}
241
242QString QgsFilterByLayerTypeAlgorithm::group() const
243{
244 return QObject::tr( "Modeler tools" );
245}
246
247QString QgsFilterByLayerTypeAlgorithm::groupId() const
248{
249 return QStringLiteral( "modelertools" );
250}
251
252Qgis::ProcessingAlgorithmFlags QgsFilterByLayerTypeAlgorithm::flags() const
253{
256 return f;
257}
258
259void QgsFilterByLayerTypeAlgorithm::initAlgorithm( const QVariantMap & )
260{
261 addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
262
263 addParameter( new QgsProcessingParameterVectorDestination( QStringLiteral( "VECTOR" ), QObject::tr( "Vector features" ), Qgis::ProcessingSourceType::VectorAnyGeometry, QVariant(), true, false ) );
264
265 addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "RASTER" ), QObject::tr( "Raster layer" ), QVariant(), true, false ) );
266}
267
268QString QgsFilterByLayerTypeAlgorithm::shortHelpString() const
269{
270 return QObject::tr( "This algorithm filters layer by their type. Incoming layers will be directed to different "
271 "outputs based on whether they are a vector or raster layer." );
272}
273
274QString QgsFilterByLayerTypeAlgorithm::shortDescription() const
275{
276 return QObject::tr( "Filters layers by type" );
277}
278
279QgsFilterByLayerTypeAlgorithm *QgsFilterByLayerTypeAlgorithm::createInstance() const
280{
281 return new QgsFilterByLayerTypeAlgorithm();
282}
283
284QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
285{
286 const QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context );
287 if ( !layer )
288 throw QgsProcessingException( QObject::tr( "Could not load input layer" ) );
289
290 QVariantMap outputs;
291
292 switch ( layer->type() )
293 {
295 outputs.insert( QStringLiteral( "VECTOR" ), parameters.value( QStringLiteral( "INPUT" ) ) );
296 break;
297
299 outputs.insert( QStringLiteral( "RASTER" ), parameters.value( QStringLiteral( "INPUT" ) ) );
300 break;
301
309 break;
310 }
311
312 return outputs;
313}
314
@ 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:3410
@ 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.