Skip to content

Commit 202d331

Browse files
committedMay 21, 2014
[processing] simplified saga algorithms
Now it assumes matching grid extents and does not perform resampling
1 parent c1a2ac8 commit 202d331

File tree

5 files changed

+27
-161
lines changed

5 files changed

+27
-161
lines changed
 

‎python/plugins/processing/algs/saga/SagaAlgorithm.py

Lines changed: 23 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -63,34 +63,18 @@ class SagaAlgorithm(GeoAlgorithm):
6363
OUTPUT_EXTENT = 'OUTPUT_EXTENT'
6464

6565
def __init__(self, descriptionfile):
66-
# True if it should resample
67-
self.resample = True
66+
self.allowUnmatchingGridExtents = False
6867

6968
# In case several non-matching raster layers are used as input
7069
GeoAlgorithm.__init__(self)
7170
self.descriptionFile = descriptionfile
7271
self.defineCharacteristicsFromFile()
73-
if self.resample:
74-
# Reconsider resampling policy now that we know the input
75-
# parameters
76-
self.resample = self.setResamplingPolicy()
7772

7873
def getCopy(self):
7974
newone = SagaAlgorithm(self.descriptionFile)
8075
newone.provider = self.provider
8176
return newone
8277

83-
def setResamplingPolicy(self):
84-
count = 0
85-
for param in self.parameters:
86-
if isinstance(param, ParameterRaster):
87-
count += 1
88-
if isinstance(param, ParameterMultipleInput):
89-
if param.datatype == ParameterMultipleInput.TYPE_RASTER:
90-
return True
91-
92-
return count > 1
93-
9478
def getIcon(self):
9579
return QIcon(os.path.dirname(__file__) + '/../../images/saga.png')
9680

@@ -116,8 +100,8 @@ def defineCharacteristicsFromFile(self):
116100
self.hardcodedStrings.append(line[len('Harcoded|') + 1:])
117101
elif line.startswith('Parameter'):
118102
self.addParameter(ParameterFactory.getFromString(line))
119-
elif line.startswith('DontResample'):
120-
self.resample = False
103+
elif line.startswith('AllowUnmatching'):
104+
self.allowUnmatchingGridExtents = True
121105
elif line.startswith('Extent'):
122106
# An extent parameter that wraps 4 SAGA numerical parameters
123107
self.extentParamNames = line[6:].strip().split(' ')
@@ -128,71 +112,6 @@ def defineCharacteristicsFromFile(self):
128112
line = lines.readline().strip('\n').strip()
129113
lines.close()
130114

