25void QgsLocationBasedAlgorithm::addPredicateParameter()
 
   27  auto predicateParam = std::make_unique<QgsProcessingParameterEnum>( QStringLiteral( 
"PREDICATE" ), QObject::tr( 
"Where the features (geometric predicate)" ), predicateOptionsList(), 
true, QVariant::fromValue( QList<int>() << 0 ) );
 
   29  QVariantMap predicateMetadata;
 
   30  QVariantMap widgetMetadata;
 
   31  widgetMetadata.insert( QStringLiteral( 
"useCheckBoxes" ), 
true );
 
   32  widgetMetadata.insert( QStringLiteral( 
"columns" ), 2 );
 
   33  predicateMetadata.insert( QStringLiteral( 
"widget_wrapper" ), widgetMetadata );
 
   34  predicateParam->setMetadata( predicateMetadata );
 
   36  addParameter( predicateParam.release() );
 
   39QgsLocationBasedAlgorithm::Predicate QgsLocationBasedAlgorithm::reversePredicate( QgsLocationBasedAlgorithm::Predicate predicate )
 const 
   64QStringList QgsLocationBasedAlgorithm::predicateOptionsList()
 const 
   66  return QStringList() << QObject::tr( 
"intersect" )
 
   67                       << QObject::tr( 
"contain" )
 
   68                       << QObject::tr( 
"disjoint" )
 
   69                       << QObject::tr( 
"equal" )
 
   70                       << QObject::tr( 
"touch" )
 
   71                       << QObject::tr( 
"overlap" )
 
   72                       << QObject::tr( 
"are within" )
 
   73                       << QObject::tr( 
"cross" );
 
   79  if ( mTargetFeatureCount == 0 )
 
   83  if ( mIntersectFeatureCount == 0 && !selectedPredicates.contains( Disjoint ) )
 
   86  if ( mTargetFeatureCount > 0 && mIntersectFeatureCount > 0 && mTargetFeatureCount < mIntersectFeatureCount )
 
   89    processByIteratingOverTargetSource( context, targetSource, intersectSource, selectedPredicates, handleFeatureFunction, onlyRequireTargetIds, feedback, skipTargetFeatureIds );
 
   99    processByIteratingOverIntersectSource( context, targetSource, intersectSource, selectedPredicates, handleFeatureFunction, onlyRequireTargetIds, feedback, skipTargetFeatureIds );
 
  106    feedback->
pushWarning( QObject::tr( 
"No spatial index exists for intersect layer, performance will be severely degraded" ) );
 
  110  if ( onlyRequireTargetIds )
 
  114  double step = mTargetFeatureCount > 0 ? 100.0 / 
static_cast<double>( mTargetFeatureCount ) : 1;
 
  117  std::unique_ptr<QgsGeometryEngine> engine;
 
  124    if ( skipTargetFeatureIds.contains( f.
id() ) )
 
  136    bool isMatch = 
false;
 
  137    bool isDisjoint = 
true;
 
  146        engine->prepareGeometry();
 
  149      for ( 
int predicate : selectedPredicates )
 
  151        switch ( 
static_cast<Predicate
>( predicate ) )
 
  188        foundSet.insert( f.
id() );
 
  189        handleFeatureFunction( f );
 
  193    if ( isDisjoint && selectedPredicates.contains( Disjoint ) )
 
  195      foundSet.insert( f.
id() );
 
  196      handleFeatureFunction( f );
 
  207    feedback->
pushWarning( QObject::tr( 
"No spatial index exists for input layer, performance will be severely degraded" ) );
 
  212  QList<Predicate> predicates;
 
  213  predicates.reserve( selectedPredicates.count() );
 
  214  for ( 
int i : selectedPredicates )
 
  216    predicates << reversePredicate( static_cast<Predicate>( i ) );
 
  220  if ( predicates.contains( Disjoint ) )
 
  226  double step = mIntersectFeatureCount > 0 ? 100.0 / 
