Skip to content

Commit 56b77db

Browse files
committed
[FEATURE][processing] Add choice of simplification method to simplify
This change allows users to choose which method to use when running the simplify geometries algorithm, with choices of the existing distance based (Douglas Peucker) algorithm, area based (Visvalingam) algorithm and snap-to-grid. Visvaligam in particular usually results in more cartographically pleasing simplification over the standard distance based methods.
1 parent fbd6618 commit 56b77db

9 files changed

+193
-2
lines changed

python/plugins/processing/algs/help/qgis.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ qgis:setstyleforvectorlayer: >
429429
qgis:simplifygeometries: >
430430
This algorithm simplifies the geometries in a line or polygon layer. It creates a new layer with the same features as the ones in the input layer, but with geometries containing a lower number of vertices.
431431

432+
The algorithm gives a choice of simplification methods, including distance based (the "Douglas-Peucker" algorithm), area based ("Visvalingam" algorithm) and snapping geometries to grid.
433+
432434
qgis:singlepartstomultipart:
433435

434436

python/plugins/processing/algs/qgis/SimplifyGeometries.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@
2929

3030
from qgis.PyQt.QtGui import QIcon
3131

32-
from qgis.core import Qgis, QgsFeature, QgsGeometry, QgsWkbTypes
32+
from qgis.core import Qgis, QgsFeature, QgsGeometry, QgsWkbTypes, QgsMapToPixelSimplifier
3333

3434
from processing.core.GeoAlgorithm import GeoAlgorithm
3535
from processing.core.ProcessingLog import ProcessingLog
3636
from processing.core.parameters import ParameterVector
3737
from processing.core.parameters import ParameterNumber
38+
from processing.core.parameters import ParameterSelection
3839
from processing.core.outputs import OutputVector
3940
from processing.tools import dataobjects, vector
4041

@@ -46,6 +47,7 @@ class SimplifyGeometries(GeoAlgorithm):
4647
INPUT = 'INPUT'
4748
TOLERANCE = 'TOLERANCE'
4849
OUTPUT = 'OUTPUT'
50+
METHOD = 'METHOD'
4951

5052
def getIcon(self):
5153
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'simplify.png'))
@@ -57,6 +59,13 @@ def defineCharacteristics(self):
5759
self.addParameter(ParameterVector(self.INPUT,
5860
self.tr('Input layer'),
5961
[ParameterVector.VECTOR_TYPE_POLYGON, ParameterVector.VECTOR_TYPE_LINE]))
62+
self.methods = [self.tr('Distance (Douglas-Peucker)'),
63+
'Snap to grid',
64+
'Area (Visvalingam)']
65+
self.addParameter(ParameterSelection(
66+
self.METHOD,
67+
self.tr('Simplification method'),
68+
self.methods, default=0))
6069
self.addParameter(ParameterNumber(self.TOLERANCE,
6170
self.tr('Tolerance'), 0.0, 10000000.0, 1.0))
6271

@@ -65,6 +74,7 @@ def defineCharacteristics(self):
6574
def processAlgorithm(self, progress):
6675
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
6776
tolerance = self.getParameterValue(self.TOLERANCE)
77+
method = self.getParameterValue(self.METHOD)
6878

6979
pointsBefore = 0
7080
pointsAfter = 0
@@ -74,12 +84,21 @@ def processAlgorithm(self, progress):
7484

