From bd65fc607b5bae7196dd9d7efbd4b7aa83db0065 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 1 Jun 2018 15:42:21 +1000 Subject: [PATCH] [processing][gdal] Don't double quote output paths Breaks for some drivers, e.g. KML Fixes #18264 --- .../plugins/processing/algs/gdal/GdalUtils.py | 4 +- .../plugins/processing/algs/gdal/ogr2ogr.py | 2 +- .../processing/gui/BatchAlgorithmDialog.py | 2 + .../processing/tests/GdalAlgorithmsTest.py | 49 +++++++++++++++---- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/python/plugins/processing/algs/gdal/GdalUtils.py b/python/plugins/processing/algs/gdal/GdalUtils.py index a4bda86566ef..0401faa37497 100644 --- a/python/plugins/processing/algs/gdal/GdalUtils.py +++ b/python/plugins/processing/algs/gdal/GdalUtils.py @@ -276,7 +276,7 @@ def ogrConnectionStringAndFormat(uri, context): if layer is None: path, ext = os.path.splitext(uri) format = QgsVectorFileWriter.driverForExtension(ext) - return '"' + uri + '"', '"' + format + '"' + return uri, '"' + format + '"' provider = layer.dataProvider().name() if provider == 'spatialite': @@ -348,7 +348,7 @@ def ogrConnectionStringAndFormat(uri, context): path, ext = os.path.splitext(ogrstr) format = QgsVectorFileWriter.driverForExtension(ext) - return '"' + ogrstr + '"', '"' + format + '"' + return ogrstr, '"' + format + '"' @staticmethod def ogrLayerName(uri): diff --git a/python/plugins/processing/algs/gdal/ogr2ogr.py b/python/plugins/processing/algs/gdal/ogr2ogr.py index 22e031083dd7..49ccb01231d0 100644 --- a/python/plugins/processing/algs/gdal/ogr2ogr.py +++ b/python/plugins/processing/algs/gdal/ogr2ogr.py @@ -82,7 +82,7 @@ def getConsoleCommands(self, parameters, context, feedback, executing=True): output, outputFormat = GdalUtils.ogrConnectionStringAndFormat(outFile, context) if outputFormat == 'SQLite' and os.path.isfile(output): - raise QgsProcessinException(self.tr('Output file "{}" already exists.'.format(output))) + raise QgsProcessingException(self.tr('Output file "{}" already exists.'.format(output))) arguments = [] if outputFormat: diff --git a/python/plugins/processing/gui/BatchAlgorithmDialog.py b/python/plugins/processing/gui/BatchAlgorithmDialog.py index 23d731fa5c7f..49dcb74cdb41 100644 --- a/python/plugins/processing/gui/BatchAlgorithmDialog.py +++ b/python/plugins/processing/gui/BatchAlgorithmDialog.py @@ -33,6 +33,7 @@ from qgis.core import (QgsProcessingParameterDefinition, QgsProcessingParameterRasterDestination, + QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingOutputLayerDefinition, QgsProcessingOutputHtml, @@ -99,6 +100,7 @@ def accept(self): text = widget.getValue() if out.checkValueIsAcceptable(text): if isinstance(out, (QgsProcessingParameterRasterDestination, + QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink)): # load rasters and sinks on completion parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, project) diff --git a/python/plugins/processing/tests/GdalAlgorithmsTest.py b/python/plugins/processing/tests/GdalAlgorithmsTest.py index d07c8033af20..ce4f204e259c 100644 --- a/python/plugins/processing/tests/GdalAlgorithmsTest.py +++ b/python/plugins/processing/tests/GdalAlgorithmsTest.py @@ -41,6 +41,7 @@ from processing.algs.gdal.GridInverseDistanceNearestNeighbor import GridInverseDistanceNearestNeighbor from processing.algs.gdal.GridLinear import GridLinear from processing.algs.gdal.GridNearestNeighbor import GridNearestNeighbor +from processing.algs.gdal.ogr2ogr import ogr2ogr from processing.algs.gdal.proximity import proximity from processing.algs.gdal.rasterize import rasterize from processing.algs.gdal.retile import retile @@ -233,10 +234,10 @@ def _copyFile(dst): def testOgrConnectionStringAndFormat(self): context = QgsProcessingContext() output, outputFormat = GdalUtils.ogrConnectionStringAndFormat('d:/test/test.shp', context) - self.assertEqual(output, '"d:/test/test.shp"') + self.assertEqual(output, 'd:/test/test.shp') self.assertEqual(outputFormat, '"ESRI Shapefile"') output, outputFormat = GdalUtils.ogrConnectionStringAndFormat('d:/test/test.mif', context) - self.assertEqual(output, '"d:/test/test.mif"') + self.assertEqual(output, 'd:/test/test.mif') self.assertEqual(outputFormat, '"MapInfo File"') def testCrsConversion(self): @@ -479,7 +480,7 @@ def testContour(self): ['gdal_contour', '-b 1 -a elev -i 5.0 -f "ESRI Shapefile" ' + source + ' ' + - '"d:/temp/check.shp"']) + 'd:/temp/check.shp']) # with NODATA value self.assertEqual( alg.getConsoleCommands({'INPUT': source, @@ -491,7 +492,7 @@ def testContour(self): ['gdal_contour', '-b 1 -a elev -i 5.0 -snodata 9999.0 -f "ESRI Shapefile" ' + source + ' ' + - '"d:/temp/check.shp"']) + 'd:/temp/check.shp']) # with "0" NODATA value self.assertEqual( alg.getConsoleCommands({'INPUT': source, @@ -503,7 +504,7 @@ def testContour(self): ['gdal_contour', '-b 1 -a elev -i 5.0 -snodata 0.0 -f "GPKG" ' + source + ' ' + - '"d:/temp/check.gpkg"']) + 'd:/temp/check.gpkg']) def testGdal2Tiles(self): context = QgsProcessingContext() @@ -648,7 +649,7 @@ def testGdalTindex(self): 'OUTPUT': 'd:/temp/test.shp'}, context, feedback), ['gdaltindex', '-tileindex location -f "ESRI Shapefile" ' + - '"d:/temp/test.shp" ' + + 'd:/temp/test.shp ' + source]) # with input srs @@ -658,7 +659,7 @@ def testGdalTindex(self): 'OUTPUT': 'd:/temp/test.shp'}, context, feedback), ['gdaltindex', '-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' + - '"d:/temp/test.shp" ' + + 'd:/temp/test.shp ' + source]) # with target using proj string @@ -669,7 +670,7 @@ def testGdalTindex(self): 'OUTPUT': 'd:/temp/test.shp'}, context, feedback), ['gdaltindex', '-tileindex location -t_srs EPSG:20936 -f "ESRI Shapefile" ' + - '"d:/temp/test.shp" ' + + 'd:/temp/test.shp ' + source]) # with target using custom projection @@ -680,7 +681,7 @@ def testGdalTindex(self): 'OUTPUT': 'd:/temp/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" ' + - '"d:/temp/test.shp" ' + + 'd:/temp/test.shp ' + source]) # with non-EPSG crs code @@ -690,7 +691,7 @@ def testGdalTindex(self): 'OUTPUT': 'd:/temp/test.shp'}, context, feedback), ['gdaltindex', '-tileindex location -t_srs EPSG:3111 -f "ESRI Shapefile" ' + - '"d:/temp/test.shp" ' + + 'd:/temp/test.shp ' + source]) def testGridAverage(self): @@ -897,6 +898,34 @@ def testGridNearestNeighbour(self): source + ' ' + 'd:/temp/check.jpg']) + def testOgr2Ogr(self): + context = QgsProcessingContext() + feedback = QgsProcessingFeedback() + source = os.path.join(testDataPath, 'polys.gml') + alg = ogr2ogr() + alg.initAlgorithm() + + self.assertEqual( + alg.getConsoleCommands({'INPUT': source, + 'OUTPUT': 'd:/temp/check.shp'}, context, feedback), + ['ogr2ogr', + '-f "ESRI Shapefile" d:/temp/check.shp ' + + source + ' polys2']) + + self.assertEqual( + alg.getConsoleCommands({'INPUT': source, + 'OUTPUT': 'd:/temp/check.kml'}, context, feedback), + ['ogr2ogr', + '-f "LIBKML" d:/temp/check.kml ' + + source + ' polys2']) + + self.assertEqual( + alg.getConsoleCommands({'INPUT': source, + 'OUTPUT': 'd:/temp/my out/check.kml'}, context, feedback), + ['ogr2ogr', + '-f "LIBKML" "d:/temp/my out/check.kml" ' + + source + ' polys2']) + def testProximity(self): context = QgsProcessingContext() feedback = QgsProcessingFeedback()