Skip to content
Permalink
Browse files

Introduce GRASS_USE_REXTERNAL setting

GRASS GIS, in addition to importing data in its native formats via
`r.in.gdal`/`v.in.ogr` (and likewise `r.import`/v.import`),
also supports `r.external`/`v.external` which only link the data into
the GRASS DB.

Nevertheless, both `r.external` and `v.external` occasionally have problems,
especially on windows. E.g.:

- https://trac.osgeo.org/grass/ticket/3927

GRASS 7 Processing Plugin already has a setting that controls whether
`v.external` is used (disabled by default).

With this commit the complementary setting for `r.external` gets added too.
Usage of `r.external` is disabled by default. This is changing the existing
behavior, which was to use r`r.external`. The downsides of this change
should be the somewhat lower import speed + higher disk usage. Nevertheless
this way we have the same default value as `v.external` + we circumvent the
`r.import/v.import` shortcomings.
  • Loading branch information
pmav99 authored and nyalldawson committed Oct 25, 2019
1 parent a83154c commit 0c3cb558a89b751082de6a08e07c8c34966d4b7c
@@ -700,29 +700,31 @@ def processOutputs(self, parameters, context, feedback):
elif isinstance(out, QgsProcessingParameterFolderDestination):
self.exportRasterLayersIntoDirectory(outName, parameters, context)

def loadRasterLayerFromParameter(self, name, parameters, context, external=True, band=1):
def loadRasterLayerFromParameter(self, name, parameters, context, external=None, band=1):
"""
Creates a dedicated command to load a raster into
the temporary GRASS DB.
:param name: name of the parameter.
:param parameters: algorithm parameters dict.
:param context: algorithm context.
:param external: True if using r.external.
:param external: use r.external if True, r.in.gdal otherwise.
:param band: imports only specified band. None for all bands.
"""
layer = self.parameterAsRasterLayer(parameters, name, context)
self.loadRasterLayer(name, layer, external, band)

def loadRasterLayer(self, name, layer, external=True, band=1, destName=None):
def loadRasterLayer(self, name, layer, external=None, band=1, destName=None):
"""
Creates a dedicated command to load a raster into
the temporary GRASS DB.
:param name: name of the parameter.
:param layer: QgsMapLayer for the raster layer.
:param external: True if using r.external.
:param external: use r.external if True, r.in.gdal if False.
:param band: imports only specified band. None for all bands.
:param destName: force the destination name of the raster.
"""
if external is None:
external = ProcessingConfig.getSetting(Grass7Utils.GRASS_USE_REXTERNAL)
self.inputLayers.append(layer)
self.setSessionProjectionFromLayer(layer)
if not destName:
@@ -70,9 +70,16 @@ def load(self):
Grass7Utils.GRASS_HELP_PATH,
self.tr('Location of GRASS docs'),
Grass7Utils.grassHelpPath()))
# Add a setting for using v.external instead of v.in.ogr
# But set it to False by default because some algorithms
# can't be used with external data (need a solid v.in.ogr).
# Add settings for using r.external/v.external instead of r.in.gdal/v.in.ogr
# but set them to False by default because the {r,v}.external implementations
# have some bugs on windows + there are algorithms that can't be used with
# external data (need a solid r.in.gdal/v.in.ogr).
# For more info have a look at e.g. https://trac.osgeo.org/grass/ticket/3927
ProcessingConfig.addSetting(Setting(
self.name(),
Grass7Utils.GRASS_USE_REXTERNAL,
self.tr('For raster layers, use r.external (faster) instead of r.in.gdal'),
False))
ProcessingConfig.addSetting(Setting(
self.name(),
Grass7Utils.GRASS_USE_VEXTERNAL,
@@ -90,6 +97,7 @@ def unload(self):
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_REXTERNAL)
ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_VEXTERNAL)

def isActive(self):
@@ -50,6 +50,7 @@ class Grass7Utils:
GRASS_LOG_COMMANDS = 'GRASS7_LOG_COMMANDS'
GRASS_LOG_CONSOLE = 'GRASS7_LOG_CONSOLE'
GRASS_HELP_PATH = 'GRASS_HELP_PATH'
GRASS_USE_REXTERNAL = 'GRASS_USE_REXTERNAL'
GRASS_USE_VEXTERNAL = 'GRASS_USE_VEXTERNAL'

# TODO Review all default options formats
@@ -401,6 +402,9 @@ def executeGrass(commands, feedback, outputCommands=None):
elif 'Segmentation fault' in line:
feedback.reportError(line.strip())
feedback.reportError('\n' + Grass7Utils.tr('GRASS command crashed :( Try a different set of input parameters and consult the GRASS algorithm manual for more information.') + '\n')
if ProcessingConfig.getSetting(Grass7Utils.GRASS_USE_REXTERNAL):
feedback.reportError(Grass7Utils.tr(
'Suggest disabling the experimental "use r.external" option from the Processing GRASS Provider options.') + '\n')
if ProcessingConfig.getSetting(Grass7Utils.GRASS_USE_VEXTERNAL):
feedback.reportError(Grass7Utils.tr(
'Suggest disabling the experimental "use v.external" option from the Processing GRASS Provider options.') + '\n')

0 comments on commit 0c3cb55

Please sign in to comment.
You can’t perform that action at this time.