4

I have multiple WFS that show the same features (streets) in different regions. I would like to write a model that extracts the features from the current map extent.

How do I let the model know, which layer has features in the current map extend, so I don't end up with a lot of empty layers?

Can the QGIS modeler check, if a layer has features in the current map extent?

2 Answers 2

4

You could use the "Extract/clip by extent" algorithm from the "Vector overlay" Toolbox on every layer (select the option "Use Current Map Canvas Extent" as Extent) and than count the features in the resulting output layer (If count > 0: Layer is in current map extent).

Another way to do it, is using a python script: Just iterate over your map layers and then check if they intersect with your current map extent:

canvas = iface.mapCanvas()
current_extent = canvas.extent()

layers = QgsProject.instance().mapLayers().values()

visible_layers = []
for layer in layers:
    if layer.type() == QgsMapLayer.VectorLayer:
        if any(feature.geometry().intersects(current_extent) for feature in layer.getFeatures()):
            visible_layers.append(layer.name())

print(visible_layers)
2

I would also think in terms of PyQGIS combined with editing the model by hand. There is a useful method variantToSource() from the QgsProcessingUtils class. After its implementation, one gets a pure QgsProcessingFeatureSource-object that possesses a hasFeatures method.

On the other side, one could handle the empty QgsProcessingFeatureSource as an empty dictionary i.e. {}, however, the temporary output will still be added. Therefore I am suggesting adding the QgsProcessingException in this case to ignore empty temporary outputs.

So, in the end, your model may look as follows:

"""
Model exported as python.
Name : filterwfs
Group : Models
With QGIS : 33408
"""

from qgis.core import (QgsProcessing,
                       QgsProcessingAlgorithm,
                       QgsProcessingMultiStepFeedback,
                       QgsProcessingParameterVectorLayer,
                       QgsProcessingParameterFeatureSink,
                       QgsProcessingException,
                       QgsProcessingUtils)
from qgis.utils import iface
import processing


class Filterwfs(QgsProcessingAlgorithm):

    def name(self):
        return 'filterwfs'

    def displayName(self):
        return 'filterwfs'

    def group(self):
        return 'Models'

    def groupId(self):
        return 'Models'

    def createInstance(self):
        return Filterwfs()

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterVectorLayer('input', 'INPUT', defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('output', 'OUTPUT', type=QgsProcessing.TypeVectorPolygon,
                                                            createByDefault=False, defaultValue=None))

    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(1, model_feedback)
        results = {}
        outputs = {}

        # Extract/clip by extent
        alg_params = {
            'INPUT': parameters['input'],
            'EXTENT': iface.mapCanvas().extent(),
            'CLIP': False,
            'OUTPUT': parameters['output']
        }
        outputs['extract'] = processing.run("native:extractbyextent", alg_params, context=context, feedback=feedback,
                                            is_child_algorithm=True)
        results['Output'] = outputs['extract']['OUTPUT']

        source = QgsProcessingUtils.variantToSource(results['Output'], context=context, fallbackValue=feedback)
        if source.hasFeatures() > 0:
            return results
        else:
            raise QgsProcessingException('Empty layer was not added.')

References:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.