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