131-
def calculateResamplingExtent(self):
132-
"""This method calculates the resampling extent, but it might
133-
set self.resample to False if, with the current layers, there
134-
is no need to resample.
135-
"""
136-
137-
auto = ProcessingConfig.getSetting(SagaUtils.SAGA_AUTO_RESAMPLING)
138-
if auto:
139-
first = True
140-
self.inputExtentsCount = 0
141-
for param in self.parameters:
142-
if param.value:
143-
if isinstance(param, ParameterRaster):
144-
if isinstance(param.value, QgsRasterLayer):
145-
layer = param.value
146-
else:
147-
layer = dataobjects.getObjectFromUri(param.value)
148-
self.addToResamplingExtent(layer, first)
149-
first = False
150-
if isinstance(param, ParameterMultipleInput):
151-
if param.datatype \
152-
== ParameterMultipleInput.TYPE_RASTER:
153-
layers = param.value.split(';')
154-
for layername in layers:
155-
layer = dataobjects.getObjectFromUri(layername)
156-
self.addToResamplingExtent(layer, first)
157-
first = False
158-
if self.inputExtentsCount < 2:
159-
self.resample = False
160-
else:
161-
self.xmin = ProcessingConfig.getSetting(
162-
SagaUtils.SAGA_RESAMPLING_REGION_XMIN)
163-
self.xmax = ProcessingConfig.getSetting(
164-
SagaUtils.SAGA_RESAMPLING_REGION_XMAX)
165-
self.ymin = ProcessingConfig.getSetting(
166-
SagaUtils.SAGA_RESAMPLING_REGION_YMIN)
167-
self.ymax = ProcessingConfig.getSetting(
168-
SagaUtils.SAGA_RESAMPLING_REGION_YMAX)
169-
self.cellsize = ProcessingConfig.getSetting(
170-
SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE)
171-
172-
def addToResamplingExtent(self, layer, first):
173-
if layer is None:
174-
return
175-
if first:
176-
self.inputExtentsCount = 1
177-
self.xmin = layer.extent().xMinimum()
178-
self.xmax = layer.extent().xMaximum()
179-
self.ymin = layer.extent().yMinimum()
180-
self.ymax = layer.extent().yMaximum()
181-
self.cellsize = (layer.extent().xMaximum()
182-
- layer.extent().xMinimum()) / layer.width()
183-
else:
184-
cellsize = (layer.extent().xMaximum() -
185-
layer.extent().xMinimum()) / layer.width()
186-
if self.xmin != layer.extent().xMinimum() or self.xmax \
187-
!= layer.extent().xMaximum() or self.ymin \
188-
!= layer.extent().yMinimum() or self.ymax \
189-
!= layer.extent().yMaximum() or self.cellsize != cellsize:
190-
self.xmin = min(self.xmin, layer.extent().xMinimum())
191-
self.xmax = max(self.xmax, layer.extent().xMaximum())
192-
self.ymin = min(self.ymin, layer.extent().yMinimum())
193-
self.ymax = max(self.ymax, layer.extent().yMaximum())
194-
self.cellsize = min(self.cellsize, cellsize)
195-
self.inputExtentsCount += 1
196115

197116
def processAlgorithm(self, progress):
198117
if isWindows():
@@ -208,8 +127,6 @@ def processAlgorithm(self, progress):
208127

209128
# 1: Export rasters to sgrd and vectors to shp
210129
# Tables must be in dbf format. We check that.
211-
if self.resample:
212-
self.calculateResamplingExtent()
213130
for param in self.parameters:
214131
if isinstance(param, ParameterRaster):
215132
if param.value is None:
@@ -219,8 +136,6 @@ def processAlgorithm(self, progress):
219136
exportCommand = self.exportRasterLayer(value)
220137
if exportCommand is not None:
221138
commands.append(exportCommand)
222-
if self.resample:
223-
commands.append(self.resampleRasterLayer(value))
224139
if isinstance(param, ParameterVector):
225140
if param.value is None:
226141
continue
@@ -253,9 +168,6 @@ def processAlgorithm(self, progress):
253168
exportCommand = self.exportRasterLayer(layerfile)
254169
if exportCommand is not None:
255170
commands.append(exportCommand)
256-
if self.resample:
257-
commands.append(
258-
self.resampleRasterLayer(layerfile))
259171
elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
260172
for layerfile in layers:
261173
layer = dataobjects.getObjectFromUri(layerfile, False)
@@ -421,34 +333,7 @@ def getOutputCellsize(self):
421333
cellsize = float(param.value)
422334
break
423335
return cellsize
424-
425-
def resampleRasterLayer(self, layer):
426-
"""This is supposed to be run after having exported all raster
427-
layers.
428-
"""
429-
430-
if layer in self.exportedLayers.keys():
431-
inputFilename = self.exportedLayers[layer]
432-
else:
433-
inputFilename = layer
434-
destFilename = getTempFilename('sgrd')
435-
self.exportedLayers[layer] = destFilename
436-
saga208 = ProcessingConfig.getSetting(SagaUtils.SAGA_208)
437-
if isWindows() or isMac() or not saga208:
438-
s = 'grid_tools "Resampling" -INPUT "' + inputFilename \
439-
+ '" -TARGET 0 -SCALE_UP_METHOD 0 -SCALE_DOWN_METHOD 0 -USER_XMIN ' \
440-
+ str(self.xmin) + ' -USER_XMAX ' + str(self.xmax) \
441-
+ ' -USER_YMIN ' + str(self.ymin) + ' -USER_YMAX ' \
442-
+ str(self.ymax) + ' -USER_SIZE ' + str(self.cellsize) \
443-
+ ' -USER_GRID "' + destFilename + '"'
444-
else:
445-
s = 'libgrid_tools "Resampling" -INPUT "' + inputFilename \
446-
+ '" -TARGET 0 -SCALE_UP_METHOD 0 -SCALE_DOWN_METHOD 0 -USER_XMIN ' \
447-
+ str(self.xmin) + ' -USER_XMAX ' + str(self.xmax) \
448-
+ ' -USER_YMIN ' + str(self.ymin) + ' -USER_YMAX ' \
449-
+ str(self.ymax) + ' -USER_SIZE ' + str(self.cellsize) \
450-
+ ' -USER_GRID "' + destFilename + '"'
451-
return s
336+
452337

