QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsalgorithmextractbylocation.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmextractbylocation.cpp
3 ---------------------
4 begin : April 2017
5 copyright : (C) 2017 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#include "qgsgeometryengine.h"
20#include "qgsvectorlayer.h"
22
24
25void QgsLocationBasedAlgorithm::addPredicateParameter()
26{
27 std::unique_ptr<QgsProcessingParameterEnum> predicateParam( new QgsProcessingParameterEnum( QStringLiteral( "PREDICATE" ), QObject::tr( "Where the features (geometric predicate)" ), predicateOptionsList(), true, QVariant::fromValue( QList<int>() << 0 ) ) );
28
29 QVariantMap predicateMetadata;
30 QVariantMap widgetMetadata;
31 widgetMetadata.insert( QStringLiteral( "useCheckBoxes" ), true );
32 widgetMetadata.insert( QStringLiteral( "columns" ), 2 );
33 predicateMetadata.insert( QStringLiteral( "widget_wrapper" ), widgetMetadata );
34 predicateParam->setMetadata( predicateMetadata );
35
36 addParameter( predicateParam.release() );
37}
38
39QgsLocationBasedAlgorithm::Predicate QgsLocationBasedAlgorithm::reversePredicate( QgsLocationBasedAlgorithm::Predicate predicate ) const
40{
41 switch ( predicate )
42 {
43 case Intersects:
44 return Intersects;
45 case Contains:
46 return Within;
47 case Disjoint:
48 return Disjoint;
49 case IsEqual:
50 return IsEqual;
51 case Touches:
52 return Touches;
53 case Overlaps:
54 return Overlaps;
55 case Within:
56 return Contains;
57 case Crosses:
58 return Crosses;
59 }
60 // no warnings
61 return Intersects;
62}
63
64QStringList QgsLocationBasedAlgorithm::predicateOptionsList() const
65{
66 return QStringList() << QObject::tr( "intersect" )
67 << QObject::tr( "contain" )
68 << QObject::tr( "disjoint" )
69 << QObject::tr( "equal" )
70 << QObject::tr( "touch" )
71 << QObject::tr( "overlap" )
72 << QObject::tr( "are within" )
73 << QObject::tr( "cross" );
74}
75
76void QgsLocationBasedAlgorithm::process( const QgsProcessingContext &context, QgsFeatureSource *targetSource, QgsFeatureSource *intersectSource, const QList<int> &selectedPredicates, const std::function<void( const QgsFeature & )> &handleFeatureFunction, bool onlyRequireTargetIds, QgsProcessingFeedback *feedback, const QgsFeatureIds &skipTargetFeatureIds )
77{
78 // skip if there are no features to select from!
79 if ( mTargetFeatureCount == 0 )
80 return;
81
82 // skip if intersect layer is empty, unless we are looking for disjoints
83 if ( mIntersectFeatureCount == 0 && !selectedPredicates.contains( Disjoint ) )
84 return;
85
86 if ( mTargetFeatureCount > 0 && mIntersectFeatureCount > 0 && mTargetFeatureCount < mIntersectFeatureCount )
87 {
88 // joining FEWER features to a layer with MORE features. So we iterate over the FEW features and find matches from the MANY
89 processByIteratingOverTargetSource( context, targetSource, intersectSource, selectedPredicates, handleFeatureFunction, onlyRequireTargetIds, feedback, skipTargetFeatureIds );
90 }
91 else
92 {
93 // default -- iterate over the intersect source and match back to the target source. We do this on the assumption that the most common
94 // use case is joining a points layer to a polygon layer (e.g. findings points within a polygon), so by iterating
95 // over the polygons we can take advantage of prepared geometries for the spatial relationship test.
96
97 // TODO - consider using more heuristics to determine whether it's always best to iterate over the intersect
98 // source.
99 processByIteratingOverIntersectSource( context, targetSource, intersectSource, selectedPredicates, handleFeatureFunction, onlyRequireTargetIds, feedback, skipTargetFeatureIds );
100 }
101}
102
103void QgsLocationBasedAlgorithm::processByIteratingOverTargetSource( const QgsProcessingContext &context, QgsFeatureSource *targetSource, QgsFeatureSource *intersectSource, const QList<int> &selectedPredicates, const std::function<void( const QgsFeature & )> &handleFeatureFunction, bool onlyRequireTargetIds, QgsProcessingFeedback *feedback, const QgsFeatureIds &skipTargetFeatureIds )
104{
106 feedback->pushWarning( QObject::tr( "No spatial index exists for intersect layer, performance will be severely degraded" ) );
107
108 QgsFeatureIds foundSet;
110 if ( onlyRequireTargetIds )
111 request.setNoAttributes();
112
113 QgsFeatureIterator fIt = targetSource->getFeatures( request );
114 double step = mTargetFeatureCount > 0 ? 100.0 / static_cast<double>( mTargetFeatureCount ) : 1;
115 int current = 0;
116 QgsFeature f;
117 std::unique_ptr<QgsGeometryEngine> engine;
118 while ( fIt.nextFeature( f ) )
119 {
120 if ( feedback->isCanceled() )
121 break;
122
123 // don't check features in skipTargetFeatureIds
124 if ( skipTargetFeatureIds.contains( f.id() ) )
125 continue;
126 if ( !f.hasGeometry() )
127 continue;
128
129 engine.reset();
130
131 QgsRectangle bbox = f.geometry().boundingBox();
132 request = QgsFeatureRequest().setFilterRect( bbox ).setNoAttributes().setDestinationCrs( mTargetCrs, context.transformContext() );
133
134 QgsFeatureIterator testFeatureIt = intersectSource->getFeatures( request );
135 QgsFeature testFeature;
136 bool isMatch = false;
137 bool isDisjoint = true;
138 while ( testFeatureIt.nextFeature( testFeature ) )
139 {
140 if ( feedback->isCanceled() )
141 break;
142
143 if ( !engine )
144 {
145 engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
146 engine->prepareGeometry();
147 }
148
149 for ( int predicate : selectedPredicates )
150 {
151 switch ( static_cast<Predicate>( predicate ) )
152 {
153 case Intersects:
154 isMatch = engine->intersects( testFeature.geometry().constGet() );
155 break;
156 case Contains:
157 isMatch = engine->contains( testFeature.geometry().constGet() );
158 break;
159 case Disjoint:
160 if ( engine->intersects( testFeature.geometry().constGet() ) )
161 {
162 isDisjoint = false;
163 }
164 break;
165 case IsEqual:
166 isMatch = engine->isEqual( testFeature.geometry().constGet() );
167 break;
168 case Touches:
169 isMatch = engine->touches( testFeature.geometry().constGet() );
170 break;
171 case Overlaps:
172 isMatch = engine->overlaps( testFeature.geometry().constGet() );
173 break;
174 case Within:
175 isMatch = engine->within( testFeature.geometry().constGet() );
176 break;
177 case Crosses:
178 isMatch = engine->crosses( testFeature.geometry().constGet() );
179 break;
180 }
181
182 if ( isMatch )
183 break;
184 }
185
186 if ( isMatch )
187 {
188 foundSet.insert( f.id() );
189 handleFeatureFunction( f );
190 break;
191 }
192 }
193 if ( isDisjoint && selectedPredicates.contains( Disjoint ) )
194 {
195 foundSet.insert( f.id() );
196 handleFeatureFunction( f );
197 }
198
199 current += 1;
200 feedback->setProgress( current * step );
201 }
202}
203
204void QgsLocationBasedAlgorithm::processByIteratingOverIntersectSource( const QgsProcessingContext &context, QgsFeatureSource *targetSource, QgsFeatureSource *intersectSource, const QList<int> &selectedPredicates, const std::function<void( const QgsFeature & )> &handleFeatureFunction, bool onlyRequireTargetIds, QgsProcessingFeedback *feedback, const QgsFeatureIds &skipTargetFeatureIds )
205{
207 feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
208
209 // build a list of 'reversed' predicates, because in this function
210 // we actually test the reverse of what the user wants (allowing us
211 // to prepare geometries and optimise the algorithm)
212 QList<Predicate> predicates;
213 predicates.reserve( selectedPredicates.count() );
214 for ( int i : selectedPredicates )
215 {
216 predicates << reversePredicate( static_cast<Predicate>( i ) );
217 }
218
219 QgsFeatureIds disjointSet;
220 if ( predicates.contains( Disjoint ) )
221 disjointSet = targetSource->allFeatureIds();
222
223 QgsFeatureIds foundSet;
225 QgsFeatureIterator fIt = intersectSource->getFeatures( request );
226 double step = mIntersectFeatureCount > 0 ? 100.0 / static_cast<double>( mIntersectFeatureCount ) : 1;
227 int current = 0;
228 QgsFeature f;
229 std::unique_ptr<QgsGeometryEngine> engine;
230 while ( fIt.nextFeature( f ) )
231 {
232 if ( feedback->isCanceled() )
233 break;
234
235 if ( !f.hasGeometry() )
236 continue;
237
238 engine.reset();
239
240 QgsRectangle bbox = f.geometry().boundingBox();
241 request = QgsFeatureRequest().setFilterRect( bbox );
242 if ( onlyRequireTargetIds )
243 request.setNoAttributes();
244
245 QgsFeatureIterator testFeatureIt = targetSource->getFeatures( request );
246 QgsFeature testFeature;
247 while ( testFeatureIt.nextFeature( testFeature ) )
248 {
249 if ( feedback->isCanceled() )
250 break;
251
252 if ( skipTargetFeatureIds.contains( testFeature.id() ) )
253 {
254 // don't check features in skipTargetFeatureIds
255 continue;
256 }
257 if ( foundSet.contains( testFeature.id() ) )
258 {
259 // already added this one, no need for further tests
260 continue;
261 }
262 if ( predicates.count() == 1 && predicates.at( 0 ) == Disjoint && !disjointSet.contains( testFeature.id() ) )
263 {
264 // calculating only the disjoint set, and we've already eliminated this feature so no need for further tests
265 continue;
266 }
267
268 if ( !engine )
269 {
270 engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
271 engine->prepareGeometry();
272 }
273
274 bool isMatch = false;
275
276 for ( Predicate predicate : std::as_const( predicates ) )
277 {
278 switch ( predicate )
279 {
280 case Intersects:
281 isMatch = engine->intersects( testFeature.geometry().constGet() );
282 break;
283 case Contains:
284 isMatch = engine->contains( testFeature.geometry().constGet() );
285 break;
286 case Disjoint:
287 if ( engine->intersects( testFeature.geometry().constGet() ) )
288 {
289 disjointSet.remove( testFeature.id() );
290 }
291 break;
292 case IsEqual:
293 isMatch = engine->isEqual( testFeature.geometry().constGet() );
294 break;
295 case Touches:
296 isMatch = engine->touches( testFeature.geometry().constGet() );
297 break;
298 case Overlaps:
299 isMatch = engine->overlaps( testFeature.geometry().constGet() );
300 break;
301 case Within:
302 isMatch = engine->within( testFeature.geometry().constGet() );
303 break;
304 case Crosses:
305 isMatch = engine->crosses( testFeature.geometry().constGet() );
306 break;
307 }
308 if ( isMatch )
309 break;
310 }
311
312 if ( isMatch )
313 {
314 foundSet.insert( testFeature.id() );
315 handleFeatureFunction( testFeature );
316 }
317 }
318
319 current += 1;
320 feedback->setProgress( current * step );
321 }
322
323 if ( predicates.contains( Disjoint ) )
324 {
325 disjointSet = disjointSet.subtract( foundSet );
326 QgsFeatureRequest disjointReq = QgsFeatureRequest().setFilterFids( disjointSet );
327 if ( onlyRequireTargetIds )
329 QgsFeatureIterator disjointIt = targetSource->getFeatures( disjointReq );
330 QgsFeature f;
331 while ( disjointIt.nextFeature( f ) )
332 {
333 handleFeatureFunction( f );
334 }
335 }
336}
337
338
339//
340// QgsSelectByLocationAlgorithm
341//
342
343void QgsSelectByLocationAlgorithm::initAlgorithm( const QVariantMap & )
344{
345 QStringList methods = QStringList() << QObject::tr( "creating new selection" )
346 << QObject::tr( "adding to current selection" )
347 << QObject::tr( "selecting within current selection" )
348 << QObject::tr( "removing from current selection" );
349
350 addParameter( new QgsProcessingParameterVectorLayer( QStringLiteral( "INPUT" ), QObject::tr( "Select features from" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
351 addPredicateParameter();
352 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INTERSECT" ), QObject::tr( "By comparing to the features from" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
353
354 addParameter( new QgsProcessingParameterEnum( QStringLiteral( "METHOD" ), QObject::tr( "Modify current selection by" ), methods, false, 0 ) );
355}
356
357QString QgsSelectByLocationAlgorithm::name() const
358{
359 return QStringLiteral( "selectbylocation" );
360}
361
362Qgis::ProcessingAlgorithmFlags QgsSelectByLocationAlgorithm::flags() const
363{
365}
366
367QString QgsSelectByLocationAlgorithm::displayName() const
368{
369 return QObject::tr( "Select by location" );
370}
371
372QStringList QgsSelectByLocationAlgorithm::tags() const
373{
374 return QObject::tr( "select,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( ',' );
375}
376
377QString QgsSelectByLocationAlgorithm::group() const
378{
379 return QObject::tr( "Vector selection" );
380}
381
382QString QgsSelectByLocationAlgorithm::groupId() const
383{
384 return QStringLiteral( "vectorselection" );
385}
386
387QString QgsSelectByLocationAlgorithm::shortHelpString() const
388{
389 return QObject::tr( "This algorithm creates a selection in a vector layer. The criteria for selecting "
390 "features is based on the spatial relationship between each feature and the features in an additional layer." );
391}
392
393QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance() const
394{
395 return new QgsSelectByLocationAlgorithm();
396}
397
398QVariantMap QgsSelectByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
399{
400 QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral( "INPUT" ), context );
401 if ( !selectLayer )
402 throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
403
404 Qgis::SelectBehavior method = static_cast<Qgis::SelectBehavior>( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
405 std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
406 if ( !intersectSource )
407 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
408
409 const QList<int> selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
410
411 QgsFeatureIds selectedIds;
412 auto addToSelection = [&]( const QgsFeature &feature ) {
413 selectedIds.insert( feature.id() );
414 };
415
416 mTargetCrs = selectLayer->sourceCrs();
417 mTargetFeatureCount = selectLayer->featureCount();
418 mIntersectFeatureCount = intersectSource->featureCount();
419
420 switch ( method )
421 {
424 {
425 // When subsetting or removing we only need to check already selected features
426 std::unique_ptr<QgsVectorLayerSelectedFeatureSource> selectLayerSelected( new QgsVectorLayerSelectedFeatureSource( selectLayer ) );
427 mTargetCrs = selectLayerSelected->sourceCrs();
428 mTargetFeatureCount = selectLayerSelected->featureCount();
429 process( context, selectLayerSelected.get(), intersectSource.get(), selectedPredicates, addToSelection, true, feedback );
430 break;
431 }
433 // When adding we can skip checking already selected features
434 process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection, true, feedback, selectLayer->selectedFeatureIds() );
435 break;
437 process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection, true, feedback );
438 break;
439 }
440
441 selectLayer->selectByIds( selectedIds, method );
442 QVariantMap results;
443 results.insert( QStringLiteral( "OUTPUT" ), parameters.value( QStringLiteral( "INPUT" ) ) );
444 return results;
445}
446
447
448//
449// QgsExtractByLocationAlgorithm
450//
451
452void QgsExtractByLocationAlgorithm::initAlgorithm( const QVariantMap & )
453{
454 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Extract features from" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
455 addPredicateParameter();
456 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INTERSECT" ), QObject::tr( "By comparing to the features from" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
457
458 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted (location)" ) ) );
459}
460
461QString QgsExtractByLocationAlgorithm::name() const
462{
463 return QStringLiteral( "extractbylocation" );
464}
465
466QString QgsExtractByLocationAlgorithm::displayName() const
467{
468 return QObject::tr( "Extract by location" );
469}
470
471QStringList QgsExtractByLocationAlgorithm::tags() const
472{
473 return QObject::tr( "extract,filter,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( ',' );
474}
475
476QString QgsExtractByLocationAlgorithm::group() const
477{
478 return QObject::tr( "Vector selection" );
479}
480
481QString QgsExtractByLocationAlgorithm::groupId() const
482{
483 return QStringLiteral( "vectorselection" );
484}
485
486QString QgsExtractByLocationAlgorithm::shortHelpString() const
487{
488 return QObject::tr( "This algorithm creates a new vector layer that only contains matching features from an "
489 "input layer. The criteria for adding features to the resulting layer is defined "
490 "based on the spatial relationship between each feature and the features in an additional layer." );
491}
492
493QgsExtractByLocationAlgorithm *QgsExtractByLocationAlgorithm::createInstance() const
494{
495 return new QgsExtractByLocationAlgorithm();
496}
497
498bool QgsExtractByLocationAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
499{
500 std::unique_ptr<QgsFeatureSource> input( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
501 if ( !input )
502 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
503 std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
504 if ( !intersectSource )
505 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
506
507 mTargetCrs = input->sourceCrs();
508 mTargetFeatureCount = input->featureCount();
509 mIntersectFeatureCount = intersectSource->featureCount();
510
511 return true;
512}
513
514QVariantMap QgsExtractByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
515{
516 std::unique_ptr<QgsFeatureSource> input( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
517 if ( !input )
518 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
519 std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
520 if ( !intersectSource )
521 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
522
523 const QList<int> selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
524 QString dest;
525 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, input->fields(), input->wkbType(), mTargetCrs ) );
526
527 if ( !sink )
528 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
529
530 auto addToSink = [&]( const QgsFeature &feature ) {
531 QgsFeature f = feature;
532 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
533 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
534 };
535 process( context, input.get(), intersectSource.get(), selectedPredicates, addToSink, false, feedback );
536
537 sink->finalize();
538
539 QVariantMap results;
540 results.insert( QStringLiteral( "OUTPUT" ), dest );
541 return results;
542}
543
@ VectorAnyGeometry
Any vector layer with geometry.
@ NotPresent
No spatial index exists for the source.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3410
@ NotAvailableInStandaloneTool
Algorithm should not be available from the standalone "qgis_process" tool. Used to flag algorithms wh...
@ NoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
SelectBehavior
Specifies how a selection should be applied.
Definition qgis.h:1681
@ SetSelection
Set selection, removing any existing selection.
@ AddToSelection
Add selection to current selection.
@ IntersectSelection
Modify current selection to include only select features which match.
@ RemoveFromSelection
Remove from current selection.
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.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
An interface for objects which provide features via a getFeatures method.
virtual Qgis::SpatialIndexPresence hasSpatialIndex() const
Returns an enum value representing the presence of a valid spatial index on the source,...
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFeatureId id
Definition qgsfeature.h:66
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
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
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.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer (with or without geometry) parameter for processing algorithms.
A rectangle specified with double values.
QgsFeatureSource subclass for the selected features from a QgsVectorLayer.
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsCoordinateReferenceSystem sourceCrs() const FINAL
Returns the coordinate reference system for features in the source.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection)
Selects matching features using a list of feature IDs.
QSet< QgsFeatureId > QgsFeatureIds