mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Improve ext scripts and support OutputFolder
This commit is contained in:
parent
5827513c4b
commit
56b963e313
@ -72,6 +72,12 @@ class Grass7AlgorithmProvider(QgsProcessingProvider):
|
|||||||
Grass7Utils.GRASS_HELP_PATH,
|
Grass7Utils.GRASS_HELP_PATH,
|
||||||
self.tr('Location of GRASS docs'),
|
self.tr('Location of GRASS docs'),
|
||||||
Grass7Utils.grassHelpPath()))
|
Grass7Utils.grassHelpPath()))
|
||||||
|
# Add a setting for using v.external instead of v.in.ogr
|
||||||
|
ProcessingConfig.addSetting(Setting(
|
||||||
|
self.name(),
|
||||||
|
Grass7Utils.GRASS_USE_VEXTERNAL,
|
||||||
|
self.tr('For vector layers, use v.external (faster) instead of v.in.ogr'),
|
||||||
|
True))
|
||||||
ProcessingConfig.readSettings()
|
ProcessingConfig.readSettings()
|
||||||
self.refreshAlgorithms()
|
self.refreshAlgorithms()
|
||||||
return True
|
return True
|
||||||
@ -83,6 +89,7 @@ class Grass7AlgorithmProvider(QgsProcessingProvider):
|
|||||||
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS)
|
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS)
|
||||||
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE)
|
ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE)
|
||||||
ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH)
|
ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH)
|
||||||
|
ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_VEXTERNAL)
|
||||||
|
|
||||||
def isActive(self):
|
def isActive(self):
|
||||||
return ProcessingConfig.getSetting('ACTIVATE_GRASS7')
|
return ProcessingConfig.getSetting('ACTIVATE_GRASS7')
|
||||||
|
@ -10,13 +10,19 @@ QGIS3 Processing Port
|
|||||||
* Replace all parameters by QgsProcessingParameters.
|
* Replace all parameters by QgsProcessingParameters.
|
||||||
* Re-enable GRASS algorithm by default.
|
* Re-enable GRASS algorithm by default.
|
||||||
* Add GRASS 7.2 new algorithms.
|
* Add GRASS 7.2 new algorithms.
|
||||||
* Improve unit tests
|
* Improve unit tests.
|
||||||
* GRASS_REGION_CELLSIZE_PARAMETER is integer or double?
|
* Use some raster/vector layers with spacename into their path.
|
||||||
* GRASS_SNAP_TOLERANCE_PARAMETER is integer or double?
|
* Better support for files output that are not HTML.
|
||||||
* Do we need to use QgsProcessingParameters::parameterFromScriptCode for description files?
|
* Use prepareAlgorithm for algorithm preparation.
|
||||||
We don't NEED but we have to improve getParameterFromString (or use an internal method) at least.
|
* Opens HTML files in Viewer.
|
||||||
There is also a problem for parameterFromScriptCode: it doesn't use description very well.
|
* Support ParameterTable.
|
||||||
We can also use parameterFromVariantMap and a custom internal Grass7Algorithm getParameterFromString.
|
* Remove specific algorithms code in Grass7Algorithm.py (move them in ext).
|
||||||
|
* Convert all ext scripts.
|
||||||
|
* Support OutputFolder.
|
||||||
|
* Support multiple output raster formats.
|
||||||
|
* Support multiple output vector formats.
|
||||||
|
* Support multiple bands input rasters.
|
||||||
|
* Review all the methods of QgsProcessingAlgorithm.
|
||||||
* Make tests under MS-Windows 7 for Utf-8 support.
|
* Make tests under MS-Windows 7 for Utf-8 support.
|
||||||
|
|
||||||
Unit tests
|
Unit tests
|
||||||
|
@ -2,8 +2,11 @@ r.horizon
|
|||||||
Horizon angle computation from a digital elevation model.
|
Horizon angle computation from a digital elevation model.
|
||||||
Raster (r.*)
|
Raster (r.*)
|
||||||
QgsProcessingParameterRasterLayer|elevation|Name of input elevation raster map|None|False
|
QgsProcessingParameterRasterLayer|elevation|Name of input elevation raster map|None|False
|
||||||
QgsProcessingParameterNumber|direction|Direction in which you want to know the horizon height|QgsProcessingParameterNumber.Double|0.0|False|360|0
|
QgsProcessingParameterNumber|direction|Direction in which you want to know the horizon height|QgsProcessingParameterNumber.Double|0.0|True|0.0|360.0
|
||||||
QgsProcessingParameterNumber|maxdistance|The maximum distance to consider when finding the horizon height|QgsProcessingParameterNumber.Double|10000|False|None|0
|
QgsProcessingParameterNumber|step|Angle step size for multidirectional horizon|QgsProcessingParameterNumber.Double|None|True|0.0|360.0
|
||||||
QgsProcessingParameterString|distance|Sampling distance step coefficient (0.5-1.5)|1.0
|
QgsProcessingParameterNumber|start|Start angle for multidirectional horizon|QgsProcessingParameterNumber.Double|0.0|True|0.0|360.0
|
||||||
|
QgsProcessingParameterNumber|end|End angle for multidirectional horizon|QgsProcessingParameterNumber.Double|360.0|True|0.0|360.0
|
||||||
|
QgsProcessingParameterNumber|maxdistance|The maximum distance to consider when finding the horizon height|QgsProcessingParameterNumber.Double|None|True|0|None
|
||||||
|
QgsProcessingParameterNumber|distance|Sampling distance step coefficient|QgsProcessingParameterNumber.Double|1.0|True|0.5|1.5
|
||||||
QgsProcessingParameterBoolean|-d|Write output in degrees (default is radians)|False
|
QgsProcessingParameterBoolean|-d|Write output in degrees (default is radians)|False
|
||||||
QgsProcessingParameterRasterDestination|output|Horizon
|
QgsProcessingParameterFolderDestination|output|Folder to get horizon rasters
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
"""
|
"""
|
||||||
from builtins import str
|
|
||||||
|
|
||||||
__author__ = 'Médéric Ribreux'
|
__author__ = 'Médéric Ribreux'
|
||||||
__date__ = 'February 2016'
|
__date__ = 'February 2016'
|
||||||
@ -27,49 +26,26 @@ __copyright__ = '(C) 2016, Médéric Ribreux'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
|
|
||||||
def processInputs(alg):
|
def processInputs(alg, parameters, context):
|
||||||
# If there is another raster to copy categories from
|
if 'first' and 'second' in alg.exportedLayers:
|
||||||
# we need to import it with r.in.gdal rather than r.external
|
|
||||||
first = alg.getParameterValue(u'first')
|
|
||||||
second = alg.getParameterValue(u'second')
|
|
||||||
if first in list(alg.exportedLayers.keys()) and second in list(alg.exportedLayers.keys()):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
for raster in [first, second]:
|
for name in ['first', 'second']:
|
||||||
alg.setSessionProjectionFromLayer(raster, alg.commands)
|
raster = alg.parameterAsRasterLayer(parameters, name, context)
|
||||||
|
alg.setSessionProjectionFromLayer(raster)
|
||||||
|
|
||||||
destFilename = alg.getTempFilename()
|
# We need to import all the bands and color tables of the input raster
|
||||||
alg.exportedLayers[raster] = destFilename
|
alg.commands.append(
|
||||||
command = 'r.in.gdal input={} output={} --overwrite -o'.format(raster, destFilename)
|
alg.loadRasterLayer(name,
|
||||||
alg.commands.append(command)
|
parameters[name],
|
||||||
|
False, None
|
||||||
alg.setSessionProjectionFromProject(alg.commands)
|
|
||||||
|
|
||||||
region = str(alg.getParameterValue(alg.GRASS_REGION_EXTENT_PARAMETER))
|
|
||||||
regionCoords = region.split(',')
|
|
||||||
command = 'g.region'
|
|
||||||
command += ' -a'
|
|
||||||
command += ' n=' + str(regionCoords[3])
|
|
||||||
command += ' s=' + str(regionCoords[2])
|
|
||||||
command += ' e=' + str(regionCoords[1])
|
|
||||||
command += ' w=' + str(regionCoords[0])
|
|
||||||
cellsize = alg.getParameterValue(alg.GRASS_REGION_CELLSIZE_PARAMETER)
|
|
||||||
if cellsize:
|
|
||||||
command += ' res=' + str(cellsize)
|
|
||||||
else:
|
|
||||||
command += ' res=' + str(alg.getDefaultCellsize(parameters, context))
|
|
||||||
alignToResolution = alg.getParameterValue(alg.GRASS_REGION_ALIGN_TO_RESOLUTION)
|
|
||||||
if alignToResolution:
|
|
||||||
command += ' -a'
|
|
||||||
alg.commands.append(command)
|
|
||||||
|
|
||||||
|
|
||||||
def processOutputs(alg):
|
|
||||||
# Keep color table
|
|
||||||
output = alg.getOutputValue(u'output')
|
|
||||||
command = u"r.out.gdal -t createopt=\"TFW=YES,COMPRESS=LZW\" input={} output=\"{}\" --overwrite".format(
|
|
||||||
alg.exportedLayers[output],
|
|
||||||
output
|
|
||||||
)
|
)
|
||||||
alg.commands.append(command)
|
)
|
||||||
alg.outputCommands.append(command)
|
alg.inputLayers.append(raster)
|
||||||
|
|
||||||
|
alg.postInputs(parameters, context)
|
||||||
|
|
||||||
|
def processOutputs(alg, parameters, context):
|
||||||
|
# Keep color table
|
||||||
|
self.exportRasterLayer('output', parameters, context, True)
|
||||||
|
|
||||||
|
40
python/plugins/processing/algs/grass7/ext/r_horizon.py
Normal file
40
python/plugins/processing/algs/grass7/ext/r_horizon.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
***************************************************************************
|
||||||
|
r_horizon.py
|
||||||
|
------------
|
||||||
|
Date : September 2017
|
||||||
|
Copyright : (C) 2017 by Médéric Ribreux
|
||||||
|
Email : medspx at medspx dot fr
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = 'Médéric Ribreux'
|
||||||
|
__date__ = 'September 2017'
|
||||||
|
__copyright__ = '(C) 2017, Médéric Ribreux'
|
||||||
|
|
||||||
|
# This will get replaced with a git SHA1 when you do a git archive
|
||||||
|
|
||||||
|
__revision__ = '$Format:%H$'
|
||||||
|
import os
|
||||||
|
|
||||||
|
def processOutputs(alg, parameters, context):
|
||||||
|
# There will be as outputs as the difference between start and end divided by steps
|
||||||
|
start = alg.parameterAsDouble(parameters, 'start', context)
|
||||||
|
end = alg.parameterAsDouble(parameters, 'end', context)
|
||||||
|
step = alg.parameterAsDouble(parameters, 'step', context)
|
||||||
|
num = start + step
|
||||||
|
directory = alg.parameterAsString(parameters, 'output', context)
|
||||||
|
while num < end:
|
||||||
|
grassName = '{}_{}'.format(alg.exportedLayers['output'], int(num))
|
||||||
|
fileName = '{}.tif'.format(os.path.join(directory, '{0:0>3}'.format(int(num))))
|
||||||
|
alg.exportRasterLayer(grassName, fileName)
|
||||||
|
num += step
|
@ -27,44 +27,39 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
|
|
||||||
def processInputs(alg, parameters, context):
|
def processInputs(alg, parameters, context):
|
||||||
# We need to import all the bands and color tables of the input raster
|
|
||||||
if 'input' in alg.exportedLayers:
|
if 'input' in alg.exportedLayers:
|
||||||
return
|
return
|
||||||
raster = alg.parameterAsRasterLayer(parameters, 'input', context)
|
|
||||||
alg.setSessionProjectionFromLayer(raster)
|
# We need to import all the bands and color tables of the input raster
|
||||||
alg.prepareInputs()
|
alg.loadRasterLayerFromParameter('input', parameters, context, False, None)
|
||||||
|
alg.postInputs(parameters, context)
|
||||||
|
|
||||||
def processCommand(alg, parameters, context):
|
def processCommand(alg, parameters, context):
|
||||||
# We need to introduce something clever:
|
|
||||||
# if the input raster is multiband: export each component directly
|
# if the input raster is multiband: export each component directly
|
||||||
raster = alg.exportedLayers[alg.getParameterValue('input')]
|
rasterInput = alg.exportedLayers['input']
|
||||||
|
raster = alg.parameterAsRasterLayer(parameters, 'input', context)
|
||||||
for color in ['red', 'green', 'blue']:
|
for color in ['red', 'green', 'blue']:
|
||||||
alg.exportedLayers[alg.getOutputValue(color)] = color + alg.uniqueSuffix
|
alg.exportedLayers[color] = color + alg.uniqueSuffix
|
||||||
|
|
||||||
commands = ["if [ $(g.list type=rast pattern='{}.*' | wc -l) -eq \"0\" ]; then".format(raster)]
|
# If the raster is not multiband, really do r.rgb
|
||||||
commands.append(" r.rgb input={} red={} green={} blue={} --overwrite".format(
|
if raster.bandCount() == 1:
|
||||||
raster,
|
alg.commands.append(" r.rgb input={} red={} green={} blue={} --overwrite".format(
|
||||||
alg.exportedLayers[alg.getOutputValue('red')],
|
rasterInput,
|
||||||
alg.exportedLayers[alg.getOutputValue('green')],
|
alg.exportedLayers['red'],
|
||||||
alg.exportedLayers[alg.getOutputValue('blue')]
|
alg.exportedLayers['green'],
|
||||||
|
alg.exportedLayers['blue']
|
||||||
))
|
))
|
||||||
commands.append("fi")
|
|
||||||
alg.commands.extend(commands)
|
|
||||||
|
|
||||||
|
|
||||||
def processOutputs(alg, parameters, context):
|
def processOutputs(alg, parameters, context):
|
||||||
raster = alg.exportedLayers[alg.getParameterValue('input')]
|
raster = alg.parameterAsRasterLayer(parameters, 'input', context)
|
||||||
commands = ["if [ $(g.list type=rast pattern='{}.*' | wc -l) -eq \"0\" ]; then".format(raster)]
|
|
||||||
|
# if the raster was monoband, export from r.rgb
|
||||||
|
if raster.bandCount() == 1:
|
||||||
for color in ['red', 'green', 'blue']:
|
for color in ['red', 'green', 'blue']:
|
||||||
commands.append(" r.out.gdal -t input={} output={} createopt=\"TFW=YES,COMPRESS=LZW\" --overwrite".format(
|
alg.exportRasterLayerFromOutput(color, parameters, context, True)
|
||||||
alg.exportedLayers[alg.getOutputValue(color)],
|
# otherwise, export directly from the multibands
|
||||||
alg.getOutputValue(color)
|
else:
|
||||||
))
|
|
||||||
commands.append("else")
|
|
||||||
for color in ['red', 'green', 'blue']:
|
for color in ['red', 'green', 'blue']:
|
||||||
commands.append(" r.out.gdal -t input={} output={} createopt=\"TFW=YES,COMPRESS=LZW\" --overwrite".format(
|
fileName = alg.parameterAsOutputLayer(parameters, color, context)
|
||||||
'{}.{}'.format(raster, color),
|
grassName = '{}{}'.format(alg.exportedLayers['input'], color)
|
||||||
alg.getOutputValue(color)
|
alg.exportRasterLayer(grassName, fileName, True)
|
||||||
))
|
|
||||||
commands.append("fi")
|
|
||||||
alg.commands.extend(commands)
|
|
||||||
|
@ -60,12 +60,14 @@ from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinat
|
|||||||
QgsProcessingParameterRasterDestination, # NOQA
|
QgsProcessingParameterRasterDestination, # NOQA
|
||||||
QgsProcessingParameterVectorDestination, # NOQA
|
QgsProcessingParameterVectorDestination, # NOQA
|
||||||
QgsProcessingParameterFileDestination,
|
QgsProcessingParameterFileDestination,
|
||||||
|
QgsProcessingParameterFolderDestination,
|
||||||
QgsProcessingParameterString, # NOQA
|
QgsProcessingParameterString, # NOQA
|
||||||
QgsProcessingParameterMultipleLayers,
|
QgsProcessingParameterMultipleLayers,
|
||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
QgsProcessingParameterNumber)
|
QgsProcessingParameterNumber)
|
||||||
# TODELETE
|
# TODELETE
|
||||||
from qgis.core import (QgsMessageLog)
|
from qgis.core import (QgsMessageLog)
|
||||||
|
|
||||||
from processing.tools.vector import resolveFieldIndex
|
from processing.tools.vector import resolveFieldIndex
|
||||||
from processing.tools import dataobjects
|
from processing.tools import dataobjects
|
||||||
from processing.core.outputs import OutputNumber, OutputRaster, OutputVector
|
from processing.core.outputs import OutputNumber, OutputRaster, OutputVector
|
||||||
|
Loading…
x
Reference in New Issue
Block a user