7585
features = vector.features(layer)
7686
total = 100.0 / len(features)
87+
88+
if method != 0:
89+
simplifier = QgsMapToPixelSimplifier(QgsMapToPixelSimplifier.SimplifyGeometry, tolerance, method)
90+
7791
for current, input_feature in enumerate(features):
7892
out_feature = input_feature
7993
if input_feature.geometry():
8094
input_geometry = input_feature.geometry()
8195
pointsBefore += input_geometry.geometry().nCoordinates()
82-
output_geometry = input_geometry.simplify(tolerance)
96+
97+
if method == 0: # distance
98+
output_geometry = input_geometry.simplify(tolerance)
99+
else:
100+
output_geometry = simplifier.simplify(input_geometry)
101+
83102
pointsAfter += output_geometry.geometry().nCoordinates()
84103
out_feature.setGeometry(output_geometry)
85104
writer.addFeature(out_feature)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<GMLFeatureClassList>
2+
<GMLFeatureClass>
3+
<Name>simplify_grid_lines</Name>
4+
<ElementPath>simplify_grid_lines</ElementPath>
5+
<GeometryType>2</GeometryType>
6+
<SRSName>EPSG:4326</SRSName>
7+
<DatasetSpecificInfo>
8+
<FeatureCount>4</FeatureCount>
9+
<ExtentXMin>-0.08703</ExtentXMin>
10+
<ExtentXMax>10.63163</ExtentXMax>
11+
<ExtentYMin>-0.26248</ExtentYMin>
12+
<ExtentYMax>4.98546</ExtentYMax>
13+
</DatasetSpecificInfo>
14+
</GMLFeatureClass>
15+
</GMLFeatureClassList>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation=""
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-0.08703339882121899</gml:X><gml:Y>-0.262475442043224</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:simplify_grid_lines fid="1">
16+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
17+
</ogr:simplify_grid_lines>
18+
</gml:featureMember>
19+
<gml:featureMember>
20+
<ogr:simplify_grid_lines fid="3">
21+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.087033398821219,2.782318271119842 2.314145383104125,2.757563850687622 7.388801571709235,4.713163064833005 9.789980353634579,2.757563850687622 10.631630648330059,2.757563850687622</gml:coordinates></gml:LineString></ogr:geometryProperty>
22+
</ogr:simplify_grid_lines>
23+
</gml:featureMember>
24+
<gml:featureMember>
25+
<ogr:simplify_grid_lines fid="2">
26+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>0.061493123772101,-0.237721021611003 1.967583497053045,-0.262475442043224 4.34400785854617,2.262475442043221 6.448133595284873,-0.262475442043224 10.606876227897841,-0.188212180746563</gml:coordinates></gml:LineString></ogr:geometryProperty>
27+
</ogr:simplify_grid_lines>
28+
</gml:featureMember>
29+
<gml:featureMember>
30+
<ogr:simplify_grid_lines fid="4">
31+
</ogr:simplify_grid_lines>
32+
</gml:featureMember>
33+
</ogr:FeatureCollection>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<GMLFeatureClassList>
2+
<GMLFeatureClass>
3+
<Name>simplify_vis_lines</Name>
4+
<ElementPath>simplify_vis_lines</ElementPath>
5+
<GeometryType>2</GeometryType>
6+
<SRSName>EPSG:4326</SRSName>
7+
<DatasetSpecificInfo>
8+
<FeatureCount>4</FeatureCount>
9+
<ExtentXMin>-0.08703</ExtentXMin>
10+
<ExtentXMax>10.63163</ExtentXMax>
11+
<ExtentYMin>-0.26248</ExtentYMin>
12+
<ExtentYMax>4.98546</ExtentYMax>
13+
</DatasetSpecificInfo>
14+
</GMLFeatureClass>
15+
</GMLFeatureClassList>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation=""
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-0.08703339882121899</gml:X><gml:Y>-0.262475442043224</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:simplify_vis_lines fid="1">
16+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
17+
</ogr:simplify_vis_lines>
18+
</gml:featureMember>
19+
<gml:featureMember>
20+
<ogr:simplify_vis_lines fid="3">
21+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.087033398821219,2.782318271119842 5.284675834970531,2.782318271119842 7.388801571709235,4.713163064833005 10.631630648330059,2.757563850687622</gml:coordinates></gml:LineString></ogr:geometryProperty>
22+
</ogr:simplify_vis_lines>
23+
</gml:featureMember>
24+
<gml:featureMember>
25+
<ogr:simplify_vis_lines fid="2">
26+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>0.061493123772101,-0.237721021611003 1.967583497053045,-0.262475442043224 4.34400785854617,2.262475442043221 6.448133595284873,-0.262475442043224 10.606876227897841,-0.188212180746563</gml:coordinates></gml:LineString></ogr:geometryProperty>
27+
</ogr:simplify_vis_lines>
28+
</gml:featureMember>
29+
<gml:featureMember>
30+
<ogr:simplify_vis_lines fid="4">
31+
</ogr:simplify_vis_lines>
32+
</gml:featureMember>
33+
</ogr:FeatureCollection>

