[processing] Use text file for input file list to gdal tile index alg

Avoids too long command being generated with many inputs

Fixes #21296
This commit is contained in:
Nyall Dawson 2019-02-18 15:40:14 +10:00
parent 1b228bb67f
commit 342c093d91
2 changed files with 42 additions and 47 deletions

View File

@ -131,13 +131,6 @@ class gdaltindex(GdalAlgorithm):
self.setOutputValue(self.OUTPUT, outFile)
output, outFormat = GdalUtils.ogrConnectionStringAndFormat(outFile, context)
layers = []
for layer in input_layers:
if layer.type() != QgsMapLayer.RasterLayer:
raise QgsProcessingException(
self.tr('All layers must be raster layers!'))
layers.append(layer.source())
arguments = []
arguments.append('-tileindex')
arguments.append(self.parameterAsString(parameters, self.PATH_FIELD_NAME, context))
@ -162,6 +155,11 @@ class gdaltindex(GdalAlgorithm):
arguments.append('-f {}'.format(outFormat))
arguments.append(output)
arguments.append(' '.join(layers))
# 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='tile_index_files.txt', alg=self, parameters=parameters, parameter_name=self.LAYERS, context=context, quote=True, executing=executing)
arguments.append('--optfile')
arguments.append(list_file)
return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]

View File

@ -1225,55 +1225,52 @@ class TestGdalAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
alg.initAlgorithm()
with tempfile.TemporaryDirectory() as outdir:
self.assertEqual(
alg.getConsoleCommands({'LAYERS': [source],
'OUTPUT': outdir + '/test.shp'}, context, feedback),
['gdaltindex',
'-tileindex location -f "ESRI Shapefile" ' +
outdir + '/test.shp ' +
source])
commands = alg.getConsoleCommands({'LAYERS': [source],
'OUTPUT': outdir + '/test.shp'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdaltindex')
self.assertIn('-tileindex location -f "ESRI Shapefile" ' + outdir + '/test.shp', commands[1])
self.assertIn('--optfile ', commands[1])
# with input srs
self.assertEqual(
alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': 'EPSG:3111',
'OUTPUT': outdir + '/test.shp'}, context, feedback),
['gdaltindex',
'-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' +
outdir + '/test.shp ' +
source])
commands = alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': 'EPSG:3111',
'OUTPUT': outdir + '/test.shp'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdaltindex')
self.assertIn('-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' + outdir + '/test.shp', commands[1])
self.assertIn('--optfile ', commands[1])
# with target using proj string
custom_crs = 'proj4: +proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs'
self.assertEqual(
alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': custom_crs,
'OUTPUT': outdir + '/test.shp'}, context, feedback),
['gdaltindex',
'-tileindex location -t_srs EPSG:20936 -f "ESRI Shapefile" ' +
outdir + '/test.shp ' +
source])
commands = alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': custom_crs,
'OUTPUT': outdir + '/test.shp'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdaltindex')
self.assertIn('-tileindex location -t_srs EPSG:20936 -f "ESRI Shapefile" ' + outdir + '/test.shp', commands[1])
self.assertIn('--optfile ', commands[1])
# with target using custom projection
custom_crs = 'proj4: +proj=utm +zone=36 +south +a=63785 +b=6357 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs'
self.assertEqual(
alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': custom_crs,
'OUTPUT': outdir + '/test.shp'}, context, feedback),
['gdaltindex',
'-tileindex location -t_srs "+proj=utm +zone=36 +south +a=63785 +b=6357 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs" -f "ESRI Shapefile" ' +
outdir + '/test.shp ' +
source])
commands = alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': custom_crs,
'OUTPUT': outdir + '/test.shp'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdaltindex')
self.assertIn('-tileindex location -t_srs "+proj=utm +zone=36 +south +a=63785 +b=6357 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs" -f "ESRI Shapefile" ' + outdir + '/test.shp', commands[1])
self.assertIn('--optfile ', commands[1])
# with non-EPSG crs code
self.assertEqual(
alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': 'POSTGIS:3111',
'OUTPUT': outdir + '/test.shp'}, context, feedback),
['gdaltindex',
'-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' +
outdir + '/test.shp ' +
source])
commands = alg.getConsoleCommands({'LAYERS': [source],
'TARGET_CRS': 'POSTGIS:3111',
'OUTPUT': outdir + '/test.shp'}, context, feedback)
self.assertEqual(len(commands), 2)
self.assertEqual(commands[0], 'gdaltindex')
self.assertIn(
'-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' + outdir + '/test.shp',
commands[1])
self.assertIn('--optfile ', commands[1])
def testGridAverage(self):
context = QgsProcessingContext()