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