453338
def exportRasterLayer(self, source):
454339
if source in sessionExportedLayers:
@@ -485,22 +370,33 @@ def checkBeforeOpeningParametersDialog(self):
485370
html = '<p>This algorithm requires SAGA to be run.Unfortunately, \
486371
it seems that SAGA is not installed in your system, or it \
487372
is not correctly configured to be used from QGIS</p>'
488-
html += '<p><a href= "http://docs.qgis.org/2.0/en/docs/user_manual/processing/3rdParty.html">Click here</a> to know more about how to install and configure SAGA to be used with QGIS</p>'
373+
html += '<p><a href= "http://docs.qgis.org/2.0/en/docs/user_manual/processing/3rdParty.html">\
374+
Click here</a> to know more about how to install and configure SAGA to be used with QGIS</p>'
489375
return html
490376

491377
def checkParameterValuesBeforeExecuting(self):
492-
"""We check that there are no multiband layers, which are not
493-
supported by SAGA.
494378
"""
495-
379+
We check that there are no multiband layers, which are not
380+
supported by SAGA, and that raster layers have the same grid extent
381+
"""
382+
extent = None
496383
for param in self.parameters:
497-
if isinstance(param, ParameterRaster):
498-
value = param.value
499-
layer = dataobjects.getObjectFromUri(value)
500-
if layer is not None and layer.bandCount() > 1:
384+
if isinstance(param, ParameterRaster):
385+
layer = dataobjects.getObjectFromUri(param.value)
386+
if layer is None:
387+
continue
388+
if layer.bandCount() > 1:
501389
return 'Input layer ' + str(layer.name()) \
502390
+ ' has more than one band.\n' \
503391
+ 'Multiband layers are not supported by SAGA'
392+
if extent is None:
393+
extent = (layer.extent(), layer.height(), layer.width())
394+
else:
395+
extent2 = (layer.extent(), layer.height(), layer.width())
396+
if extent != extent2:
397+
return "Input layers do not have the same grid extent."
398+
399+
504400

505401
def help(self):
506402
name = self.cmdname.lower()

‎python/plugins/processing/algs/saga/SagaAlgorithmProvider.py

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,48 +51,23 @@ def initializeSettings(self):
5151
SagaUtils.sagaPath()))
5252
ProcessingConfig.addSetting(Setting(self.getDescription(),
5353
SagaUtils.SAGA_208,
54-
'Enable SAGA 2.0.8 compatibility', True))
54+
'Use SAGA 2.0.8 syntax', True))
5555
ProcessingConfig.addSetting(Setting(self.getDescription(),
5656
SagaUtils.SAGA_IMPORT_EXPORT_OPTIMIZATION,
5757
'Enable SAGA Import/Export optimizations',
5858
False))
59-
ProcessingConfig.addSetting(Setting(self.getDescription(),
60-
SagaUtils.SAGA_AUTO_RESAMPLING,
61-
'Use min covering grid system for resampling', True))
6259
ProcessingConfig.addSetting(Setting(self.getDescription(),
6360
SagaUtils.SAGA_LOG_COMMANDS,
6461
'Log execution commands', True))
6562
ProcessingConfig.addSetting(Setting(self.getDescription(),
6663
SagaUtils.SAGA_LOG_CONSOLE,
6764
'Log console output', True))
68-
ProcessingConfig.addSetting(Setting(self.getDescription(),
69-
SagaUtils.SAGA_RESAMPLING_REGION_XMIN,
70-
'Resampling region min x', 0))
71-
ProcessingConfig.addSetting(Setting(self.getDescription(),
72-
SagaUtils.SAGA_RESAMPLING_REGION_YMIN,
73-
'Resampling region min y', 0))
74-
ProcessingConfig.addSetting(Setting(self.getDescription(),
75-
SagaUtils.SAGA_RESAMPLING_REGION_XMAX,
76-
'Resampling region max x', 1000))
77-
ProcessingConfig.addSetting(Setting(self.getDescription(),
78-
SagaUtils.SAGA_RESAMPLING_REGION_YMAX,
79-
'Resampling region max y', 1000))
80-
ProcessingConfig.addSetting(Setting(self.getDescription(),
81-
SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE,
82-
'Resampling region cellsize', 1))
8365

8466
def unload(self):
8567
AlgorithmProvider.unload(self)
8668
if isWindows():
8769
ProcessingConfig.removeSetting(SagaUtils.SAGA_FOLDER)
88-
89-
ProcessingConfig.removeSetting(SagaUtils.SAGA_AUTO_RESAMPLING)
90-
ProcessingConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMIN)
91-
ProcessingConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMIN)
92-
ProcessingConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMAX)
93-
ProcessingConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMAX)
94-
ProcessingConfig.removeSetting(
95-
SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE)
70+
9671
ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_CONSOLE)
9772
ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_COMMANDS)
9873

‎python/plugins/processing/algs/saga/SagaUtils.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ class SagaUtils:
4242
SAGA_208 = 'SAGA_208'
4343
SAGA_LOG_COMMANDS = 'SAGA_LOG_COMMANDS'
4444
SAGA_LOG_CONSOLE = 'SAGA_LOG_CONSOLE'
45-
SAGA_AUTO_RESAMPLING = 'SAGA_AUTO_RESAMPLING'
46-
SAGA_RESAMPLING_REGION_XMIN = 'SAGA_RESAMPLING_REGION_XMIN'
47-
SAGA_RESAMPLING_REGION_YMIN = 'SAGA_RESAMPLING_REGION_YMIN'
48-
SAGA_RESAMPLING_REGION_XMAX = 'SAGA_RESAMPLING_REGION_XMAX'
49-
SAGA_RESAMPLING_REGION_YMAX = 'SAGA_RESAMPLING_REGION_YMAX'
50-
SAGA_RESAMPLING_REGION_CELLSIZE = 'SAGA_RESAMPLING_REGION_CELLSIZE'
5145
SAGA_FOLDER = 'SAGA_FOLDER'
5246
SAGA_IMPORT_EXPORT_OPTIMIZATION = 'SAGA_IMPORT_EXPORT_OPTIMIZATION'
5347

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Raster calculator|Grid Calculator
22
grid_calculus
3+
AllowUnmatching
34
ParameterMultipleInput|GRIDS|Raster layers|3|False
45
ParameterString|FORMULA|Formula|
56
OutputRaster|RESULT|Result

‎python/plugins/processing/algs/saga/description/Merging.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Merge raster layers|Merging
22
grid_tools
3-
DontResample
3+
AllowUnmatching
44
ParameterMultipleInput|GRIDS|Grids to Merge|3|False
55
ParameterSelection|TYPE|Preferred data storage type|[0] 1 bit;[1] 1 byte unsigned integer;[2] 1 byte signed integer;[3] 2 byte unsigned integer;[4] 2 byte signed integer;[5] 4 byte unsigned integer;[6] 4 byte signed integer;[7] 4 byte floating point;[8] 8 byte floating point
66
ParameterSelection|INTERPOL|Interpolation|[0] Nearest Neighbor;[1] Bilinear Interpolation;[2] Inverse Distance Interpolation;[3] Bicubic Spline Interpolation;[4] B-Spline Interpolation

0 commit comments

Comments
 (0)
Please sign in to comment.