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}
1 Answer 1
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}
Explore related questions
See similar questions with these tags.