python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

+26
Original file line numberDiff line numberDiff line change
@@ -939,3 +939,29 @@ tests:
939939
OUTPUT:
940940
name: expected/simplify_multilines.gml
941941
type: vector
942+
943+
- algorithm: qgis:simplifygeometries
944+
name: Simplify (visval)
945+
params:
946+
INPUT:
947+
name: simplify_lines.gml
948+
type: vector
949+
METHOD: '2'
950+
TOLERANCE: 1.0
951+
results:
952+
OUTPUT:
953+
name: expected/simplify_vis_lines.gml
954+
type: vector
955+
956+
- algorithm: qgis:simplifygeometries
957+
name: Simplify (grid)
958+
params:
959+
INPUT:
960+
name: simplify_lines.gml
961+
type: vector
962+
METHOD: '1'
963+
TOLERANCE: 5.0
964+
results:
965+
OUTPUT:
966+
name: expected/simplify_grid_lines.gml
967+
type: vector
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<GMLFeatureClassList>
2+
<GMLFeatureClass>
3+
<Name>simplify_lines</Name>
4+
<ElementPath>simplify_lines</ElementPath>
5+
<GeometryType>2</GeometryType>
6+
<SRSName>EPSG:4326</SRSName>
7+
<DatasetSpecificInfo>
8+
<FeatureCount>4</FeatureCount>
9+
<ExtentXMin>-0.08703</ExtentXMin>
10+
<ExtentXMax>10.63163</ExtentXMax>
11+
<ExtentYMin>-0.26248</ExtentYMin>
12+
<ExtentYMax>4.98546</ExtentYMax>
13+
</DatasetSpecificInfo>
14+
</GMLFeatureClass>
15+
</GMLFeatureClassList>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation=""
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-0.08703339882121885</gml:X><gml:Y>-0.2624754420432236</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:simplify_lines fid="1">
16+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
17+
</ogr:simplify_lines>
18+
</gml:featureMember>
19+
<gml:featureMember>
20+
<ogr:simplify_lines fid="3">
21+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.087033398821219,2.782318271119842 2.314145383104125,2.757563850687622 2.611198428290766,4.688408644400785 2.611198428290766,2.807072691552063 5.284675834970531,2.782318271119842 7.388801571709235,4.713163064833005 9.789980353634579,2.757563850687622 10.631630648330061,2.757563850687622</gml:coordinates></gml:LineString></ogr:geometryProperty>
22+
</ogr:simplify_lines>
23+
</gml:featureMember>
24+
<gml:featureMember>
25+
<ogr:simplify_lines fid="2">
26+
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>0.061493123772101,-0.237721021611003 1.967583497053045,-0.262475442043224 4.34400785854617,2.262475442043221 6.448133595284873,-0.262475442043224 10.606876227897841,-0.188212180746563</gml:coordinates></gml:LineString></ogr:geometryProperty>
27+
</ogr:simplify_lines>
28+
</gml:featureMember>
29+
<gml:featureMember>
30+
<ogr:simplify_lines fid="4">
31+
</ogr:simplify_lines>
32+
</gml:featureMember>
33+
</ogr:FeatureCollection>

0 commit comments

Comments
 (0)