I'm trying to implement a processing plugins in QGIS 3.28.9, but when I hit Run, it gives me a message that my polygon layer is not a polygon layer, but, it is a polygon, in fact. Can someone help to fix this problem?
code:
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None or source.wkbType() != QgsWkbTypes.PolygonGeometry:
raise QgsProcessingException('Invalid input source. Expected a polygon layer.')
feedback.setProgressText('Converting polygons to lines...')
converted_lines = processing.run("qgis:polygonstolines", {
'INPUT': source,
'OUTPUT': 'memory:' # Convert to a temporary memory layer
})['OUTPUT']
# Get the output sink
sink = self.parameterAsSink(parameters, self.OUTUPUT, context,
converted_lines.fields(), QgsProcessing.TypeVectorLine)
if sink is None:
raise QgsProcessingException('Invalid output sink')
# Add converted lines to the output sink
sink.addFeatures(converted_lines.getFeatures())
return {self.OUTPUT: sink}
Best Answer
Your layer has a
MultiPolygon
geometry type. Therefore, thesource.wkbType()
test will returnWkbType.MultiPolygon
which is why the processing exception is being raised.Change your conditional statement to:
I assume that you are already passing a list of types to the
QgsProcessingParameterFeatureSource
constructor so that the input layer dropdown box is filtered e.g.But, since it is still possible to select a different input type when using browse or select file...
...a check of the input geometry type is indeed prudent.
However, I suggest that an alternative (and perhaps better practice) way to run the input check is to re-implement and override the
checkParameterValues
method of theQgsProcessingAlgorithm
class and do the check there.Here, we can implement our own logic and return
False
and a helpful message string if the check fails.Following this recommendation given in the docs:
we can use super() which returns an object which represents the base or parent class of a subclass (in this case
QgsProcessingAlgorithm
) and call the default implementation ofcheckParameterValues()
, returning the result- as in this example.Now, if you try to run the algorithm with a non-polygon layer input, you will see this:
Edit: There are a few other issues with your code. You have not passed
is_child_algorithm=True
to yourprocessing.run()
call. This is required since the "native:polygonstolines" alg is being run inside a parent algorithm.As for the persistent error you were getting, I found that to get the child algorithm to accept the parent input, I had to call the
materialize()
method on theQgsProcessingFeatureSource
object to return an in memory copy as aQgsVectorLayer
object.Below is a complete working example. By the way, I guess that you will be adding some more processing steps because, as it is, this whole script is just a wrapper around an existing algorithm. If you add more steps you may want to use
QgsProcessingMultiStepFeedback
. You can see an example in my recent answer here.