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