Skip to content

Commit 2ed225d

Browse files
committedFeb 9, 2018
[processing] ressurect raster calculator and add CRS parameter
1 parent f340eec commit 2ed225d

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed
 

‎python/plugins/processing/algs/qgis/RasterCalculator.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@
3232
from qgis.core import (QgsProcessing,
3333
QgsProcessingException,
3434
QgsProcessingUtils,
35+
QgsProcessingParameterCrs,
3536
QgsProcessingParameterMultipleLayers,
3637
QgsProcessingParameterNumber,
3738
QgsProcessingParameterExtent,
3839
QgsProcessingParameterRasterDestination,
3940
QgsProcessingParameterRasterLayer,
4041
QgsProcessingOutputRasterLayer,
41-
QgsProcessingParameterString)
42+
QgsProcessingParameterString,
43+
QgsCoordinateTransform)
4244
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
4345

4446

@@ -48,6 +50,7 @@ class RasterCalculator(QgisAlgorithm):
4850
EXTENT = 'EXTENT'
4951
CELLSIZE = 'CELLSIZE'
5052
EXPRESSION = 'EXPRESSION'
53+
CRS = 'CRS'
5154
OUTPUT = 'OUTPUT'
5255

5356
def group(self):
@@ -60,13 +63,6 @@ def __init__(self):
6063
super().__init__()
6164

6265
def initAlgorithm(self, config=None):
63-
layer_param = QgsProcessingParameterMultipleLayers(self.LAYERS,
64-
self.tr('Input layers'),
65-
layerType=QgsProcessing.TypeRaster,
66-
optional=True)
67-
layer_param.setMetadata({'widget_wrapper': 'processing.algs.qgis.ui.RasterCalculatorWidgets.LayersListWidgetWrapper'})
68-
self.addParameter(layer_param)
69-
7066
class ParameterRasterCalculatorExpression(QgsProcessingParameterString):
7167

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

10197
self.addParameter(ParameterRasterCalculatorExpression(self.EXPRESSION, self.tr('Expression'),
10298
multiLine=True))
99+
self.addParameter(QgsProcessingParameterMultipleLayers(self.LAYERS,
100+
self.tr('Reference layer(s) (used for automated determination extent and cellsize)'),
101+
layerType=QgsProcessing.TypeRaster,
102+
optional=True))
103103
self.addParameter(QgsProcessingParameterNumber(self.CELLSIZE,
104104
self.tr('Cell size (use 0 or empty to set it automatically)'),
105105
type=QgsProcessingParameterNumber.Double,
106106
minValue=0.0, defaultValue=0.0, optional=True))
107107
self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
108108
self.tr('Output extent'),
109109
optional=True))
110+
self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Output CRS', 'ProjectCrs'))
110111
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output')))
111112

112113
def name(self):
@@ -118,10 +119,32 @@ def displayName(self):
118119
def processAlgorithm(self, parameters, context, feedback):
119120
expression = self.parameterAsString(parameters, self.EXPRESSION, context)
120121
layers = self.parameterAsLayerList(parameters, self.LAYERS, context)
122+
crs = self.parameterAsCrs(parameters, self.CRS, context)
123+
121124
layersDict = {}
122125
if layers:
123126
layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers}
124127

128+
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
129+
if not layers and bbox.isNull():
130+
raise QgsProcessingException(self.tr("No reference layer selected to automate extent box"))
131+
132+
if bbox.isNull() and layers:
133+
bbox = QgsProcessingUtils.combineLayerExtents(layers, crs)
134+
135+
cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context)
136+
if not layers and cellsize == 0:
137+
raise QgsProcessingException(self.tr("No reference layer selected to automate cellsize value"))
138+
139+
def _cellsize(layer):
140+
ext = layer.extent()
141+
if layer.crs() != crs:
142+
transform = QgsCoordinateTransform(layer.crs(), crs, context.project())
143+
ext = transform.transformBoundingBox(ext)
144+
return (ext.xMaximum() - ext.xMinimum()) / layer.width()
145+
if cellsize == 0:
146+
cellsize = min([_cellsize(lyr) for lyr in layersDict.values()])
147+
125148
for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()):
126149
name = lyr.name()
127150
if (name + "@") in expression:
@@ -137,28 +160,15 @@ def processAlgorithm(self, parameters, context, feedback):
137160
entries.append(entry)
138161

139162
output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
140-
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
141-
if bbox.isNull():
142-
bbox = QgsProcessingUtils.combineLayerExtents(layers)
143163

144-
if bbox.isNull():
145-
if layersDict:
146-
bbox = list(layersDict.values())[0].extent()
147-
for lyr in layersDict.values():
148-
bbox.combineExtentWith(lyr.extent())
149-
else:
150-
raise QgsProcessingException(self.tr("No layers selected"))
151-
152-
def _cellsize(layer):
153-
return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width()
154-
cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) or min([_cellsize(lyr) for lyr in layersDict.values()])
155164
width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize)
156165
height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize)
157166
driverName = GdalUtils.getFormatShortNameFromFilename(output)
158167
calc = QgsRasterCalculator(expression,
159168
output,
160169
driverName,
161170
bbox,
171+
crs,
162172
width,
163173
height,
164174
entries)

0 commit comments

Comments
 (0)
Please sign in to comment.