Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] ressurect raster calculator and add CRS parameter
  • Loading branch information
nirvn committed Feb 9, 2018
1 parent f340eec commit 2ed225d
Showing 1 changed file with 32 additions and 22 deletions.
54 changes: 32 additions & 22 deletions python/plugins/processing/algs/qgis/RasterCalculator.py
Expand Up @@ -32,13 +32,15 @@
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingUtils,
QgsProcessingParameterCrs,
QgsProcessingParameterMultipleLayers,
QgsProcessingParameterNumber,
QgsProcessingParameterExtent,
QgsProcessingParameterRasterDestination,
QgsProcessingParameterRasterLayer,
QgsProcessingOutputRasterLayer,
QgsProcessingParameterString)
QgsProcessingParameterString,
QgsCoordinateTransform)
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry


Expand All @@ -48,6 +50,7 @@ class RasterCalculator(QgisAlgorithm):
EXTENT = 'EXTENT'
CELLSIZE = 'CELLSIZE'
EXPRESSION = 'EXPRESSION'
CRS = 'CRS'
OUTPUT = 'OUTPUT'

def group(self):
Expand All @@ -60,13 +63,6 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
layer_param = QgsProcessingParameterMultipleLayers(self.LAYERS,
self.tr('Input layers'),
layerType=QgsProcessing.TypeRaster,
optional=True)
layer_param.setMetadata({'widget_wrapper': 'processing.algs.qgis.ui.RasterCalculatorWidgets.LayersListWidgetWrapper'})
self.addParameter(layer_param)

class ParameterRasterCalculatorExpression(QgsProcessingParameterString):

def __init__(self, name='', description='', multiLine=False):
Expand Down Expand Up @@ -100,13 +96,18 @@ def evaluateForModeler(self, value, model):

self.addParameter(ParameterRasterCalculatorExpression(self.EXPRESSION, self.tr('Expression'),
multiLine=True))
self.addParameter(QgsProcessingParameterMultipleLayers(self.LAYERS,
self.tr('Reference layer(s) (used for automated determination extent and cellsize)'),
layerType=QgsProcessing.TypeRaster,
optional=True))
self.addParameter(QgsProcessingParameterNumber(self.CELLSIZE,
self.tr('Cell size (use 0 or empty to set it automatically)'),
type=QgsProcessingParameterNumber.Double,
minValue=0.0, defaultValue=0.0, optional=True))
self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
self.tr('Output extent'),
optional=True))
self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Output CRS', 'ProjectCrs'))
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output')))

def name(self):
Expand All @@ -118,10 +119,32 @@ def displayName(self):
def processAlgorithm(self, parameters, context, feedback):
expression = self.parameterAsString(parameters, self.EXPRESSION, context)
layers = self.parameterAsLayerList(parameters, self.LAYERS, context)
crs = self.parameterAsCrs(parameters, self.CRS, context)

layersDict = {}
if layers:
layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers}

bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
if not layers and bbox.isNull():
raise QgsProcessingException(self.tr("No reference layer selected to automate extent box"))

if bbox.isNull() and layers:
bbox = QgsProcessingUtils.combineLayerExtents(layers, crs)

cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context)
if not layers and cellsize == 0:
raise QgsProcessingException(self.tr("No reference layer selected to automate cellsize value"))

def _cellsize(layer):
ext = layer.extent()
if layer.crs() != crs:
transform = QgsCoordinateTransform(layer.crs(), crs, context.project())
ext = transform.transformBoundingBox(ext)
return (ext.xMaximum() - ext.xMinimum()) / layer.width()
if cellsize == 0:
cellsize = min([_cellsize(lyr) for lyr in layersDict.values()])

for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()):
name = lyr.name()
if (name + "@") in expression:
Expand All @@ -137,28 +160,15 @@ def processAlgorithm(self, parameters, context, feedback):
entries.append(entry)

output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
if bbox.isNull():
bbox = QgsProcessingUtils.combineLayerExtents(layers)

if bbox.isNull():
if layersDict:
bbox = list(layersDict.values())[0].extent()
for lyr in layersDict.values():
bbox.combineExtentWith(lyr.extent())
else:
raise QgsProcessingException(self.tr("No layers selected"))

def _cellsize(layer):
return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width()
cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) or min([_cellsize(lyr) for lyr in layersDict.values()])
width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize)
height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize)
driverName = GdalUtils.getFormatShortNameFromFilename(output)
calc = QgsRasterCalculator(expression,
output,
driverName,
bbox,
crs,
width,
height,
entries)
Expand Down

0 comments on commit 2ed225d

Please sign in to comment.