With the transition from QGIS2.x to QGIS3.x the whole processing framework has been reworked and large parts of it run now as C++ classes that you can interact with using Python. Unfortunately the simple parameter syntax for data/dataset IO are no longer valid. The new parameter structure is much more orientated after the builtin (Python-) Processing algorithms that you find preinstalled in the toolbox.
As I see, you already followed the description of the new algorithm structure by @underdark. But in order to adjust this structure for your requirements (raster layers, double input, etc.) you have to change the code at multiple locations in the script. I have coded a rough example with a short explanation for you (just an algorithm skeleton based on @underdarks example):
from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.core import (QgsProcessing, QgsProcessingAlgorithm,
QgsProcessingParameterRasterLayer,QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
class RasterAlg(QgsProcessingAlgorithm):
INPUT_RASTER_A = 'INPUT_RASTER_A'
INPUT_RASTER_B = 'INPUT_RASTER_B'
INPUT_DOUBLE = 'INPUT_DOUBLE'
OUTPUT_RASTER_A = 'OUTPUT_RASTER_A'
OUTPUT_RASTER_B = 'OUTPUT_RASTER_B'
def __init__(self):
super().__init__()
def name(self):
return "RasterAlg"
def tr(self, text):
return QCoreApplication.translate("RasterAlg", text)
def displayName(self):
return self.tr("RasterAlg script")
def group(self):
return self.tr("RasterAlgs")
def groupId(self):
return "RasterAlgs"
def shortHelpString(self):
return self.tr("RasterAlg script without logic")
def helpUrl(self):
return "https://qgis.org"
def createInstance(self):
return type(self)()
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterRasterLayer(
self.INPUT_RASTER_A,
self.tr("Input Raster A"), None, False))
self.addParameter(QgsProcessingParameterRasterLayer(
self.INPUT_RASTER_B,
self.tr("Input Raster B"), None, False))
self.addParameter(QgsProcessingParameterNumber(
self.INPUT_DOUBLE,
self.tr("Input Double"),
QgsProcessingParameterNumber.Double,
QVariant(1.0)))
self.addParameter(QgsProcessingParameterRasterDestination(
self.OUTPUT_RASTER_A,
self.tr("Output Raster A"),
None, False))
self.addParameter(QgsProcessingParameterRasterDestination(
self.OUTPUT_RASTER_B,
self.tr("Output Raster B"),
None, False))
def processAlgorithm(self, parameters, context, feedback):
raster_a = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER_A, context)
raster_b = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER_B, context)
double_val = self.parameterAsDouble(parameters, self.INPUT_DOUBLE,context)
output_path_raster_a = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER_A, context)
output_path_raster_b = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER_B, context)
#DO SOME CALCULATION
results = {}
results[self.OUTPUT_RASTER_A] = output_path_raster_a
results[self.OUTPUT_RASTER_B] = output_path_raster_b
return results
Which steps are done?
- Import all necessary classes.
- Define the algorithm as a class inheriting from
QgsProcessingAlgorithm
.
- First you have to declare the names of the input and output parameters as string variables (parameter names) of the algorithm class (ie.
INPUT_RASTER_A = 'INPUT_RASTER_A'
) in order to reference your algorithm with the parameters provided by the processing framework.
- Add the methods that wire your algorithm to the processing toolbox gui and provide helpstrings, etc.
- Then you add the parameters of the processing framework. Those are defined as child classes of
QgsProcessingParameterType
- in the case of your algorithm: QgsProcessingParameterRasterLayer
, QgsProcessingParameterNumber
, and so on. You can consult the API entries (ie. QgsProcessingParameterRasterLayer
) in order to pass the right arguments and construct the parameter objects.
- Pass the parameters alongside
context
and feedback
objects to the processAlgorithm()
method where you obtain the input datasets from the parameters at runtime (in this case QgsRasterLayer objects by using the parameterAsRasterLayer()
method, etc.).
- Do your computation.
- Add the outputs to the results dictionary and return them as result of calling
processAlgorithm()
.
I hope I could give you some insights on how to design your python algorithms in QGIS3. Whenever you are stuck, it is always helpful to look at how existing algorithms of the processing framework handle the parameters. You can have a look at them here.