static_cast<double>( mIntersectFeatureCount ) : 1;
 
  229  std::unique_ptr<QgsGeometryEngine> engine;
 
  242    if ( onlyRequireTargetIds )
 
  252      if ( skipTargetFeatureIds.contains( testFeature.
id() ) )
 
  257      if ( foundSet.contains( testFeature.
id() ) )
 
  262      if ( predicates.count() == 1 && predicates.at( 0 ) == Disjoint && !disjointSet.contains( testFeature.
id() ) )
 
  271        engine->prepareGeometry();
 
  274      bool isMatch = 
false;
 
  276      for ( Predicate predicate : std::as_const( predicates ) )
 
  289              disjointSet.remove( testFeature.
id() );
 
  314        foundSet.insert( testFeature.
id() );
 
  315        handleFeatureFunction( testFeature );
 
  323  if ( predicates.contains( Disjoint ) )
 
  325    disjointSet = disjointSet.subtract( foundSet );
 
  327    if ( onlyRequireTargetIds )
 
  333      handleFeatureFunction( f );
 
  343void QgsSelectByLocationAlgorithm::initAlgorithm( 
const QVariantMap & )
 
  345  QStringList methods = QStringList() << QObject::tr( 
"creating new selection" )
 
  346                                      << QObject::tr( 
"adding to current selection" )
 
  347                                      << QObject::tr( 
"selecting within current selection" )
 
  348                                      << QObject::tr( 
"removing from current selection" );
 
  351  addPredicateParameter();
 
  354  addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"METHOD" ), QObject::tr( 
"Modify current selection by" ), methods, 
false, 0 ) );
 
  357QString QgsSelectByLocationAlgorithm::name()
 const 
  359  return QStringLiteral( 
"selectbylocation" );
 
  367QString QgsSelectByLocationAlgorithm::displayName()
 const 
  369  return QObject::tr( 
"Select by location" );
 
  372QStringList QgsSelectByLocationAlgorithm::tags()
 const 
  374  return QObject::tr( 
"select,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( 
',' );
 
  377QString QgsSelectByLocationAlgorithm::group()
 const 
  379  return QObject::tr( 
"Vector selection" );
 
  382QString QgsSelectByLocationAlgorithm::groupId()
 const 
  384  return QStringLiteral( 
"vectorselection" );
 
  387QString QgsSelectByLocationAlgorithm::shortHelpString()
 const 
  389  return QObject::tr( 
"This algorithm creates a selection in a vector layer. The criteria for selecting " 
  390                      "features is based on the spatial relationship between each feature and the features in an additional layer." );
 
  393QString QgsSelectByLocationAlgorithm::shortDescription()
 const 
  395  return QObject::tr( 
"Creates a selection in a vector layer based on the spatial relationship with features in an additional layer." );
 
  398QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance()
 const 
  400  return new QgsSelectByLocationAlgorithm();
 
  405  QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral( 
"INPUT" ), context );
 
  410  std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( 
"INTERSECT" ), context ) );
 
  411  if ( !intersectSource )
 
  414  const QList<int> selectedPredicates = parameterAsEnums( parameters, QStringLiteral( 
"PREDICATE" ), context );
 
  417  auto addToSelection = [&]( 
const QgsFeature &feature ) {
 
  418    selectedIds.insert( feature.id() );
 
  423  mIntersectFeatureCount = intersectSource->
featureCount();
 
  431      auto selectLayerSelected = std::make_unique<QgsVectorLayerSelectedFeatureSource>( selectLayer );
 
  432      mTargetCrs = selectLayerSelected->sourceCrs();
 
  433      mTargetFeatureCount = selectLayerSelected->featureCount();
 
  434      process( context, selectLayerSelected.get(), intersectSource.get(), selectedPredicates, addToSelection, 
true, feedback );
 
  439      process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection, 
true, feedback, selectLayer->
selectedFeatureIds() );
 
  442      process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection, 
