mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			467 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			467 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
"""
 | 
						|
***************************************************************************
 | 
						|
    SagaAlgorithm.py
 | 
						|
    ---------------------
 | 
						|
    Date                 : August 2012
 | 
						|
    Copyright            : (C) 2012 by Victor Olaya
 | 
						|
    Email                : volayaf at gmail dot com
 | 
						|
***************************************************************************
 | 
						|
*                                                                         *
 | 
						|
*   This program is free software; you can redistribute it and/or modify  *
 | 
						|
*   it under the terms of the GNU General Public License as published by  *
 | 
						|
*   the Free Software Foundation; either version 2 of the License, or     *
 | 
						|
*   (at your option) any later version.                                   *
 | 
						|
*                                                                         *
 | 
						|
***************************************************************************
 | 
						|
"""
 | 
						|
 | 
						|
__author__ = 'Victor Olaya'
 | 
						|
__date__ = 'August 2012'
 | 
						|
__copyright__ = '(C) 2012, Victor Olaya'
 | 
						|
 | 
						|
import os
 | 
						|
import shutil
 | 
						|
import importlib
 | 
						|
from qgis.core import (Qgis,
 | 
						|
                       QgsApplication,
 | 
						|
                       QgsProcessingUtils,
 | 
						|
                       QgsProcessingException,
 | 
						|
                       QgsMessageLog,
 | 
						|
                       QgsProcessing,
 | 
						|
                       QgsProcessingAlgorithm,
 | 
						|
                       QgsProcessingParameterRasterLayer,
 | 
						|
                       QgsProcessingParameterFeatureSource,
 | 
						|
                       QgsProcessingParameterBoolean,
 | 
						|
                       QgsProcessingParameterNumber,
 | 
						|
                       QgsProcessingParameterEnum,
 | 
						|
                       QgsProcessingParameterMultipleLayers,
 | 
						|
                       QgsProcessingParameterMatrix,
 | 
						|
                       QgsProcessingParameterString,
 | 
						|
                       QgsProcessingParameterField,
 | 
						|
                       QgsProcessingParameterFile,
 | 
						|
                       QgsProcessingParameterExtent,
 | 
						|
                       QgsProcessingParameterRasterDestination,
 | 
						|
                       QgsProcessingParameterVectorDestination)
 | 
						|
from processing.core.ProcessingConfig import ProcessingConfig
 | 
						|
from processing.algs.help import shortHelp
 | 
						|
from processing.tools.system import getTempFilename
 | 
						|
from processing.algs.saga.SagaNameDecorator import decoratedAlgorithmName, decoratedGroupName
 | 
						|
from processing.algs.saga.SagaParameters import Parameters
 | 
						|
from . import SagaUtils
 | 
						|
from .SagaAlgorithmBase import SagaAlgorithmBase
 | 
						|
 | 
						|
pluginPath = os.path.normpath(os.path.join(
 | 
						|
    os.path.split(os.path.dirname(__file__))[0], os.pardir))
 | 
						|
 | 
						|
sessionExportedLayers = {}
 | 
						|
 | 
						|
 | 
						|
