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