true, feedback );
 
  448  results.insert( QStringLiteral( 
"OUTPUT" ), parameters.value( QStringLiteral( 
"INPUT" ) ) );
 
  457void QgsExtractByLocationAlgorithm::initAlgorithm( 
const QVariantMap & )
 
  460  addPredicateParameter();
 
  466QString QgsExtractByLocationAlgorithm::name()
 const 
  468  return QStringLiteral( 
"extractbylocation" );
 
  471QString QgsExtractByLocationAlgorithm::displayName()
 const 
  473  return QObject::tr( 
"Extract by location" );
 
  476QStringList QgsExtractByLocationAlgorithm::tags()
 const 
  478  return QObject::tr( 
"extract,filter,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split( 
',' );
 
  481QString QgsExtractByLocationAlgorithm::group()
 const 
  483  return QObject::tr( 
"Vector selection" );
 
  486QString QgsExtractByLocationAlgorithm::groupId()
 const 
  488  return QStringLiteral( 
"vectorselection" );
 
  491QString QgsExtractByLocationAlgorithm::shortHelpString()
 const 
  493  return QObject::tr( 
"This algorithm creates a new vector layer that only contains matching features from an " 
  494                      "input layer. The criteria for adding features to the resulting layer is defined " 
  495                      "based on the spatial relationship between each feature and the features in an additional layer." );
 
  498QString QgsExtractByLocationAlgorithm::shortDescription()
 const 
  500  return QObject::tr( 
"Creates a vector layer that only contains features matching a spatial relationship with the features in an additional layer." );
 
  503QgsExtractByLocationAlgorithm *QgsExtractByLocationAlgorithm::createInstance()
 const 
  505  return new QgsExtractByLocationAlgorithm();
 
  510  std::unique_ptr<QgsFeatureSource> input( parameterAsSource( parameters, QStringLiteral( 
"INPUT" ), context ) );
 
  513  std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( 
"INTERSECT" ), context ) );
 
  514  if ( !intersectSource )
 
  517  mTargetCrs = input->sourceCrs();
 
  518  mTargetFeatureCount = input->featureCount();
 
  519  mIntersectFeatureCount = intersectSource->
featureCount();
 
  526  std::unique_ptr<QgsFeatureSource> input( parameterAsSource( parameters, QStringLiteral( 
"INPUT" ), context ) );
 
  529  std::unique_ptr<QgsFeatureSource> intersectSource( parameterAsSource( parameters, QStringLiteral( 
"INTERSECT" ), context ) );
 
  530  if ( !intersectSource )
 
  533  const QList<int> selectedPredicates = parameterAsEnums( parameters, QStringLiteral( 
"PREDICATE" ), context );
 
  535  std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, QStringLiteral( 
"OUTPUT" ), context, dest, input->fields(), input->wkbType(), mTargetCrs ) );
 
  540  auto addToSink = [&]( 
const QgsFeature &feature ) {
 
  545  process( context, input.get(), intersectSource.get(), selectedPredicates, addToSink, 
false, feedback );
 
  550  results.insert( QStringLiteral( 
"OUTPUT" ), dest );
 
@ VectorAnyGeometry
Any vector layer with geometry.
 
@ NotPresent
No spatial index exists for the source.
 
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
 
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
 
@ NotAvailableInStandaloneTool
Algorithm should not be available from the standalone "qgis_process" tool. Used to flag algorithms wh...
 
@ NoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
 
SelectBehavior
Specifies how a selection should be applied.
 
@ 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)
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...
 
bool hasGeometry() const
Returns true if the feature has an associated geometry.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
void setProgress(double progress)
Sets the current progress for the feedback object.
 
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.
 
QgsCoordinateReferenceSystem sourceCrs() const FINAL
Returns the coordinate reference system for features in the source.
 
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