I have written a simple QgsProcessingAlgorithm
that populates a QgsFeatureSink
.
Before outputting the result, I need to call another algorithm to clip my features.
Everything seems to work just fine, the clip algorithm
is called and its output shows in the log, except my actual output is not clipped.
It seems the sink is returned no matter what I specify to be actually returned by the function.
What I am doing wrong ?
from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.processing import alg
from qgis.core import (
QgsField,
QgsFields,
QgsFeature,
QgsFeatureSink,
QgsGeometry,
QgsPointXY,
QgsProcessing,
QgsProcessingAlgorithm,
QgsWkbTypes
)
import processing
import random
@alg(name='test_alg', label=alg.tr('Test'), group='test', group_label=alg.tr('Test'))
@alg.input(type=alg.SOURCE, name='INPUT', label='Input')
@alg.input(type=int, name='NB_POINTS', label='Number of points to create', default=1000, minValue=10, maxValue=100000)
@alg.input(type=alg.SINK, name='OUTPUT', label='Output')
def testAlg(instance, parameters, context, feedback, inputs):
"""
Test script to randomly generate n points unniformly distributed within a polygon extent
and clip the result with regards to the polygon itself.
"""
# Define some attributes
fields = QgsFields()
fields.append(QgsField('Point_No', QVariant.Double))
# Initialise variables
source = instance.parameterAsSource(parameters, 'INPUT', context)
nb_points = instance.parameterAsInt(parameters, 'NB_POINTS', context)
# Setup the sink
(sink, dest_id) = instance.parameterAsSink(parameters, 'OUTPUT', context, fields, QgsWkbTypes.Point, source.sourceCrs())
# Define the Points generator
def genPoints(n, extent, attributes):
"""
Generator to produce the Points yielded as Features with attribute
"""
feat = QgsFeature()
xmin, xmax, ymin, ymax = extent.xMinimum(), extent.xMaximum(), extent.yMinimum(), extent.yMaximum()
total = 100 / n
for i in range(n):
feedback.setProgress(i * total)
attributes[0] = i
x, y = random.uniform(xmin, xmax), random.uniform(ymin, ymax)
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
feat.setAttributes(attributes)
yield feat
feedback.pushInfo(f'Generating {nb_points} Points')
sink.addFeatures(genPoints(nb_points, source.sourceExtent(), [0]),
QgsFeatureSink.FastInsert)
feedback.pushInfo('Clipping to Input Polygon...')
clipped_points = processing.run('native:clip', {
'INPUT': dest_id,
'OVERLAY': parameters['INPUT'],
'OUTPUT': 'memory:ClippedPoints',
}, context=context, feedback=feedback)['OUTPUT']
return {'OUTPUT': clipped_points.id()}