Skip to content

Commit

Permalink
[processing][gdal] Add unit tests for Dissolve algorithm
Browse files Browse the repository at this point in the history
Also:

Thanks to @agiudiceandrea:

Fixes #19900
Statistics were erroneously computed on the dissolve field, rather than on the statistic attribute field as it should be.

Fixes #19307
Handle filenames with white spaces (in the same way as Buffer, OffsetCurve, OneSideBuffer, PintsAlongLines algs).
  • Loading branch information
nyalldawson committed Sep 25, 2018
1 parent 6e06c32 commit a3af1f9
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 5 deletions.
10 changes: 5 additions & 5 deletions python/plugins/processing/algs/gdal/Dissolve.py
Expand Up @@ -154,21 +154,21 @@ def getConsoleCommands(self, parameters, context, feedback, executing=True):
if self.parameterAsBool(parameters, self.COMPUTE_AREA, context):
tokens.append("SUM(ST_Area({0})) AS area, ST_Perimeter(ST_Union({0})) AS perimeter".format(geometry))

statsField = self.parameterAsString(parameters, self.FIELD, context)
statsField = self.parameterAsString(parameters, self.STATISTICS_ATTRIBUTE, context)
if statsField and self.parameterAsBool(parameters, self.COMPUTE_STATISTICS, context):
tokens.append("SUM({0}) AS sum, MIN({0}) AS min, MAX({0}) AS max, AVG({0}) AS avg".format(statsField))

params = ','.join(tokens)
if params:
if self.parameterAsBool(parameters, self.KEEP_ATTRIBUTES, context):
sql = "SELECT ST_Union({}) AS {}{}, {} FROM {} GROUP BY {}".format(geometry, geometry, other_fields, params, layerName, fieldName)
sql = "SELECT ST_Union({}) AS {}{}, {} FROM '{}' GROUP BY {}".format(geometry, geometry, other_fields, params, layerName, fieldName)
else:
sql = "SELECT ST_Union({}) AS {}, {}, {} FROM {} GROUP BY {}".format(geometry, geometry, fieldName, params, layerName, fieldName)
sql = "SELECT ST_Union({}) AS {}, {}, {} FROM '{}' GROUP BY {}".format(geometry, geometry, fieldName, params, layerName, fieldName)
else:
if self.parameterAsBool(parameters, self.KEEP_ATTRIBUTES, context):
sql = "SELECT ST_Union({}) AS {}{} FROM {} GROUP BY {}".format(geometry, geometry, other_fields, layerName, fieldName)
sql = "SELECT ST_Union({}) AS {}{} FROM '{}' GROUP BY {}".format(geometry, geometry, other_fields, layerName, fieldName)
else:
sql = "SELECT ST_Union({}) AS {}, {} FROM {} GROUP BY {}".format(geometry, geometry, fieldName, layerName, fieldName)
sql = "SELECT ST_Union({}) AS {}, {} FROM '{}' GROUP BY {}".format(geometry, geometry, fieldName, layerName, fieldName)

arguments.append(sql)

Expand Down
146 changes: 146 additions & 0 deletions python/plugins/processing/tests/GdalAlgorithmsTest.py
Expand Up @@ -31,6 +31,7 @@
from processing.algs.gdal.AssignProjection import AssignProjection
from processing.algs.gdal.ClipRasterByExtent import ClipRasterByExtent
from processing.algs.gdal.ClipRasterByMask import ClipRasterByMask
from processing.algs.gdal.Dissolve import Dissolve
from processing.algs.gdal.gdal2tiles import gdal2tiles
from processing.algs.gdal.gdalcalc import gdalcalc
from processing.algs.gdal.gdaltindex import gdaltindex
Expand Down Expand Up @@ -611,6 +612,151 @@ def testContour(self):
source + ' ' +
outdir + '/check.shp'])

def testDissolve(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
source = os.path.join(testDataPath, 'polys.gml')
source_with_space = os.path.join(testDataPath, 'filename with spaces.gml')
alg = Dissolve()
alg.initAlgorithm()

with tempfile.TemporaryDirectory() as outdir:
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source_with_space,
'FIELD': 'my_field',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
'"' + source_with_space + '" ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'filename_with_spaces\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'GEOMETRY': 'the_geom',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(the_geom) AS the_geom, my_field FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'EXPLODE_COLLECTIONS': True,
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'polys2\' ' +
'GROUP BY my_field" -explodecollections -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COUNT_FEATURES': True,
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field, COUNT(geometry) AS count FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COUNT_FEATURES': True,
'GEOMETRY': 'the_geom',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(the_geom) AS the_geom, my_field, COUNT(the_geom) AS count FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COMPUTE_AREA': True,
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field, SUM(ST_Area(geometry)) AS area, ' +
'ST_Perimeter(ST_Union(geometry)) AS perimeter FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COMPUTE_AREA': True,
'GEOMETRY': 'the_geom',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(the_geom) AS the_geom, my_field, SUM(ST_Area(the_geom)) AS area, ' +
'ST_Perimeter(ST_Union(the_geom)) AS perimeter FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COMPUTE_STATISTICS': True,
'STATISTICS_ATTRIBUTE': 'my_val',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field, ' +
'SUM(my_val) AS sum, MIN(my_val) AS min, MAX(my_val) AS max, AVG(my_val) AS avg FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

# compute stats without stats attribute, and vice versa (should be ignored)
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'COMPUTE_STATISTICS': True,
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'STATISTICS_ATTRIBUTE': 'my_val',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'polys2\' ' +
'GROUP BY my_field" -f "ESRI Shapefile"'])

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FIELD': 'my_field',
'OPTIONS': 'my opts',
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['ogr2ogr',
outdir + '/check.shp ' +
source + ' ' +
'-dialect sqlite -sql "SELECT ST_Union(geometry) AS geometry, my_field FROM \'polys2\' ' +
'GROUP BY my_field" "my opts" -f "ESRI Shapefile"'])

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

0 comments on commit a3af1f9

Please sign in to comment.