Skip to content

Commit

Permalink
[FEATURE][processing] Add choice of simplification method to simplify
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nyalldawson committed Aug 31, 2016
1 parent fbd6618 commit 56b77db
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 2 deletions.
2 changes: 2 additions & 0 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -429,6 +429,8 @@ qgis:setstyleforvectorlayer: >
qgis:simplifygeometries: >
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.

The algorithm gives a choice of simplification methods, including distance based (the "Douglas-Peucker" algorithm), area based ("Visvalingam" algorithm) and snapping geometries to grid.

qgis:singlepartstomultipart:


Expand Down
23 changes: 21 additions & 2 deletions python/plugins/processing/algs/qgis/SimplifyGeometries.py
Expand Up @@ -29,12 +29,13 @@

from qgis.PyQt.QtGui import QIcon

from qgis.core import Qgis, QgsFeature, QgsGeometry, QgsWkbTypes
from qgis.core import Qgis, QgsFeature, QgsGeometry, QgsWkbTypes, QgsMapToPixelSimplifier

from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.ProcessingLog import ProcessingLog
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector

Expand All @@ -46,6 +47,7 @@ class SimplifyGeometries(GeoAlgorithm):
INPUT = 'INPUT'
TOLERANCE = 'TOLERANCE'
OUTPUT = 'OUTPUT'
METHOD = 'METHOD'

def getIcon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'simplify.png'))
Expand All @@ -57,6 +59,13 @@ def defineCharacteristics(self):
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'),
[ParameterVector.VECTOR_TYPE_POLYGON, ParameterVector.VECTOR_TYPE_LINE]))
self.methods = [self.tr('Distance (Douglas-Peucker)'),
'Snap to grid',
'Area (Visvalingam)']
self.addParameter(ParameterSelection(
self.METHOD,
self.tr('Simplification method'),
self.methods, default=0))
self.addParameter(ParameterNumber(self.TOLERANCE,
self.tr('Tolerance'), 0.0, 10000000.0, 1.0))

Expand All @@ -65,6 +74,7 @@ def defineCharacteristics(self):
def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
tolerance = self.getParameterValue(self.TOLERANCE)
method = self.getParameterValue(self.METHOD)

pointsBefore = 0
pointsAfter = 0
Expand All @@ -74,12 +84,21 @@ def processAlgorithm(self, progress):

features = vector.features(layer)
total = 100.0 / len(features)

if method != 0:
simplifier = QgsMapToPixelSimplifier(QgsMapToPixelSimplifier.SimplifyGeometry, tolerance, method)

for current, input_feature in enumerate(features):
out_feature = input_feature
if input_feature.geometry():
input_geometry = input_feature.geometry()
pointsBefore += input_geometry.geometry().nCoordinates()
output_geometry = input_geometry.simplify(tolerance)

if method == 0: # distance
output_geometry = input_geometry.simplify(tolerance)
else:
output_geometry = simplifier.simplify(input_geometry)

pointsAfter += output_geometry.geometry().nCoordinates()
out_feature.setGeometry(output_geometry)
writer.addFeature(out_feature)
Expand Down
@@ -0,0 +1,15 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>simplify_grid_lines</Name>
<ElementPath>simplify_grid_lines</ElementPath>
<GeometryType>2</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
<ExtentXMin>-0.08703</ExtentXMin>
<ExtentXMax>10.63163</ExtentXMax>
<ExtentYMin>-0.26248</ExtentYMin>
<ExtentYMax>4.98546</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-0.08703339882121899</gml:X><gml:Y>-0.262475442043224</gml:Y></gml:coord>
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:simplify_grid_lines fid="1">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:simplify_grid_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_grid_lines fid="3">
<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>
</ogr:simplify_grid_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_grid_lines fid="2">
<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>
</ogr:simplify_grid_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_grid_lines fid="4">
</ogr:simplify_grid_lines>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,15 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>simplify_vis_lines</Name>
<ElementPath>simplify_vis_lines</ElementPath>
<GeometryType>2</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
<ExtentXMin>-0.08703</ExtentXMin>
<ExtentXMax>10.63163</ExtentXMax>
<ExtentYMin>-0.26248</ExtentYMin>
<ExtentYMax>4.98546</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-0.08703339882121899</gml:X><gml:Y>-0.262475442043224</gml:Y></gml:coord>
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:simplify_vis_lines fid="1">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:simplify_vis_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_vis_lines fid="3">
<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>
</ogr:simplify_vis_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_vis_lines fid="2">
<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>
</ogr:simplify_vis_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_vis_lines fid="4">
</ogr:simplify_vis_lines>
</gml:featureMember>
</ogr:FeatureCollection>
26 changes: 26 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -939,3 +939,29 @@ tests:
OUTPUT:
name: expected/simplify_multilines.gml
type: vector

- algorithm: qgis:simplifygeometries
name: Simplify (visval)
params:
INPUT:
name: simplify_lines.gml
type: vector
METHOD: '2'
TOLERANCE: 1.0
results:
OUTPUT:
name: expected/simplify_vis_lines.gml
type: vector

- algorithm: qgis:simplifygeometries
name: Simplify (grid)
params:
INPUT:
name: simplify_lines.gml
type: vector
METHOD: '1'
TOLERANCE: 5.0
results:
OUTPUT:
name: expected/simplify_grid_lines.gml
type: vector
15 changes: 15 additions & 0 deletions python/plugins/processing/tests/testdata/simplify_lines.gfs
@@ -0,0 +1,15 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>simplify_lines</Name>
<ElementPath>simplify_lines</ElementPath>
<GeometryType>2</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
<ExtentXMin>-0.08703</ExtentXMin>
<ExtentXMax>10.63163</ExtentXMax>
<ExtentYMin>-0.26248</ExtentYMin>
<ExtentYMax>4.98546</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
33 changes: 33 additions & 0 deletions python/plugins/processing/tests/testdata/simplify_lines.gml
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-0.08703339882121885</gml:X><gml:Y>-0.2624754420432236</gml:Y></gml:coord>
<gml:coord><gml:X>10.63163064833006</gml:X><gml:Y>4.985461689587426</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:simplify_lines fid="1">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.062278978388999,4.985461689587426 5.606483300589391,4.985461689587426</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:simplify_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_lines fid="3">
<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>
</ogr:simplify_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_lines fid="2">
<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>
</ogr:simplify_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:simplify_lines fid="4">
</ogr:simplify_lines>
</gml:featureMember>
</ogr:FeatureCollection>

0 comments on commit 56b77db

Please sign in to comment.