Skip to content
Permalink
Browse files

Merge pull request #7194 from wonder-sk/snap-geometries-alg

[FEATURE] Snap geometries algorithm
  • Loading branch information
wonder-sk committed Sep 14, 2018
2 parents 4ac834d + 2b55858 commit 9bcd21fb19f2bce170f5cdab4ccdcf53e4c04487
@@ -13,6 +13,7 @@
%Include auto_generated/raster/qgsrastercalcnode.sip
%Include auto_generated/raster/qgstotalcurvaturefilter.sip
%Include auto_generated/vector/qgsgeometrysnapper.sip
%Include auto_generated/vector/qgsgeometrysnappersinglesource.sip
%Include auto_generated/vector/qgszonalstatistics.sip
%Include auto_generated/interpolation/qgsinterpolator.sip
%Include auto_generated/interpolation/qgsgridfilewriter.sip
@@ -0,0 +1,52 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/vector/qgsgeometrysnappersinglesource.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsGeometrySnapperSingleSource
{
%Docstring

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.

.. note::

Originally ported from GRASS implementation of Vect_snap_lines_list()

.. versionadded:: 3.4
%End

%TypeHeaderCode
#include "qgsgeometrysnappersinglesource.h"
%End
public:

static int run( const QgsFeatureSource &source, QgsFeatureSink &sink, double thresh, QgsFeedback *feedback );
%Docstring
Run the algorithm on given source and output results to the sink, using threshold value in the source's map units.
Returns number of modified geometries.
%End
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/vector/qgsgeometrysnappersinglesource.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -26,6 +26,7 @@
__revision__ = '$Format:%H$'

from qgis.analysis import (QgsGeometrySnapper,
QgsGeometrySnapperSingleSource,
QgsInternalGeometrySnapper)
from qgis.core import (QgsFeatureSink,
QgsProcessing,
@@ -71,7 +72,8 @@ def initAlgorithm(self, config=None):
self.tr('Prefer closest point, don\'t insert new vertices'),
self.tr('Move end points only, prefer aligning nodes'),
self.tr('Move end points only, prefer closest point'),
self.tr('Snap end points to end points only')]
self.tr('Snap end points to end points only'),
self.tr('Snap to anchor nodes (single layer only)')]
self.addParameter(QgsProcessingParameterEnum(
self.BEHAVIOR,
self.tr('Behavior'),
@@ -106,6 +108,9 @@ def processAlgorithm(self, parameters, context, feedback):
total = 100.0 / source.featureCount() if source.featureCount() else 0

if parameters[self.INPUT] != parameters[self.REFERENCE_LAYER]:
if mode == 7:
raise QgsProcessingException(self.tr('This mode applies when the input and reference layer are the same.'))

snapper = QgsGeometrySnapper(reference_source)
processed = 0
for f in features:
@@ -119,6 +124,10 @@ def processAlgorithm(self, parameters, context, feedback):
sink.addFeature(f)
processed += 1
feedback.setProgress(processed * total)
elif mode == 7:
# input layer == ref layer
modified_count = QgsGeometrySnapperSingleSource.run(source, sink, tolerance, feedback)
feedback.pushInfo(self.tr('Snapped {} geometries.').format(modified_count))
else:
# snapping internally
snapper = QgsInternalGeometrySnapper(tolerance, mode)
Binary file not shown.
@@ -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>
@@ -2045,6 +2045,22 @@ tests:
name: expected/snap_internal.gml
type: vector

- algorithm: qgis:snapgeometries
name: Test Snap Geometries (to each other)
params:
BEHAVIOR: '7'
INPUT:
name: custom/snap_geometries.geojson
type: vector
REFERENCE_LAYER:
name: custom/snap_geometries.geojson
type: vector
TOLERANCE: 0.5
results:
OUTPUT:
name: expected/snap_geometries.gml
type: vector

- algorithm: qgis:poleofinaccessibility
name: Pole of inaccessibility (polygons)
params:
@@ -123,6 +123,7 @@ SET(QGIS_ANALYSIS_SRCS
raster/qgsrastermatrix.cpp
vector/mersenne-twister.cpp
vector/qgsgeometrysnapper.cpp
vector/qgsgeometrysnappersinglesource.cpp
vector/qgszonalstatistics.cpp

network/qgsgraph.cpp
@@ -231,6 +232,7 @@ SET(QGIS_ANALYSIS_HDRS

vector/mersenne-twister.h
vector/qgsgeometrysnapper.h
vector/qgsgeometrysnappersinglesource.h
vector/qgszonalstatistics.h
vector/geometry_checker/qgsgeometrycheckerutils.h
vector/geometry_checker/qgsfeaturepool.h

0 comments on commit 9bcd21f

Please sign in to comment.
You can’t perform that action at this time.