25 void QgsLocationBasedAlgorithm::addPredicateParameter()
28 QObject::tr(
"Where the features (geometric predicate)" ),
29 predicateOptionsList(),
true, QVariant::fromValue( QList< int >() << 0 ) ) );
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 );
38 addParameter( predicateParam.release() );
41 QgsLocationBasedAlgorithm::Predicate QgsLocationBasedAlgorithm::reversePredicate( QgsLocationBasedAlgorithm::Predicate predicate )
const
66 QStringList QgsLocationBasedAlgorithm::predicateOptionsList()
const
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" );
80 const QList< int > &selectedPredicates,
81 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
82 bool onlyRequireTargetIds,
92 !selectedPredicates.contains( Disjoint ) )
99 processByIteratingOverTargetSource( context, targetSource, intersectSource,
100 selectedPredicates, handleFeatureFunction,
101 onlyRequireTargetIds, feedback, skipTargetFeatureIds );
111 processByIteratingOverIntersectSource( context, targetSource, intersectSource,
112 selectedPredicates, handleFeatureFunction,
113 onlyRequireTargetIds, feedback, skipTargetFeatureIds );
119 const QList< int > &selectedPredicates,
120 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
121 bool onlyRequireTargetIds,
126 feedback->
pushWarning( QObject::tr(
"No spatial index exists for intersect layer, performance will be severely degraded" ) );
130 if ( onlyRequireTargetIds )
137 std::unique_ptr< QgsGeometryEngine > engine;
144 if ( skipTargetFeatureIds.contains( f.
id() ) )
156 bool isMatch =
false;
157 bool isDisjoint =
true;
166 engine->prepareGeometry();
169 for (
int predicate : selectedPredicates )
171 switch (
static_cast< Predicate
>( predicate ) )
208 foundSet.insert( f.
id() );
209 handleFeatureFunction( f );
213 if ( isDisjoint && selectedPredicates.contains( Disjoint ) )
215 foundSet.insert( f.
id() );
216 handleFeatureFunction( f );
226 const QList< int > &selectedPredicates,
227 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
228 bool onlyRequireTargetIds,
233 feedback->
pushWarning( QObject::tr(
"No spatial index exists for input layer, performance will be severely degraded" ) );
238 QList< Predicate > predicates;
239 predicates.reserve( selectedPredicates.count() );
240 for (
int i : selectedPredicates )
242 predicates << reversePredicate( static_cast< Predicate >( i ) );
246 if ( predicates.contains( Disjoint ) )
255 std::unique_ptr< QgsGeometryEngine > engine;
268 if ( onlyRequireTargetIds )
278 if ( skipTargetFeatureIds.contains( testFeature.
id() ) )
283 if ( foundSet.contains( testFeature.
id() ) )
288 if ( predicates.count() == 1 && predicates.at( 0 ) == Disjoint && !disjointSet.contains( testFeature.
id() ) )
297 engine->prepareGeometry();
300 bool isMatch =
false;
302 for ( Predicate predicate : std::as_const( predicates ) )
315 disjointSet.remove( testFeature.
id() );
340 foundSet.insert( testFeature.
id() );
341 handleFeatureFunction( testFeature );
350 if ( predicates.contains( Disjoint ) )
352 disjointSet = disjointSet.subtract( foundSet );
354 if ( onlyRequireTargetIds )
360 handleFeatureFunction( f );
370 void QgsSelectByLocationAlgorithm::initAlgorithm(
const QVariantMap & )
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" );
379 addPredicateParameter();
381 QObject::tr(
"By comparing to the features from" ),
385 QObject::tr(
"Modify current selection by" ),
386 methods,
false, 0 ) );
389 QString QgsSelectByLocationAlgorithm::name()
const
391 return QStringLiteral(
"selectbylocation" );
394 QgsProcessingAlgorithm::Flags QgsSelectByLocationAlgorithm::flags()
const
399 QString QgsSelectByLocationAlgorithm::displayName()
const
401 return QObject::tr(
"Select by location" );
404 QStringList QgsSelectByLocationAlgorithm::tags()
const
406 return QObject::tr(
"select,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split(
',' );
409 QString QgsSelectByLocationAlgorithm::group()
const
411 return QObject::tr(
"Vector selection" );
414 QString QgsSelectByLocationAlgorithm::groupId()
const
416 return QStringLiteral(
"vectorselection" );
419 QString QgsSelectByLocationAlgorithm::shortHelpString()
const
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." );
425 QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance()
const
427 return new QgsSelectByLocationAlgorithm();
432 QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral(
"INPUT" ), context );
437 std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral(
"INTERSECT" ), context ) );
438 if ( !intersectSource )
441 const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral(
"PREDICATE" ), context );
444 auto addToSelection = [&](
const QgsFeature & feature )
446 selectedIds.insert( feature.id() );
455 process( context, selectLayerSelected.get(), intersectSource.get(), selectedPredicates, addToSelection,
true, feedback );
460 process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection,
true, feedback, selectLayer->
selectedFeatureIds() );
463 process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection,
true, feedback );
469 results.insert( QStringLiteral(
"OUTPUT" ), parameters.value( QStringLiteral(
"INPUT" ) ) );
478 void QgsExtractByLocationAlgorithm::initAlgorithm(
const QVariantMap & )
481 QObject::tr(
"Extract features from" ),
483 addPredicateParameter();
485 QObject::tr(
"By comparing to the features from" ),
491 QString QgsExtractByLocationAlgorithm::name()
const
493 return QStringLiteral(
"extractbylocation" );
496 QString QgsExtractByLocationAlgorithm::displayName()
const
498 return QObject::tr(
"Extract by location" );
501 QStringList QgsExtractByLocationAlgorithm::tags()
const
503 return QObject::tr(
"extract,filter,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split(
',' );
506 QString QgsExtractByLocationAlgorithm::group()
const
508 return QObject::tr(
"Vector selection" );
511 QString QgsExtractByLocationAlgorithm::groupId()
const
513 return QStringLiteral(
"vectorselection" );
516 QString QgsExtractByLocationAlgorithm::shortHelpString()
const
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." );
523 QgsExtractByLocationAlgorithm *QgsExtractByLocationAlgorithm::createInstance()
const
525 return new QgsExtractByLocationAlgorithm();
530 std::unique_ptr< QgsFeatureSource > input( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
533 std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral(
"INTERSECT" ), context ) );
534 if ( !intersectSource )
537 const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral(
"PREDICATE" ), context );
539 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, input->fields(), input->wkbType(), input->sourceCrs() ) );
544 auto addToSink = [&](
const QgsFeature & feature )
550 process( context, input.get(), intersectSource.get(), selectedPredicates, addToSink,
false, feedback );
553 results.insert( QStringLiteral(
"OUTPUT" ), dest );