2

I have a workflow where a raster should be polygonized and afterwards simplified. The simplified vector should be saved as a shapefile. I am using the template script from QGIS to create a processing tool.

I am getting the following error:

Could not load source layer for INPUT: memory: not found

There might be other errors as well. I don't understand what to write in OUTPUT: in any of the processing.run tools.

Furthermore, I am not sure when it is necessary to instance variables (e.g. in_raster = self.parameterAsRasterLayer(...) and I am not sure about the return at the end of the script.

class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
 INPUT_RASTER = 'INPUT_RASTER'
 OUTPUT_POLYGON = 'OUTPUT_POLYGON'
 def initAlgorithm(self, config=None):
 self.addParameter(
 QgsProcessingParameterRasterLayer(
 self.INPUT_RASTER,
 self.tr('Input raster')
 )
 )
 self.addParameter(
 QgsProcessingParameterVectorDestination(
 self.OUTPUT_POLYGON,
 self.tr('Output layer')
 )
 )
 def processAlgorithm(self, parameters, context, feedback):
 in_raster = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
 #in_fs_limit = self.parameterAsDouble(parameters, self.THRESHOLD, context)
 #out_polygon = self.parameterAsOutputLayer(parameters, self.OUTPUT_POLYGON, context)
 
 polygonized_output = processing.run(
 "gdal:polygonize", 
 {
 'INPUT':in_raster,
 'BAND':1,
 'FIELD':'DN',
 'EIGHT_CONNECTEDNESS':False,
 'EXTRA':'',
 'OUTPUT':'memory:'
 }
 )['OUTPUT']
 simplified = processing.run(
 "native:simplifygeometries", 
 {
 'INPUT':polygonized_output,
 'METHOD':0,
 'TOLERANCE':350,
 'OUTPUT':parameters['OUTPUT_POLYGON']
 },
 context=context,
 feedback=feedback
 )['OUTPUT']
 return {self.OUTPUT_POLYGON: simplified}
Taras
35.7k5 gold badges77 silver badges151 bronze badges
asked May 21, 2024 at 9:34

1 Answer 1

3

The error occurs because the intermediate results stored in memory are not being handled properly. QGIS sometimes has trouble managing layers in memory between processing steps.

To fix this, you can either use temporary files for intermediate outputs instead of relying on in-memory storage, something like:

temp_polygonized_output = os.path.join(tempfile.gettempdir(), 'polygonized_output.shp')
temp_simplified_output = os.path.join(tempfile.gettempdir(), 'simplified_output.shp')
 

or do 'OUTPUT': 'TEMPORARY_OUTPUT' as I did below:

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
 QgsFeatureSink,
 QgsProcessingException,
 QgsProcessingAlgorithm,
 QgsProcessingParameterFeatureSource,
 QgsProcessingParameterVectorDestination,
 QgsProcessingParameterRasterLayer,
 QgsProcessingParameterFeatureSink)
from qgis import processing
class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
 """
 This is an example algorithm that takes a vector layer and
 creates a new identical one.
 It is meant to be used as an example of how to create your own
 algorithms and explain the methods and variables used to do it. An
 algorithm like this will be available in all elements, and there
 is no need for additional work.
 All Processing algorithms should extend the QgsProcessingAlgorithm
 class.
 """
 # Constants are used to refer to parameters and outputs. They will be
 # used when calling the algorithm from another algorithm, or when
 # calling from the QGIS console.
 INPUT_RASTER = 'INPUT'
 OUTPUT_POLYGON = 'OUTPUT'
 def tr(self, string):
 """
 Returns a translatable string with the self.tr() function.
 """
 return QCoreApplication.translate('Processing', string)
 
 def createInstance(self):
 """
 Returns a new instance of the algorithm. This is necessary for
 creating the algorithm from within QGIS.
 """
 return ExampleProcessingAlgorithm()
 def name(self):
 """
 Returns the algorithm name, used for identifying the algorithm. This
 string should be fixed for the algorithm, and must not be localised.
 The name should be unique within each provider. Names should contain
 lowercase alphanumeric characters only and no spaces or other
 formatting characters.
 """
 return 'myscript'
 def initAlgorithm(self, config=None):
 self.addParameter(
 QgsProcessingParameterRasterLayer(
 self.INPUT_RASTER,
 self.tr('Input raster')
 )
 )
 self.addParameter(
 QgsProcessingParameterVectorDestination(
 self.OUTPUT_POLYGON,
 self.tr('Output layer')
 )
 )
 def processAlgorithm(self, parameters, context, feedback):
 in_raster = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
 # in_fs_limit = self.parameterAsDouble(parameters, self.THRESHOLD, context)
 out_polygon = self.parameterAsOutputLayer(parameters, self.OUTPUT_POLYGON, context)
 polygonized_output = processing.run(
 "gdal:polygonize",
 {
 'INPUT': in_raster,
 'BAND': 1,
 'FIELD': 'DN',
 'EIGHT_CONNECTEDNESS': False,
 'EXTRA': '',
 'OUTPUT': 'TEMPORARY_OUTPUT'
 }
 )['OUTPUT']
 simplified = processing.run(
 "native:simplifygeometries",
 {
 'INPUT': polygonized_output,
 'METHOD': 0,
 'TOLERANCE': 350,
 'OUTPUT': out_polygon
 },
 context=context,
 feedback=feedback
 )['OUTPUT']
 return {self.OUTPUT_POLYGON: simplified}
Taras
35.7k5 gold badges77 silver badges151 bronze badges
answered May 22, 2024 at 7:11
0

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.