Skip to content

Commit 6bf8448

Browse files
author
Médéric Ribreux
committed
Improve cell size detection and FileDestinationOutput (but not perfect)
1 parent f32bba4 commit 6bf8448

File tree

2 files changed

+57
-52
lines changed

2 files changed

+57
-52
lines changed

python/plugins/processing/algs/grass7/Grass7Algorithm.py

+51-52
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
QgsProcessingParameterFileDestination,
5858
QgsProcessingOutputVectorLayer,
5959
QgsProcessingOutputRasterLayer,
60-
QgsProcessingOutputHtml)
60+
QgsProcessingOutputHtml,
61+
QgsProcessingUtils)
6162
from qgis.utils import iface
6263

6364
from processing.core.ProcessingConfig import ProcessingConfig
@@ -66,7 +67,8 @@
6667

6768
from .Grass7Utils import Grass7Utils
6869

69-
from processing.tools import dataobjects, system
70+
#from processing.tools import dataobjects, system
71+
from processing.tools.system import isWindows, getTempFilename
7072

7173
pluginPath = os.path.normpath(os.path.join(
7274
os.path.split(os.path.dirname(__file__))[0], os.pardir))
@@ -172,7 +174,12 @@ def initAlgorithm(self, config=None):
172174
"""
173175
for p in self.params:
174176
# We use createOutput argument for automatic output creation
175-
self.addParameter(p, True)
177+
res = self.addParameter(p, True)
178+
# File destinations are not automatically added as outputs
179+
if isinstance(p, QgsProcessingParameterFileDestination):
180+
self.addOutput(QgsProcessingOutputHtml(p.name(), p.description()))
181+
QgsMessageLog.logMessage('initAlgorithm {} ({}):{}'.format(p.name(), p.isDestination(), res), 'Grass7', QgsMessageLog.INFO)
182+
QgsMessageLog.logMessage('initAlgo: {}'.format(p.toOutputDefinition()), 'Grass7', QgsMessageLog.INFO)
176183

177184
def defineCharacteristicsFromFile(self):
178185
"""
@@ -266,39 +273,27 @@ def getDefaultCellSize(self, parameters, context):
266273
"""
267274
Determine a default cell size from all the raster layers.
268275
"""
269-
if self.cellSize:
270-
return True
271-
272-
cellsize = 0
273-
parameters = [p for p in self.parameterDefinitions()
276+
cellsize = 0.0
277+
layerParams = [p for p in self.parameterDefinitions()
274278
if isinstance(p, (QgsProcessingParameterRasterLayer,
275279
QgsProcessingParameterMultipleLayers))]
276280
cz = lambda l, cellsize: max(cellsize, (l.extent().xMaximum() - l.extent().xMinimum()) / l.width())
277281

278-
for param in parameters:
282+
for param in layerParams:
279283
paramName = param.name()
280284
if isinstance(param, QgsProcessingParameterRasterLayer):
281-
layer = self.parameterAsExtent(parameters, paramName, context)
282-
cellsize = max(cellsize, (layer.extent().xMaximum() -
283-
layer.extent().xMinimum()) /
284-
layer.width())
285-
#cellsize = cz(layer, cellsize)
285+
layer = self.parameterAsLayer(parameters, paramName, context)
286+
cellsize = cz(layer, cellsize)
286287
elif isinstance(param, QgsProcessingParameterMultipleLayers):
287288
layers = self.parameterAsLayerList(parameters, paramName, context)
288289
for layer in layers:
289290
if layer.type() == QgsMapLayer.RasterLayer:
290-
#cellsize = cz(layer, cellsize)
291-
cellsize = max(cellsize, (
292-
layer.extent().xMaximum() -
293-
layer.extent().xMinimum()) /
294-
layer.width())
295-
296-
QgsMessageLog.logMessage('cellSize: {}'.format(cellsize), 'Grass7', QgsMessageLog.INFO)
297-
if cellsize == 0:
298-
return False
299-
else:
300-
self.cellSize = cellsize
301-
return True
291+
cellsize = cz(layer, cellsize)
292+
293+
if cellsize == 0.0:
294+
cellsize = 100.0
295+
296+
return cellsize
302297

303298
def grabDefaultGrassParameters(self, parameters, context):
304299
"""
@@ -309,11 +304,11 @@ def grabDefaultGrassParameters(self, parameters, context):
309304
self.region = self.parameterAsExtent(parameters,
310305
self.GRASS_REGION_EXTENT_PARAMETER,
311306
context)
312-
QgsMessageLog.logMessage('processAlgorithm self.region: {}'.format(self.region.isEmpty()), 'Grass7', QgsMessageLog.INFO)
313307
# GRASS cell size
314-
self.cellSize = self.parameterAsString(parameters,
315-
self.GRASS_REGION_CELLSIZE_PARAMETER,
316-
context)
308+
if self.parameterDefinition(self.GRASS_REGION_CELLSIZE_PARAMETER):
309+
self.cellSize = self.parameterAsDouble(parameters,
310+
self.GRASS_REGION_CELLSIZE_PARAMETER,
311+
context)
317312
# GRASS snap tolerance
318313
self.snapTolerance = self.parameterAsDouble(parameters,
319314
self.GRASS_SNAP_TOLERANCE_PARAMETER,
@@ -332,7 +327,7 @@ def grabDefaultGrassParameters(self, parameters, context):
332327
context)
333328

334329
def processAlgorithm(self, parameters, context, feedback):
335-
if system.isWindows():
330+
if isWindows():
336331
path = Grass7Utils.grassPath()
337332
if path == '':
338333
raise QgsProcessingException(
@@ -407,6 +402,7 @@ def processAlgorithm(self, parameters, context, feedback):
407402
Grass7Utils.endGrass7Session()
408403

409404
# Return outputs map
405+
QgsMessageLog.logMessage('outputDefinitions: {}'.format(self.outputDefinitions()), 'Grass7', QgsMessageLog.INFO)
410406
outputs = {}
411407
for outName in [o.name() for o in self.outputDefinitions()]:
412408
if outName in parameters:
@@ -484,8 +480,12 @@ def processInputs(self, parameters, context):
484480
self.region.xMaximum(), self.region.xMinimum()
485481
)
486482
# Handle cell size
487-
if self.getDefaultCellSize(parameters, context):
488-
command += ' res={}'.format(self.cellSize)
483+
if self.parameterDefinition(self.GRASS_REGION_CELLSIZE_PARAMETER):
484+
if self.cellSize:
485+
cellSize = self.cellSize
486+
else:
487+
cellSize = self.getDefaultCellSize(parameters, context)
488+
command += ' res={}'.format(cellSize)
489489

490490
# Handle align to resolution
491491
if self.alignToResolution:
@@ -496,7 +496,8 @@ def processInputs(self, parameters, context):
496496
QgsMessageLog.logMessage('processInputs end. Commands: {}'.format(self.commands), 'Grass7', QgsMessageLog.INFO)
497497

498498
def processCommand(self, parameters, context):
499-
"""Prepare the GRASS algorithm command
499+
"""
500+
Prepare the GRASS algorithm command
500501
:param parameters:
501502
"""
502503
noOutputs = [o for o in self.parameterDefinitions() if o not in self.destinationParameterDefinitions()]
@@ -646,6 +647,19 @@ def processOutputs(self, parameters, context):
646647
self.outputCommands.append(command)
647648
QgsMessageLog.logMessage('processOutputs. Commands: {}'.format(self.commands), 'Grass7', QgsMessageLog.INFO)
648649

650+
def exportRasterLayer(self, layerKey, layerSrc):
651+
"""
652+
Creates a dedicated command to load a raster into
653+
temporary GRASS DB.
654+
"""
655+
# TODO: handle multiple bands
656+
#destFileName = QgsProcessingUtils.generateTempFilename(layerKey)
657+
destFilename = 'a' + os.path.basename(getTempFilename())
658+
self.exportedLayers[layerKey] = destFilename
659+
command = 'r.external input="{}" band=1 output={} --overwrite -o'.format(
660+
layerSrc, destFilename)
661+
return command
662+
649663
def exportVectorLayer(self, layerKey, layerSrc):
650664
# TODO: learn about ProcessingContexts
651665
#context = dataobjects.createContext()
@@ -671,7 +685,8 @@ def exportVectorLayer(self, layerKey, layerSrc):
671685
# filename = orgFilename
672686
# TODO handle selection with a where_clause?
673687
# TODO use v.external as an option!
674-
destFileName = 'a' + os.path.basename(self.getTempFilename())
688+
#destFileName = QgsProcessingUtils.generateTempFilename(layerKey)
689+
destFileName = 'a' + os.path.basename(getTempFilename())
675690
self.exportedLayers[layerKey] = destFileName
676691
layerFileName= os.path.basename(layerSrc)
677692
layerName = os.path.splitext(layerFileName)[0]
@@ -698,29 +713,13 @@ def setSessionProjectionFromLayer(self, layer):
698713
Set the projection from a QgsVectorLayer.
699714
We creates a PROJ4 definition which is transmitted to Grass
700715
"""
701-
context = dataobjects.createContext()
716+
#context = dataobjects.createContext()
702717
if not Grass7Utils.projectionSet:
703718
proj4 = str(layer.crs().toProj4())
704719
command = 'g.proj -c proj4="{}"'.format(proj4)
705720
self.commands.append(command)
706721
Grass7Utils.projectionSet = True
707722

708-
def exportRasterLayer(self, layerKey, layerSrc):
709-
"""
710-
Creates a dedicated command to load a raster into
711-
temporary GRASS DB.
712-
"""
713-
# TODO: handle multiple bands
714-
destFilename = 'a' + os.path.basename(self.getTempFilename())
715-
self.exportedLayers[layerKey] = destFilename
716-
command = 'r.external input="{}" band=1 output={} --overwrite -o'.format(
717-
layerSrc, destFilename)
718-
return command
719-
720-
def getTempFilename(self):
721-
# TODO Replace with QgsProcessingUtils generateTempFilename
722-
return system.getTempFilename()
723-
724723
def canExecute(self):
725724
message = Grass7Utils.checkGrass7IsInstalled()
726725
return not message, message

python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py

+6
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ def icon(self):
125125
def svgIconPath(self):
126126
return QgsApplication.iconPath("providerGrass.svg")
127127

128+
def supportsNonFileBasedOutput(self):
129+
"""
130+
GRASS7 Provider doesn't support non file based outputs
131+
"""
132+
return False
133+
128134
def supportedOutputVectorLayerExtensions(self):
129135
# We use the same extensions than QGIS because:
130136
# - QGIS is using OGR like GRASS

0 commit comments

Comments
 (0)