class SagaAlgorithm(SagaAlgorithmBase):
 | 
						|
    OUTPUT_EXTENT = 'OUTPUT_EXTENT'
 | 
						|
 | 
						|
    def __init__(self, descriptionfile):
 | 
						|
        super().__init__()
 | 
						|
        self.hardcoded_strings = []
 | 
						|
        self.allow_nonmatching_grid_extents = False
 | 
						|
        self.description_file = descriptionfile
 | 
						|
        self.undecorated_group = None
 | 
						|
        self._name = ''
 | 
						|
        self._display_name = ''
 | 
						|
        self._group = ''
 | 
						|
        self._groupId = ''
 | 
						|
        self.params = []
 | 
						|
        self.known_issues = False
 | 
						|
        self.defineCharacteristicsFromFile()
 | 
						|
 | 
						|
    def createInstance(self):
 | 
						|
        return SagaAlgorithm(self.description_file)
 | 
						|
 | 
						|
    def initAlgorithm(self, config=None):
 | 
						|
        for p in self.params:
 | 
						|
            self.addParameter(p)
 | 
						|
 | 
						|
    def name(self):
 | 
						|
        return self._name
 | 
						|
 | 
						|
    def displayName(self):
 | 
						|
        return self._display_name
 | 
						|
 | 
						|
    def group(self):
 | 
						|
        return self._group
 | 
						|
 | 
						|
    def groupId(self):
 | 
						|
        return self._groupId
 | 
						|
 | 
						|
    def shortHelpString(self):
 | 
						|
        return shortHelp.get(self.id(), None)
 | 
						|
 | 
						|
    def icon(self):
 | 
						|
        return QgsApplication.getThemeIcon("/providerSaga.svg")
 | 
						|
 | 
						|
    def svgIconPath(self):
 | 
						|
        return QgsApplication.iconPath("providerSaga.svg")
 | 
						|
 | 
						|
    def flags(self):
 | 
						|
        # TODO - maybe it's safe to background thread this?
 | 
						|
        f = super().flags() | QgsProcessingAlgorithm.FlagNoThreading
 | 
						|
        if self.known_issues:
 | 
						|
            f = f | QgsProcessingAlgorithm.FlagKnownIssues
 | 
						|
        return f
 | 
						|
 | 
						|
    def defineCharacteristicsFromFile(self):
 | 
						|
        with open(self.description_file, encoding="utf-8") as lines:
 | 
						|
            line = lines.readline().strip('\n').strip()
 | 
						|
 | 
						|
            self._name = line
 | 
						|
            if '|' in self._name:
 | 
						|
                tokens = self._name.split('|')
 | 
						|
                self._name = tokens[0]
 | 
						|
                # cmdname is the name of the algorithm in SAGA, that is, the name to use to call it in the console
 | 
						|
                self.cmdname = tokens[1]
 | 
						|
 | 
						|
            else:
 | 
						|
                self.cmdname = self._name
 | 
						|
                self._display_name = self.tr(str(self._name))
 | 
						|
            self._name = decoratedAlgorithmName(self._name)
 | 
						|
            self._display_name = self.tr(str(self._name))
 | 
						|
 | 
						|
            self._name = self._name.lower()
 | 
						|
            validChars = \
 | 
						|
                'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
 | 
						|
            self._name = ''.join(c for c in self._name if c in validChars)
 | 
						|
 | 
						|
            line = lines.readline().strip('\n').strip()
 | 
						|
            if line == '##known_issues':
 | 
						|
                self.known_issues = True
 | 
						|
                line = lines.readline().strip('\n').strip()
 | 
						|
 | 
						|
            self.undecorated_group = line
 | 
						|
            self._group = self.tr(decoratedGroupName(self.undecorated_group))
 | 
						|
 | 
						|
            validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
 | 
						|
            grpName = decoratedGroupName(self.undecorated_group).lower()
 | 
						|
            self._groupId = ''.join(c for c in grpName if c in validChars)
 | 
						|
            line = lines.readline().strip('\n').strip()
 | 
						|
            while line != '':
 | 
						|
                if line.startswith('Hardcoded'):
 | 
						|
                    self.hardcoded_strings.append(line[len('Hardcoded|'):])
 | 
						|
                elif Parameters.is_parameter_line(line):
 | 
						|
                    self.params.append(Parameters.create_parameter_from_line(line))
 | 
						|
                elif line.startswith('AllowUnmatching'):
 | 
						|
                    self.allow_nonmatching_grid_extents = True
 | 
						|
                else:
 | 
						|
                    pass  # TODO
 | 
						|
                    # self.addOutput(getOutputFromString(line))
 | 
						|
                line = lines.readline().strip('\n').strip()
 | 
						|
 | 
						|
    def processAlgorithm(self, parameters, context, feedback):
 | 
						|
        commands = list()
 | 
						|
        self.exportedLayers = {}
 | 
						|
 | 
						|
        self.preProcessInputs()
 | 
						|
        extent = None
 | 
						|
        crs = None
 | 
						|
 | 
						|
        # 1: Export rasters to sgrd and vectors to shp
 | 
						|
        # Tables must be in dbf format. We check that.
 | 
						|
        for param in self.parameterDefinitions():
 | 
						|
            if isinstance(param, QgsProcessingParameterRasterLayer):
 | 
						|
                if param.name() not in parameters or parameters[param.name()] is None:
 | 
						|
                    continue
 | 
						|
 | 
						|
                if isinstance(parameters[param.name()], str):
 | 
						|
                    if parameters[param.name()].lower().endswith('sdat'):
 | 
						|
                        self.exportedLayers[param.name()] = parameters[param.name()][:-4] + 'sgrd'
 | 
						|
                    elif parameters[param.name()].lower().endswith('sgrd'):
 | 
						|
                        self.exportedLayers[param.name()] = parameters[param.name()]
 | 
						|
                    else:
 | 
						|
                        layer = self.parameterAsRasterLayer(parameters, param.name(), context)
 | 
						|
                        exportCommand = self.exportRasterLayer(param.name(), layer)
 | 
						|
                        if exportCommand is not None:
 | 
						|
                            commands.append(exportCommand)
 | 
						|
                else:
 | 
						|
                    if parameters[param.name()].source().lower().endswith('sdat'):
 | 
						|
                        self.exportedLayers[param.name()] = parameters[param.name()].source()[:-4] + 'sgrd'
 | 
						|
                    if parameters[param.name()].source().lower().endswith('sgrd'):
 | 
						|
                        self.exportedLayers[param.name()] = parameters[param.name()].source()
 | 
						|
                    else:
 | 
						|
                        exportCommand = self.exportRasterLayer(param.name(), parameters[param.name()])
 | 
						|
                        if exportCommand is not None:
 | 
						|
                            commands.append(exportCommand)
 | 
						|
            elif isinstance(param, QgsProcessingParameterFeatureSource):
 | 
						|
                if param.name() not in parameters or parameters[param.name()] is None:
 | 
						|
                    continue
 | 
						|
 | 
						|
                if not crs:
 | 
						|
                    source = self.parameterAsSource(parameters, param.name(), context)
 | 
						|
                    if source is None:
 | 
						|
                        raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))
 | 
						|
 | 
						|
                    crs = source.sourceCrs()
 | 
						|
 | 
						|
                layer_path = self.parameterAsCompatibleSourceLayerPath(parameters, param.name(), context, ['shp'], 'shp', feedback=feedback)
 | 
						|
                if layer_path:
 | 
						|
                    self.exportedLayers[param.name()] = layer_path
 | 
						|
                else:
 | 
						|
                    raise QgsProcessingException(
 | 
						|
                        self.tr('Unsupported file format'))
 | 
						|
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
 | 
						|
                if param.name() not in parameters or parameters[param.name()] is None:
 | 
						|
                    continue
 | 
						|
 | 
						|
                layers = self.parameterAsLayerList(parameters, param.name(), context)
 | 
						|
                if layers is None or len(layers) == 0:
 | 
						|
                    continue
 | 
						|
                if param.layerType() == QgsProcessing.TypeRaster:
 | 
						|
                    files = []
 | 
						|
                    for i, layer in enumerate(layers):
 | 
						|
                        if layer.source().lower().endswith('sdat'):
 | 
						|
                            files.append(layer.source()[:-4] + 'sgrd')
 | 
						|
                        elif layer.source().lower().endswith('sgrd'):
 | 
						|
                            files.append(layer.source())
 | 
						|
                        else:
 | 
						|
                            exportCommand = self.exportRasterLayer(param.name(), layer)
 | 
						|
                            files.append(self.exportedLayers[param.name()])
 | 
						|
                            if exportCommand is not None:
 | 
						|
                                commands.append(exportCommand)
 | 
						|
 | 
						|
                    self.exportedLayers[param.name()] = files
 | 
						|
                else:
 | 
						|
                    for layer in layers:
 | 
						|
                        temp_params = {}
 | 
						|
                        temp_params[param.name()] = layer
 | 
						|
 | 
						|
                        if not crs:
 | 
						|
                            source = self.parameterAsSource(temp_params, param.name(), context)
 | 
						|
                            if source is None:
 | 
						|
                                raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))
 | 
						|
 | 
						|
                            crs = source.sourceCrs()
 | 
						|
 | 
						|
                        layer_path = self.parameterAsCompatibleSourceLayerPath(temp_params, param.name(), context, ['shp'], 'shp',
 | 
						|
                                                                               feedback=feedback)
 | 
						|
                        if layer_path:
 | 
						|
                            if param.name() in self.exportedLayers:
 | 
						|
                                self.exportedLayers[param.name()].append(layer_path)
 | 
						|
                            else:
 | 
						|
                                self.exportedLayers[param.name()] = [layer_path]
 | 
						|
                        else:
 | 
						|
                            raise QgsProcessingException(
 | 
						|
                                self.tr('Unsupported file format'))
 | 
						|
 | 
						|
        # 2: Set parameters and outputs
 | 
						|
        command = self.undecorated_group + ' "' + self.cmdname + '"'
 | 
						|
        command += ' ' + ' '.join(self.hardcoded_strings)
 | 
						|
 | 
						|
        for param in self.parameterDefinitions():
 | 
						|
            if not param.name() in parameters or parameters[param.name()] is None:
 | 
						|
                continue
 | 
						|
            if param.isDestination():
 | 
						|
                continue
 | 
						|
 | 
						|
            if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource)):
 | 
						|
                command += ' -{} "{}"'.format(param.name(), self.exportedLayers[param.name()])
 | 
						|
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
 | 
						|
                if parameters[param.name()]:  # parameter may have been an empty list
 | 
						|
                    command += ' -{} "{}"'.format(param.name(), ';'.join(self.exportedLayers[param.name()]))
 | 
						|
            elif isinstance(param, QgsProcessingParameterBoolean):
 | 
						|
                if self.parameterAsBoolean(parameters, param.name(), context):
 | 
						|
                    command += ' -{} true'.format(param.name().strip())
 | 
						|
                else:
 | 
						|
                    command += ' -{} false'.format(param.name().strip())
 | 
						|
            elif isinstance(param, QgsProcessingParameterMatrix):
 | 
						|
                tempTableFile = getTempFilename('txt')
 | 
						|
                with open(tempTableFile, 'w') as f:
 | 
						|
                    f.write('\t'.join([col for col in param.headers()]) + '\n')
 | 
						|
                    values = self.parameterAsMatrix(parameters, param.name(), context)
 | 
						|
                    for i in range(0, len(values), 3):
 | 
						|
                        s = '{}\t{}\t{}\n'.format(values[i], values[i + 1], values[i + 2])
 | 
						|
                        f.write(s)
 | 
						|
                command += ' -{} "{}"'.format(param.name(), tempTableFile)
 | 
						|
            elif isinstance(param, QgsProcessingParameterExtent):
 | 
						|
                # 'We have to subtract/add half cell size, since SAGA is
 | 
						|
                # center based, not corner based
 | 
						|
                halfcell = self.getOutputCellsize(parameters, context) / 2
 | 
						|
                offset = [halfcell, -halfcell, halfcell, -halfcell]
 | 
						|
                rect = self.parameterAsExtent(parameters, param.name(), context)
 | 
						|
 | 
						|
                values = []
 | 
						|
                values.append(rect.xMinimum())
 | 
						|
                values.append(rect.xMaximum())
 | 
						|
                values.append(rect.yMinimum())
 | 
						|
                values.append(rect.yMaximum())
 | 
						|
 | 
						|
                for i in range(4):
 | 
						|
                    command += ' -{} {}'.format(param.name().split(' ')[i], float(values[i]) + offset[i])
 | 
						|
            elif isinstance(param, QgsProcessingParameterNumber):
 | 
						|
                if param.dataType() == QgsProcessingParameterNumber.Integer:
 | 
						|
                    command += ' -{} {}'.format(param.name(), self.parameterAsInt(parameters, param.name(), context))
 | 
						|
                else:
 | 
						|
                    command += ' -{} {}'.format(param.name(), self.parameterAsDouble(parameters, param.name(), context))
 | 
						|
            elif isinstance(param, QgsProcessingParameterEnum):
 | 
						|
                command += ' -{} {}'.format(param.name(), self.parameterAsEnum(parameters, param.name(), context))
 | 
						|
            elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterFile)):
 | 
						|
                command += ' -{} "{}"'.format(param.name(), self.parameterAsFile(parameters, param.name(), context))
 | 
						|
            elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterField)):
 | 
						|
                command += ' -{} "{}"'.format(param.name(), self.parameterAsString(parameters, param.name(), context))
 | 
						|
 | 
						|
        output_layers = []
 | 
						|
        output_files = {}
 | 
						|
        # If the user has entered an output file that has non-ascii chars, we use a different path with only ascii chars
 | 
						|
        output_files_nonascii = {}
 | 
						|
        for out in self.destinationParameterDefinitions():
 | 
						|
            filePath = self.parameterAsOutputLayer(parameters, out.name(), context)
 | 
						|
            if isinstance(out, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination)):
 | 
						|
                output_layers.append(filePath)
 | 
						|
                try:
 | 
						|
                    filePath.encode('ascii')
 | 
						|
                except UnicodeEncodeError:
 | 
						|
                    nonAsciiFilePath = filePath
 | 
						|
                    filePath = QgsProcessingUtils.generateTempFilename(out.name() + os.path.splitext(filePath)[1])
 | 
						|
                    output_files_nonascii[filePath] = nonAsciiFilePath
 | 
						|
 | 
						|
            output_files[out.name()] = filePath
 | 
						|
            command += ' -{} "{}"'.format(out.name(), filePath)
 | 
						|
        commands.append(command)
 | 
						|
 | 
						|
        # special treatment for RGB algorithm
 | 
						|
        # TODO: improve this and put this code somewhere else
 | 
						|
        for out in self.destinationParameterDefinitions():
 | 
						|
            if isinstance(out, QgsProcessingParameterRasterDestination):
 | 
						|
                filename = self.parameterAsOutputLayer(parameters, out.name(), context)
 | 
						|
                filename2 = os.path.splitext(filename)[0] + '.sgrd'
 | 
						|
                if self.cmdname == 'RGB Composite':
 | 
						|
                    commands.append('io_grid_image 0 -COLOURING 4 -GRID:"{}" -FILE:"{}"'.format(filename2, filename))
 | 
						|
 | 
						|
        # 3: Run SAGA
 | 
						|
        commands = self.editCommands(commands)
 | 
						|
        SagaUtils.createSagaBatchJobFileFromSagaCommands(commands)
 | 
						|
        loglines = []
 | 
						|
        loglines.append(self.tr('SAGA execution commands'))
 | 
						|
        for line in commands:
 | 
						|
            feedback.pushCommandInfo(line)
 | 
						|
            loglines.append(line)
 | 
						|
        if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS):
 | 
						|
            QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), Qgis.Info)
 | 
						|
        SagaUtils.executeSaga(feedback)
 | 
						|
 | 
						|
        if crs is not None:
 | 
						|
            for out in output_layers:
 | 
						|
                prjFile = os.path.splitext(out)[0] + '.prj'
 | 
						|
                with open(prjFile, 'w') as f:
 | 
						|
                    f.write(crs.toWkt())
 | 
						|
 | 
						|
        for old, new in output_files_nonascii.items():
 | 
						|
            oldFolder = os.path.dirname(old)
 | 
						|
            newFolder = os.path.dirname(new)
 | 
						|
            newName = os.path.splitext(os.path.basename(new))[0]
 | 
						|
            files = [f for f in os.listdir(oldFolder)]
 | 
						|
            for f in files:
 | 
						|
                ext = os.path.splitext(f)[1]
 | 
						|
                newPath = os.path.join(newFolder, newName + ext)
 | 
						|
                oldPath = os.path.join(oldFolder, f)
 | 
						|
                shutil.move(oldPath, newPath)
 | 
						|
 | 
						|
        result = {}
 | 
						|
        for o in self.outputDefinitions():
 | 
						|
            if o.name() in output_files:
 | 
						|
                result[o.name()] = output_files[o.name()]
 | 
						|
        return result
 | 
						|
 | 
						|
    def preProcessInputs(self):
 | 
						|
        name = self.name().replace('.', '_')
 | 
						|
        try:
 | 
						|
            module = importlib.import_module('processing.algs.saga.ext.' + name)
 | 
						|
        except ImportError:
 | 
						|
            return
 | 
						|
        if hasattr(module, 'preProcessInputs'):
 | 
						|
            func = getattr(module, 'preProcessInputs')
 | 
						|
            func(self)
 | 
						|
 | 
						|
    def editCommands(self, commands):
 | 
						|
        try:
 | 
						|
            module = importlib.import_module('processing.algs.saga.ext.' + self.name())
 | 
						|
        except ImportError:
 | 
						|
            return commands
 | 
						|
        if hasattr(module, 'editCommands'):
 | 
						|
            func = getattr(module, 'editCommands')
 | 
						|
            return func(commands)
 | 
						|
        else:
 | 
						|
            return commands
 | 
						|
 | 
						|
    def getOutputCellsize(self, parameters, context):
 | 
						|
        """Tries to guess the cell size of the output, searching for
 | 
						|
        a parameter with an appropriate name for it.
 | 
						|
        :param parameters:
 | 
						|
        """
 | 
						|
 | 
						|
        cellsize = 0
 | 
						|
        for param in self.parameterDefinitions():
 | 
						|
            if param.name() in parameters and param.name() == 'USER_SIZE':
 | 
						|
                cellsize = self.parameterAsDouble(parameters, param.name(), context)
 | 
						|
                break
 | 
						|
        return cellsize
 | 
						|
 | 
						|
    def exportRasterLayer(self, parameterName, layer):
 | 
						|
        global sessionExportedLayers
 | 
						|
        if layer.source() in sessionExportedLayers:
 | 
						|
            exportedLayer = sessionExportedLayers[layer.source()]
 | 
						|
            if os.path.exists(exportedLayer):
 | 
						|
                self.exportedLayers[parameterName] = exportedLayer
 | 
						|
                return None
 | 
						|
            else:
 | 
						|
                del sessionExportedLayers[layer.source()]
 | 
						|
 | 
						|
        if layer:
 | 
						|
            filename = layer.name()
 | 
						|
        else:
 | 
						|
            filename = os.path.basename(layer.source())
 | 
						|
 | 
						|
        validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
 | 
						|
        filename = ''.join(c for c in filename if c in validChars)
 | 
						|
 | 
						|
        if len(filename) == 0:
 | 
						|
            filename = 'layer'
 | 
						|
 | 
						|
        destFilename = QgsProcessingUtils.generateTempFilename(filename + '.sgrd')
 | 
						|
        sessionExportedLayers[layer.source()] = destFilename
 | 
						|
        self.exportedLayers[parameterName] = destFilename
 | 
						|
 | 
						|
        return 'io_gdal 0 -TRANSFORM 1 -RESAMPLING 3 -GRIDS "{}" -FILES "{}"'.format(destFilename, layer.source())
 | 
						|
 | 
						|
    def checkParameterValues(self, parameters, context):
 | 
						|
        """
 | 
						|
        We check that there are no multiband layers, which are not
 | 
						|
        supported by SAGA, and that raster layers have the same grid extent
 | 
						|
        """
 | 
						|
        extent = None
 | 
						|
        raster_layer_params = []
 | 
						|
        for param in self.parameterDefinitions():
 | 
						|
            if param not in parameters or parameters[param.name()] is None:
 | 
						|
                continue
 | 
						|
 | 
						|
            if isinstance(param, QgsProcessingParameterRasterLayer):
 | 
						|
                raster_layer_params.append(param.name())
 | 
						|
            elif (isinstance(param, QgsProcessingParameterMultipleLayers)
 | 
						|
                    and param.layerType() == QgsProcessing.TypeRaster):
 | 
						|
                raster_layer_params.extend(param.name())
 | 
						|
 | 
						|
        for layer_param in raster_layer_params:
 | 
						|
            layer = self.parameterAsRasterLayer(parameters, layer_param, context)
 | 
						|
 | 
						|
            if layer is None:
 | 
						|
                continue
 | 
						|
            if layer.bandCount() > 1:
 | 
						|
                return False, self.tr('Input layer {0} has more than one band.\n'
 | 
						|
                                      'Multiband layers are not supported by SAGA').format(layer.name())
 | 
						|
            if not self.allow_nonmatching_grid_extents:
 | 
						|
                if extent is None:
 | 
						|
                    extent = (layer.extent(), layer.height(), layer.width())
 | 
						|
                else:
 | 
						|
                    extent2 = (layer.extent(), layer.height(), layer.width())
 | 
						|
                    if extent != extent2:
 | 
						|
                        return False, self.tr("Input layers do not have the same grid extent.")
 | 
						|
        return super(SagaAlgorithm, self).checkParameterValues(parameters, context)
 |