Skip to content

Commit

Permalink
[FEATURE] Snap geometries algorithm
Browse files Browse the repository at this point in the history
Makes sure that any two vertices of the vector layer are at least at distance given by the threshold value.
The algorithm moves nearby vertices to one location and adds vertices to segments that are passing around other
vertices within the threshold. It does not remove any vertices. Also, it does not modify geometries unless
needed (it does not snap coordinates to a grid).

This algorithm comes handy when doing vector overlay operations such as intersection, union or difference
to prevent possible topological errors caused by numerical errors if coordinates are very close to each other.

After running the algorithm some previously valid geometries may become invalid and therefore it may be useful
to run Fix geometries algorithm afterwards.
  • Loading branch information
wonder-sk committed Sep 13, 2018
1 parent f99b2db commit 4a06697
Show file tree
Hide file tree
Showing 8 changed files with 525 additions and 0 deletions.
@@ -0,0 +1,9 @@
{
"type": "FeatureCollection",
"name": "snap_geometries",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3857" } },
"features": [
{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.123, 10.123 ], [ 20.123, 20.456 ], [ 20.2, 20.456 ], [ 20.2, 20.5 ], [ 30.0, 20.5 ], [ 30.0, 10.123 ], [ 29.8, 10.123 ], [ 21.0, 10.123 ], [ 20.123, 10.123 ] ] ] } },
{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 31.0, 10.0 ], [ 20.0, 10.0 ], [ 20.0, 5.0 ], [ 31.0, 10.0 ] ] ] } }
]
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ snap_geometries.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>20</gml:X><gml:Y>5</gml:Y></gml:coord>
<gml:coord><gml:X>31</gml:X><gml:Y>20.5</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:snap_geometries fid="snap_geometries.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:3857"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>20.123,10.123 20.123,20.456 20.123,20.456 20.123,20.456 30.0,20.5 30.0,10.123 30.0,10.123 21.0,10.123 20.123,10.123</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
</ogr:snap_geometries>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_geometries fid="snap_geometries.1">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:3857"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>31,10 30.0,10.123 21.0,10.123 20.123,10.123 20,5 31,10</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
</ogr:snap_geometries>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="snap_geometries" type="ogr:snap_geometries_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="snap_geometries_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
12 changes: 12 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -5586,6 +5586,18 @@ tests:
fields:
fid: skip

- algorithm: native:snap
name: Test Snap Geometries (to each other)
params:
INPUT:
name: custom/snap_geometries.geojson
type: vector
THRESHOLD: 0.5
results:
OUTPUT:
name: expected/snap_geometries.gml
type: vector

- algorithm: native:taperedbuffer
name: Tapered buffers (lines)
params:
Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -85,6 +85,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmshortestpathpointtopoint.cpp
processing/qgsalgorithmsimplify.cpp
processing/qgsalgorithmsmooth.cpp
processing/qgsalgorithmsnapgeometries.cpp
processing/qgsalgorithmsnaptogrid.cpp
processing/qgsalgorithmsplitwithlines.cpp
processing/qgsalgorithmstringconcatenation.cpp
Expand Down

0 comments on commit 4a06697

Please sign in to comment.