Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] add missed "srcnodata" parameter to the buildvrt algorithm
(fix #20586).

Without this parameter it is not possible to remove collars surrounding
input raster which may overlap with other input rasters. As this is very
frequent case algorithm is useless without such parameter. To keep API
compatibility new parameter is optional and not used by default.
  • Loading branch information
alexbruy committed Jan 22, 2019
1 parent ee34431 commit dc2b29c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 7 deletions.
27 changes: 20 additions & 7 deletions python/plugins/processing/algs/gdal/buildvrt.py
Expand Up @@ -39,6 +39,7 @@
QgsProcessingParameterBoolean,
QgsProcessingParameterRasterDestination,
QgsProcessingParameterCrs,
QgsProcessingParameterString,
QgsProcessingOutputLayerDefinition,
QgsProcessingUtils)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
Expand All @@ -57,6 +58,7 @@ class buildvrt(GdalAlgorithm):
ADD_ALPHA = 'ADD_ALPHA'
ASSIGN_CRS = 'ASSIGN_CRS'
RESAMPLING = 'RESAMPLING'
SRC_NODATA = 'SRC_NODATA'

RESOLUTION_OPTIONS = ['average', 'highest', 'lowest']
RESAMPLING_OPTIONS = ['nearest', 'bilinear', 'cubic', 'cubicspline', 'lanczos', 'average', 'mode']
Expand All @@ -82,38 +84,45 @@ def defaultFileExtension(self):
return 'vrt'

self.addParameter(QgsProcessingParameterMultipleLayers(self.INPUT,
QCoreApplication.translate("ParameterVrtDestination", 'Input layers'),
self.tr('Input layers'),
QgsProcessing.TypeRaster))
self.addParameter(QgsProcessingParameterEnum(self.RESOLUTION,
QCoreApplication.translate("ParameterVrtDestination", 'Resolution'),
self.tr('Resolution'),
options=self.RESOLUTION_OPTIONS,
defaultValue=0))
self.addParameter(QgsProcessingParameterBoolean(self.SEPARATE,
QCoreApplication.translate("ParameterVrtDestination", 'Place each input file into a separate band'),
self.tr('Place each input file into a separate band'),
defaultValue=True))
self.addParameter(QgsProcessingParameterBoolean(self.PROJ_DIFFERENCE,
QCoreApplication.translate("ParameterVrtDestination", 'Allow projection difference'),
self.tr('Allow projection difference'),
defaultValue=False))

add_alpha_param = QgsProcessingParameterBoolean(self.ADD_ALPHA,
QCoreApplication.translate("ParameterVrtDestination", 'Add alpha mask band to VRT when source raster has none'),
self.tr('Add alpha mask band to VRT when source raster has none'),
defaultValue=False)
add_alpha_param.setFlags(add_alpha_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(add_alpha_param)

assign_crs = QgsProcessingParameterCrs(self.ASSIGN_CRS,
QCoreApplication.translate("ParameterVrtDestination", 'Override projection for the output file'),
self.tr('Override projection for the output file'),
defaultValue=None, optional=True)
assign_crs.setFlags(assign_crs.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(assign_crs)

resampling = QgsProcessingParameterEnum(self.RESAMPLING,
QCoreApplication.translate("ParameterVrtDestination", 'Resampling algorithm'),
self.tr('Resampling algorithm'),
options=self.RESAMPLING_OPTIONS,
defaultValue=0)
resampling.setFlags(resampling.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(resampling)

src_nodata_param = QgsProcessingParameterString(self.SRC_NODATA,
self.tr('Nodata value(s) for input bands'),
defaultValue=None,
optional=True)
src_nodata_param.setFlags(src_nodata_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(src_nodata_param)

self.addParameter(ParameterVrtDestination(self.OUTPUT, QCoreApplication.translate("ParameterVrtDestination", 'Virtual')))

def name(self):
Expand Down Expand Up @@ -151,6 +160,10 @@ def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments.append('-r')
arguments.append(self.RESAMPLING_OPTIONS[self.parameterAsEnum(parameters, self.RESAMPLING, context)])

if self.SRC_NODATA in parameters and parameters[self.SRC_NODATA] not in (None, ''):
nodata = self.parameterAsString(parameters, self.SRC_NODATA, context)
arguments.append('-srcnodata "{}"'.format(nodata))

# Always write input files to a text file in case there are many of them and the
# length of the command will be longer then allowed in command prompt
list_file = GdalUtils.writeLayerParameterToTextFile(filename='buildvrtInputFiles.txt', alg=self, parameters=parameters, parameter_name=self.INPUT, context=context, executing=executing, quote=False)
Expand Down
45 changes: 45 additions & 0 deletions python/plugins/processing/tests/GdalAlgorithmsTest.py
Expand Up @@ -1104,6 +1104,51 @@ def testBuildVrt(self):
self.assertIn('-input_file_list', commands[1])
self.assertIn(outdir + '/test.vrt', commands[1])

commands = alg.getConsoleCommands({'LAYERS': [source],
'SRC_NODATA': '-9999',
'OUTPUT': outdir + '/test.vrt'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdalbuildvrt')
self.assertIn('-resolution average', commands[1])
self.assertIn('-separate', commands[1])
self.assertNotIn('-allow_projection_difference', commands[1])
self.assertNotIn('-add_alpha', commands[1])
self.assertNotIn('-a_srs', commands[1])
self.assertIn('-r nearest', commands[1])
self.assertIn('-srcnodata "-9999"', commands[1])
self.assertIn('-input_file_list', commands[1])
self.assertIn(outdir + '/test.vrt', commands[1])

commands = alg.getConsoleCommands({'LAYERS': [source],
'SRC_NODATA': '-9999 9999',
'OUTPUT': outdir + '/test.vrt'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdalbuildvrt')
self.assertIn('-resolution average', commands[1])
self.assertIn('-separate', commands[1])
self.assertNotIn('-allow_projection_difference', commands[1])
self.assertNotIn('-add_alpha', commands[1])
self.assertNotIn('-a_srs', commands[1])
self.assertIn('-r nearest', commands[1])
self.assertIn('-srcnodata "-9999 9999"', commands[1])
self.assertIn('-input_file_list', commands[1])
self.assertIn(outdir + '/test.vrt', commands[1])

commands = alg.getConsoleCommands({'LAYERS': [source],
'SRC_NODATA': '',
'OUTPUT': outdir + '/test.vrt'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdalbuildvrt')
self.assertIn('-resolution average', commands[1])
self.assertIn('-separate', commands[1])
self.assertNotIn('-allow_projection_difference', commands[1])
self.assertNotIn('-add_alpha', commands[1])
self.assertNotIn('-a_srs', commands[1])
self.assertIn('-r nearest', commands[1])
self.assertNotIn('-srcnodata', commands[1])
self.assertIn('-input_file_list', commands[1])
self.assertIn(outdir + '/test.vrt', commands[1])

def testGdalInfo(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
Expand Down

0 comments on commit dc2b29c

Please sign in to comment.