9

While extending a plugin with a Processing Provider and a set of algorithms I mostly followed the defaults of Plugin Builder 3. So, the basic code is smth along the lines of

class ORSisochronesAlgo(QgsProcessingAlgorithm):
 def initAlgorithm(self, configuration, p_str=None, Any=None, *args, **kwargs):
 # add all input parameters
 self.addParameter(
 QgsProcessingParameterFeatureSink(
 'OUTPUT',
 'Output layer'
 )
 )
 def processAlgorithm(self, parameters, context, feedback):
 source = self.parameterAsSource(parameters, self.INPUT, context)
 (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
 context, source.fields(), source.wkbType(), source.sourceCrs())
 features = source.getFeatures()
 for feature in features:
 new_feature = QgsFeature()
 # Some API calls and processing to populate new feature
 sink.addFeature(new_feature, QgsFeatureSink.FastInsert)
 return {self.OUTPUT: dest_id}

So, the output layer is automatically handled and added to the map. Very nice!

But now: How do I post-process that output layer within the Processing Algorithm? Sounds weird maybe, but here are 2 scenarios:

  • Depending on the value of a Boolean input parameter, I'd like to be able to calculate geometric differences of the output features. For this to work, the layer has to be built first. And then handled in some sort of post-processing.

  • Also, I'd like to be able to customize the style of the output layer.

There is the postProcessAlgorithm() method for QgsProcessingAlgorithm, but I'm not so sure how to work with this.. It doesn't seem to take parameters as input, no idea how to access the output layer.

Being able to do this would make the plugin so much more user-friendly.

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Dec 9, 2018 at 14:10
1
  • Ok, I think I got it.. Using QgsProcessingUtils.mapLayerFromString() lets one access layers from the provided context and one can use that in the class's postProcessAlgorithm(). I'll post an answer if I have entirely succeeded. At least styling the layer already works:) Commented Dec 9, 2018 at 14:41

1 Answer 1

11

Just to be more elaborate than the comment.

Basically, the postProcessAlgorithm() does what it says. It also returns a value map, including the OUTPUT. However, you need to look up the layer in the algorithm's context with QgsProcessingUtils.mapLayerFromString(). For that to work, you have to save a reference to the original output layer from processAlgorithm():

class ORSisochronesAlgo(QgsProcessingAlgorithm):
 dest_id = None # Save a reference to the output layer id
 def initAlgorithm(self, configuration, p_str=None, Any=None, *args, **kwargs):
 # add all input parameters
 self.addParameter(
 QgsProcessingParameterFeatureSink(
 'OUTPUT',
 'Output layer'
 )
 )
 def processAlgorithm(self, parameters, context, feedback):
 source = self.parameterAsSource(parameters, self.INPUT, context)
 (sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
 context, source.fields(), source.wkbType(), source.sourceCrs())
 features = source.getFeatures()
 for feature in features:
 new_feature = QgsFeature()
 # Some API calls and processing to populate new feature
 sink.addFeature(new_feature, QgsFeatureSink.FastInsert)
 return {self.OUTPUT: dest_id}
 def postProcessAlgorithm(self, context, feedback):
 processed_layer = QgsProcessingUtils.mapLayerFromString(self.dest_id, context)
 # Do smth with the layer, e.g. style it
 return {self.OUT: self.dest_id}
answered Dec 9, 2018 at 21:35
1
  • I think it should be return {self.OUPUT: self.dest_id} Commented Nov 8, 2021 at 11:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.