QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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"
21 
23 
24 void QgsLocationBasedAlgorithm::addPredicateParameter()
25 {
26  std::unique_ptr< QgsProcessingParameterEnum > predicateParam( new QgsProcessingParameterEnum( QStringLiteral( "PREDICATE" ),
27  QObject::tr( "Where the features (geometric predicate)" ),
28  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 
40 QgsLocationBasedAlgorithm::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 
65 QStringList 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 
77 void QgsLocationBasedAlgorithm::process( const QgsProcessingContext &context, QgsFeatureSource *targetSource,
78  QgsFeatureSource *intersectSource,
79  const QList< int > &selectedPredicates,
80  const std::function < void( const QgsFeature & ) > &handleFeatureFunction,
81  bool onlyRequireTargetIds,
82  QgsProcessingFeedback *feedback )
83 {
84 
85  if ( targetSource->featureCount() > 0 && intersectSource->featureCount() > 0
86  && targetSource->featureCount() < intersectSource->featureCount() )
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,
90  selectedPredicates, handleFeatureFunction,
91  onlyRequireTargetIds, feedback );
92  }
93  else
94  {
95  // default -- iterate over the intersect source and match back to the target source. We do this on the assumption that the most common
96  // use case is joining a points layer to a polygon layer (e.g. findings points within a polygon), so by iterating
97  // over the polygons we can take advantage of prepared geometries for the spatial relationship test.
98 
99  // TODO - consider using more heuristics to determine whether it's always best to iterate over the intersect
100  // source.
101  processByIteratingOverIntersectSource( context, targetSource, intersectSource,
102  selectedPredicates, handleFeatureFunction,
103  onlyRequireTargetIds, feedback );
104  }
105 }
106 
107 void QgsLocationBasedAlgorithm::processByIteratingOverTargetSource( const QgsProcessingContext &context, QgsFeatureSource *targetSource,
108  QgsFeatureSource *intersectSource,
109  const QList< int > &selectedPredicates,
110  const std::function < void( const QgsFeature & ) > &handleFeatureFunction,
111  bool onlyRequireTargetIds,
112  QgsProcessingFeedback *feedback )
113 {
114  if ( intersectSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
115  feedback->reportError( QObject::tr( "No spatial index exists for intersect layer, performance will be severely degraded" ) );
116 
117  QgsFeatureIds foundSet;
119  if ( onlyRequireTargetIds )
120  request.setNoAttributes();
121 
122  QgsFeatureIterator fIt = targetSource->getFeatures( request );
123  double step = targetSource->featureCount() > 0 ? 100.0 / targetSource->featureCount() : 1;
124  int current = 0;
125  QgsFeature f;
126  std::unique_ptr< QgsGeometryEngine > engine;
127  while ( fIt.nextFeature( f ) )
128  {
129  if ( feedback->isCanceled() )
130  break;
131 
132  if ( !f.hasGeometry() )
133  continue;
134 
135  engine.reset();
136 
137  QgsRectangle bbox = f.geometry().boundingBox();
138  request = QgsFeatureRequest().setFilterRect( bbox ).setNoAttributes().setDestinationCrs( targetSource->sourceCrs(), context.transformContext() );
139 
140  QgsFeatureIterator testFeatureIt = intersectSource->getFeatures( request );
141  QgsFeature testFeature;
142  bool isMatch = false;
143  bool isDisjoint = true;
144  while ( testFeatureIt.nextFeature( testFeature ) )
145  {
146  if ( feedback->isCanceled() )
147  break;
148 
149  if ( !engine )
150  {
151  engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
152  engine->prepareGeometry();
153  }
154 
155  for ( int predicate : selectedPredicates )
156  {
157  switch ( static_cast< Predicate>( predicate ) )
158  {
159  case Intersects:
160  isMatch = engine->intersects( testFeature.geometry().constGet() );
161  break;
162  case Contains:
163  isMatch = engine->contains( testFeature.geometry().constGet() );
164  break;
165  case Disjoint:
166  if ( engine->intersects( testFeature.geometry().constGet() ) )
167  {
168  isDisjoint = false;
169  }
170  break;
171  case IsEqual:
172  isMatch = engine->isEqual( testFeature.geometry().constGet() );
173  break;
174  case Touches:
175  isMatch = engine->touches( testFeature.geometry().constGet() );
176  break;
177  case Overlaps:
178  isMatch = engine->overlaps( testFeature.geometry().constGet() );
179  break;
180  case Within:
181  isMatch = engine->within( testFeature.geometry().constGet() );
182  break;
183  case Crosses:
184  isMatch = engine->crosses( testFeature.geometry().constGet() );
185  break;
186  }
187 
188  if ( isMatch )
189  break;
190  }
191 
192  if ( isMatch )
193  {
194  foundSet.insert( f.id() );
195  handleFeatureFunction( f );
196  break;
197  }
198  }
199  if ( isDisjoint && selectedPredicates.contains( Disjoint ) )
200  {
201  foundSet.insert( f.id() );
202  handleFeatureFunction( f );
203  }
204 
205  current += 1;
206  feedback->setProgress( current * step );
207  }
208 }
209 
210 void QgsLocationBasedAlgorithm::processByIteratingOverIntersectSource( const QgsProcessingContext &context, QgsFeatureSource *targetSource,
211  QgsFeatureSource *intersectSource,
212  const QList< int > &selectedPredicates,
213  const std::function < void( const QgsFeature & ) > &handleFeatureFunction,
214  bool onlyRequireTargetIds,
215  QgsProcessingFeedback *feedback )
216 {
218  feedback->reportError( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) );
219 
220  // build a list of 'reversed' predicates, because in this function
221  // we actually test the reverse of what the user wants (allowing us
222  // to prepare geometries and optimise the algorithm)
223  QList< Predicate > predicates;
224  predicates.reserve( selectedPredicates.count() );
225  for ( int i : selectedPredicates )
226  {
227  predicates << reversePredicate( static_cast< Predicate >( i ) );
228  }
229 
230  QgsFeatureIds disjointSet;
231  if ( predicates.contains( Disjoint ) )
232  disjointSet = targetSource->allFeatureIds();
233 
234  QgsFeatureIds foundSet;
236  QgsFeatureIterator fIt = intersectSource->getFeatures( request );
237  double step = intersectSource->featureCount() > 0 ? 100.0 / intersectSource->featureCount() : 1;
238  int current = 0;
239  QgsFeature f;
240  std::unique_ptr< QgsGeometryEngine > engine;
241  while ( fIt.nextFeature( f ) )
242  {
243  if ( feedback->isCanceled() )
244  break;
245 
246  if ( !f.hasGeometry() )
247  continue;
248 
249  engine.reset();
250 
251  QgsRectangle bbox = f.geometry().boundingBox();
252  request = QgsFeatureRequest().setFilterRect( bbox );
253  if ( onlyRequireTargetIds )
254  request.setNoAttributes();
255 
256  QgsFeatureIterator testFeatureIt = targetSource->getFeatures( request );
257  QgsFeature testFeature;
258  while ( testFeatureIt.nextFeature( testFeature ) )
259  {
260  if ( feedback->isCanceled() )
261  break;
262 
263  if ( foundSet.contains( testFeature.id() ) )
264  {
265  // already added this one, no need for further tests
266  continue;
267  }
268  if ( predicates.count() == 1 && predicates.at( 0 ) == Disjoint && !disjointSet.contains( testFeature.id() ) )
269  {
270  // calculating only the disjoint set, and we've already eliminated this feature so no need for further tests
271  continue;
272  }
273 
274  if ( !engine )
275  {
276  engine.reset( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
277  engine->prepareGeometry();
278  }
279 
280  for ( Predicate predicate : qgis::as_const( predicates ) )
281  {
282  bool isMatch = false;
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  {
315  foundSet.insert( testFeature.id() );
316  handleFeatureFunction( testFeature );
317  }
318  }
319 
320  }
321 
322  current += 1;
323  feedback->setProgress( current * step );
324  }
325 
326  if ( predicates.contains( Disjoint ) )
327  {
328  disjointSet = disjointSet.subtract( foundSet );
329  QgsFeatureRequest disjointReq = QgsFeatureRequest().setFilterFids( disjointSet );
330  if ( onlyRequireTargetIds )
332  QgsFeatureIterator disjointIt = targetSource->getFeatures( disjointReq );
333  QgsFeature f;
334  while ( disjointIt.nextFeature( f ) )
335  {
336  handleFeatureFunction( f );
337  }
338  }
339 }
340 
341 
342 //
343 // QgsSelectByLocationAlgorithm
344 //
345 
346 void QgsSelectByLocationAlgorithm::initAlgorithm( const QVariantMap & )
347 {
348  QStringList methods = QStringList() << QObject::tr( "creating new selection" )
349  << QObject::tr( "adding to current selection" )
350  << QObject::tr( "selecting within current selection" )
351  << QObject::tr( "removing from current selection" );
352 
353  addParameter( new QgsProcessingParameterVectorLayer( QStringLiteral( "INPUT" ), QObject::tr( "Select features from" ),
354  QList< int >() << QgsProcessing::TypeVectorAnyGeometry ) );
355  addPredicateParameter();
356  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INTERSECT" ),
357  QObject::tr( "By comparing to the features from" ),
358  QList< int >() << QgsProcessing::TypeVectorAnyGeometry ) );
359 
360  addParameter( new QgsProcessingParameterEnum( QStringLiteral( "METHOD" ),
361  QObject::tr( "Modify current selection by" ),
362  methods, false, 0 ) );
363 }
364 
365 QString QgsSelectByLocationAlgorithm::name() const
366 {
367  return QStringLiteral( "selectbylocation" );
368 }
369 
370 QgsProcessingAlgorithm::Flags QgsSelectByLocationAlgorithm::flags() const
371 {
373 }
374 
375 QString QgsSelectByLocationAlgorithm::displayName() const
376 {
377  return QObject::tr( "Select by location" );
378 }
379 
380 QStringList QgsSelectByLocationAlgorithm::tags() const
381 {
382  return QObject::tr( "select,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( ',' );
383 }
384 
385 QString QgsSelectByLocationAlgorithm::group() const
386 {
387  return QObject::tr( "Vector selection" );
388 }
389 
390 QString QgsSelectByLocationAlgorithm::groupId() const
391 {
392  return QStringLiteral( "vectorselection" );
393 }
394 
395 QString QgsSelectByLocationAlgorithm::shortHelpString() const
396 {
397  return QObject::tr( "This algorithm creates a selection in a vector layer. The criteria for selecting "
398  "features is based on the spatial relationship between each feature and the features in an additional layer." );
399 }
400 
401 QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance() const
402 {
403  return new QgsSelectByLocationAlgorithm();
404 }
405 
406 QVariantMap QgsSelectByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
407 {
408  QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral( "INPUT" ), context );
409  if ( !selectLayer )
410  throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
411 
412  QgsVectorLayer::SelectBehavior method = static_cast< QgsVectorLayer::SelectBehavior >( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
413  std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
414  if ( !intersectSource )
415  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
416 
417  const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
418 
419  QgsFeatureIds selectedIds;
420  auto addToSelection = [&]( const QgsFeature & feature )
421  {
422  selectedIds.insert( feature.id() );
423  };
424  process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection, true, feedback );
425 
426  selectLayer->selectByIds( selectedIds, method );
427  QVariantMap results;
428  results.insert( QStringLiteral( "OUTPUT" ), parameters.value( QStringLiteral( "INPUT" ) ) );
429  return results;
430 }
431 
432 
433 //
434 // QgsExtractByLocationAlgorithm
435 //
436 
437 void QgsExtractByLocationAlgorithm::initAlgorithm( const QVariantMap & )
438 {
439  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ),
440  QObject::tr( "Extract features from" ),
441  QList< int >() << QgsProcessing::TypeVectorAnyGeometry ) );
442  addPredicateParameter();
443  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INTERSECT" ),
444  QObject::tr( "By comparing to the features from" ),
445  QList< int >() << QgsProcessing::TypeVectorAnyGeometry ) );
446 
447  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted (location)" ) ) );
448 }
449 
450 QString QgsExtractByLocationAlgorithm::name() const
451 {
452  return QStringLiteral( "extractbylocation" );
453 }
454 
455 QString QgsExtractByLocationAlgorithm::displayName() const
456 {
457  return QObject::tr( "Extract by location" );
458 }
459 
460 QStringList QgsExtractByLocationAlgorithm::tags() const
461 {
462  return QObject::tr( "extract,filter,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( ',' );
463 }
464 
465 QString QgsExtractByLocationAlgorithm::group() const
466 {
467  return QObject::tr( "Vector selection" );
468 }
469 
470 QString QgsExtractByLocationAlgorithm::groupId() const
471 {
472  return QStringLiteral( "vectorselection" );
473 }
474 
475 QString QgsExtractByLocationAlgorithm::shortHelpString() const
476 {
477  return QObject::tr( "This algorithm creates a new vector layer that only contains matching features from an "
478  "input layer. The criteria for adding features to the resulting layer is defined "
479  "based on the spatial relationship between each feature and the features in an additional layer." );
480 }
481 
482 QgsExtractByLocationAlgorithm *QgsExtractByLocationAlgorithm::createInstance() const
483 {
484  return new QgsExtractByLocationAlgorithm();
485 }
486 
487 QVariantMap QgsExtractByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
488 {
489  std::unique_ptr< QgsFeatureSource > input( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
490  if ( !input )
491  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
492  std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
493  if ( !intersectSource )
494  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
495 
496  const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
497  QString dest;
498  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, input->fields(), input->wkbType(), input->sourceCrs() ) );
499 
500  if ( !sink )
501  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
502 
503  auto addToSink = [&]( const QgsFeature & feature )
504  {
505  QgsFeature f = feature;
506  sink->addFeature( f, QgsFeatureSink::FastInsert );
507  };
508  process( context, input.get(), intersectSource.get(), selectedPredicates, addToSink, false, feedback );
509 
510  QVariantMap results;
511  results.insert( QStringLiteral( "OUTPUT" ), dest );
512  return results;
513 }
514 
516 
517 
518 
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:81
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:62
QgsFeature::id
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
QgsFeatureSource::hasSpatialIndex
virtual SpatialIndexPresence hasSpatialIndex() const
Returns an enum value representing the presence of a valid spatial index on the source,...
Definition: qgsfeaturesource.cpp:190
QgsFeatureSource::sourceCrs
virtual QgsCoordinateReferenceSystem sourceCrs() const =0
Returns the coordinate reference system for features in the source.
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
QgsFeatureSource::SpatialIndexNotPresent
@ SpatialIndexNotPresent
No spatial index exists for the source.
Definition: qgsfeaturesource.h:190
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:39
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsFeatureSource
An interface for objects which provide features via a getFeatures method.
Definition: qgsfeaturesource.h:38
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2734
QgsVectorLayer::selectByIds
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, QgsVectorLayer::SelectBehavior behavior=QgsVectorLayer::SetSelection)
Selects matching features using a list of feature IDs.
Definition: qgsvectorlayer.cpp:523
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsProcessingParameterFeatureSink
A feature sink output for processing algorithms.
Definition: qgsprocessingparameters.h:2895
QgsFeatureSource::allFeatureIds
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
Definition: qgsfeaturesource.cpp:115
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:92
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
qgsgeometryengine.h
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsProcessing::TypeVectorAnyGeometry
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:47
QgsFeatureSource::getFeatures
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
QgsFeatureRequest::setFilterFids
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
Definition: qgsfeaturerequest.cpp:105
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:149
QgsProcessingParameterVectorLayer
A vector layer (with or without geometry) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2504
QgsVectorLayer::SelectBehavior
SelectBehavior
Selection behavior.
Definition: qgsvectorlayer.h:412
QgsFeatureRequest::setNoAttributes
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
Definition: qgsfeaturerequest.cpp:192
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsFeatureSource::featureCount
virtual long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
qgsvectorlayer.h
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
Definition: qgsgeometry.cpp:3636
QgsProcessingAlgorithm::FlagNoThreading
@ FlagNoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
Definition: qgsprocessingalgorithm.h:75
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
qgsalgorithmextractbylocation.h
QgsProcessingAlgorithm::FlagNotAvailableInStandaloneTool
@ FlagNotAvailableInStandaloneTool
Algorithm should not be available from the standalone "qgis_process" tool. Used to flag algorithms wh...
Definition: qgsprocessingalgorithm.h:82
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:996
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsFeatureRequest::setDestinationCrs
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
Definition: qgsfeaturerequest.cpp:258
QgsProcessingParameterEnum
An enum based parameter for processing algorithms, allowing for selection from predefined values.
Definition: qgsprocessingparameters.h:2256
QgsProcessingAlgorithm::flags
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
Definition: qgsprocessingalgorithm.cpp:88
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:179
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
QgsFeatureSink::FastInsert
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Definition: qgsfeaturesink.h:70