24 void QgsLocationBasedAlgorithm::addPredicateParameter()
27 QObject::tr(
"Where the features (geometric predicate)" ),
28 predicateOptionsList(),
true, QVariant::fromValue( QList< int >() << 0 ) ) );
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 );
37 addParameter( predicateParam.release() );
40 QgsLocationBasedAlgorithm::Predicate QgsLocationBasedAlgorithm::reversePredicate( QgsLocationBasedAlgorithm::Predicate predicate )
const
65 QStringList QgsLocationBasedAlgorithm::predicateOptionsList()
const
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" );
79 const QList< int > &selectedPredicates,
80 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
81 bool onlyRequireTargetIds,
89 processByIteratingOverTargetSource( context, targetSource, intersectSource,
90 selectedPredicates, handleFeatureFunction,
91 onlyRequireTargetIds, feedback );
101 processByIteratingOverIntersectSource( context, targetSource, intersectSource,
102 selectedPredicates, handleFeatureFunction,
103 onlyRequireTargetIds, feedback );
109 const QList< int > &selectedPredicates,
110 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
111 bool onlyRequireTargetIds,
115 feedback->
reportError( QObject::tr(
"No spatial index exists for intersect layer, performance will be severely degraded" ) );
119 if ( onlyRequireTargetIds )
126 std::unique_ptr< QgsGeometryEngine > engine;
142 bool isMatch =
false;
143 bool isDisjoint =
true;
152 engine->prepareGeometry();
155 for (
int predicate : selectedPredicates )
157 switch (
static_cast< Predicate
>( predicate ) )
194 foundSet.insert( f.
id() );
195 handleFeatureFunction( f );
199 if ( isDisjoint && selectedPredicates.contains( Disjoint ) )
201 foundSet.insert( f.
id() );
202 handleFeatureFunction( f );
212 const QList< int > &selectedPredicates,
213 const std::function <
void(
const QgsFeature & ) > &handleFeatureFunction,
214 bool onlyRequireTargetIds,
218 feedback->
reportError( QObject::tr(
"No spatial index exists for input layer, performance will be severely degraded" ) );
223 QList< Predicate > predicates;
224 predicates.reserve( selectedPredicates.count() );
225 for (
int i : selectedPredicates )
227 predicates << reversePredicate( static_cast< Predicate >( i ) );
231 if ( predicates.contains( Disjoint ) )
240 std::unique_ptr< QgsGeometryEngine > engine;
253 if ( onlyRequireTargetIds )
263 if ( foundSet.contains( testFeature.
id() ) )
268 if ( predicates.count() == 1 && predicates.at( 0 ) == Disjoint && !disjointSet.contains( testFeature.
id() ) )
277 engine->prepareGeometry();
280 for ( Predicate predicate : qgis::as_const( predicates ) )
282 bool isMatch =
false;
294 disjointSet.remove( testFeature.
id() );
315 foundSet.insert( testFeature.
id() );
316 handleFeatureFunction( testFeature );
326 if ( predicates.contains( Disjoint ) )
328 disjointSet = disjointSet.subtract( foundSet );
330 if ( onlyRequireTargetIds )
336 handleFeatureFunction( f );
346 void QgsSelectByLocationAlgorithm::initAlgorithm(
const QVariantMap & )
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" );
355 addPredicateParameter();
357 QObject::tr(
"By comparing to the features from" ),
361 QObject::tr(
"Modify current selection by" ),
362 methods,
false, 0 ) );
365 QString QgsSelectByLocationAlgorithm::name()
const
367 return QStringLiteral(
"selectbylocation" );
370 QgsProcessingAlgorithm::Flags QgsSelectByLocationAlgorithm::flags()
const
375 QString QgsSelectByLocationAlgorithm::displayName()
const
377 return QObject::tr(
"Select by location" );
380 QStringList QgsSelectByLocationAlgorithm::tags()
const
382 return QObject::tr(
"select,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split(
',' );
385 QString QgsSelectByLocationAlgorithm::group()
const
387 return QObject::tr(
"Vector selection" );
390 QString QgsSelectByLocationAlgorithm::groupId()
const
392 return QStringLiteral(
"vectorselection" );
395 QString QgsSelectByLocationAlgorithm::shortHelpString()
const
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." );
401 QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance()
const
403 return new QgsSelectByLocationAlgorithm();
408 QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral(
"INPUT" ), context );
413 std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral(
"INTERSECT" ), context ) );
414 if ( !intersectSource )
417 const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral(
"PREDICATE" ), context );
420 auto addToSelection = [&](
const QgsFeature & feature )
422 selectedIds.insert( feature.id() );
424 process( context, selectLayer, intersectSource.get(), selectedPredicates, addToSelection,
true, feedback );
428 results.insert( QStringLiteral(
"OUTPUT" ), parameters.value( QStringLiteral(
"INPUT" ) ) );
437 void QgsExtractByLocationAlgorithm::initAlgorithm(
const QVariantMap & )
440 QObject::tr(
"Extract features from" ),
442 addPredicateParameter();
444 QObject::tr(
"By comparing to the features from" ),
450 QString QgsExtractByLocationAlgorithm::name()
const
452 return QStringLiteral(
"extractbylocation" );
455 QString QgsExtractByLocationAlgorithm::displayName()
const
457 return QObject::tr(
"Extract by location" );
460 QStringList QgsExtractByLocationAlgorithm::tags()
const
462 return QObject::tr(
"extract,filter,intersects,intersecting,disjoint,touching,within,contains,overlaps,relation" ).split(
',' );
465 QString QgsExtractByLocationAlgorithm::group()
const
467 return QObject::tr(
"Vector selection" );
470 QString QgsExtractByLocationAlgorithm::groupId()
const
472 return QStringLiteral(
"vectorselection" );
475 QString QgsExtractByLocationAlgorithm::shortHelpString()
const
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." );
482 QgsExtractByLocationAlgorithm *QgsExtractByLocationAlgorithm::createInstance()
const
484 return new QgsExtractByLocationAlgorithm();
489 std::unique_ptr< QgsFeatureSource > input( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
492 std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral(
"INTERSECT" ), context ) );
493 if ( !intersectSource )
496 const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral(
"PREDICATE" ), context );
498 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, input->fields(), input->wkbType(), input->sourceCrs() ) );
503 auto addToSink = [&](
const QgsFeature & feature )
508 process( context, input.get(), intersectSource.get(), selectedPredicates, addToSink,
false, feedback );
511 results.insert( QStringLiteral(
"OUTPUT" ), dest );