Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Add API method to remove duplicate nodes from geometries
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerate geometry. By default, z values are not considered when detecting duplicate nodes. E.g. two nodes with the same x and y coordinate but different z values will still be considered duplicate and one will be removed. If useZValues is true, then the z values are also tested and nodes with the same x and y but different z will be maintained. Note that duplicate nodes are not tested between different parts of a multipart geometry. E.g. a multipoint geometry with overlapping points will not be changed by this method. The function will return true if nodes were removed, or false if no duplicate nodes were found. Includes unit tests and a processing algorithm which exposes this functionality.
- Loading branch information
1 parent
0b452ca
commit e12621c
Showing
34 changed files
with
720 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<ogr:FeatureCollection | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://ogr.maptools.org/ line_duplicate_nodes.xsd" | ||
xmlns:ogr="http://ogr.maptools.org/" | ||
xmlns:gml="http://www.opengis.net/gml"> | ||
<gml:boundedBy> | ||
<gml:Box> | ||
<gml:coord><gml:X>2</gml:X><gml:Y>0</gml:Y></gml:coord> | ||
<gml:coord><gml:X>3</gml:X><gml:Y>3</gml:Y></gml:coord> | ||
</gml:Box> | ||
</gml:boundedBy> | ||
|
||
<gml:featureMember> | ||
<ogr:line_duplicate_nodes fid="lines.2"> | ||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>2,0 2,2 3,2 3,3 3,3</gml:coordinates></gml:LineString></ogr:geometryProperty> | ||
</ogr:line_duplicate_nodes> | ||
</gml:featureMember> | ||
</ogr:FeatureCollection> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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="line_duplicate_nodes" type="ogr:line_duplicate_nodes_Type" substitutionGroup="gml:_Feature"/> | ||
<xs:complexType name="line_duplicate_nodes_Type"> | ||
<xs:complexContent> | ||
<xs:extension base="gml:AbstractFeatureType"> | ||
<xs:sequence> | ||
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> | ||
</xs:sequence> | ||
</xs:extension> | ||
</xs:complexContent> | ||
</xs:complexType> | ||
</xs:schema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<ogr:FeatureCollection | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://ogr.maptools.org/ removed_duplicated_nodes_line.xsd" | ||
xmlns:ogr="http://ogr.maptools.org/" | ||
xmlns:gml="http://www.opengis.net/gml"> | ||
<gml:boundedBy> | ||
<gml:Box> | ||
<gml:coord><gml:X>2</gml:X><gml:Y>0</gml:Y></gml:coord> | ||
<gml:coord><gml:X>3</gml:X><gml:Y>3</gml:Y></gml:coord> | ||
</gml:Box> | ||
</gml:boundedBy> | ||
|
||
<gml:featureMember> | ||
<ogr:removed_duplicated_nodes_line fid="lines.2"> | ||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>2,0 2,2 3,2 3,3</gml:coordinates></gml:LineString></ogr:geometryProperty> | ||
</ogr:removed_duplicated_nodes_line> | ||
</gml:featureMember> | ||
</ogr:FeatureCollection> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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="removed_duplicated_nodes_line" type="ogr:removed_duplicated_nodes_line_Type" substitutionGroup="gml:_Feature"/> | ||
<xs:complexType name="removed_duplicated_nodes_line_Type"> | ||
<xs:complexContent> | ||
<xs:extension base="gml:AbstractFeatureType"> | ||
<xs:sequence> | ||
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> | ||
</xs:sequence> | ||
</xs:extension> | ||
</xs:complexContent> | ||
</xs:complexType> | ||
</xs:schema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/*************************************************************************** | ||
qgsalgorithmremoveduplicatenodes.cpp | ||
--------------------- | ||
begin : November 2017 | ||
copyright : (C) 2017 by Nyall Dawson | ||
email : nyall dot dawson at gmail dot com | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgsalgorithmremoveduplicatenodes.h" | ||
|
||
///@cond PRIVATE | ||
|
||
QString QgsAlgorithmRemoveDuplicateNodes::name() const | ||
{ | ||
return QStringLiteral( "removeduplicatenodes" ); | ||
} | ||
|
||
QString QgsAlgorithmRemoveDuplicateNodes::displayName() const | ||
{ | ||
return QObject::tr( "Remove duplicate nodes" ); | ||
} | ||
|
||
QStringList QgsAlgorithmRemoveDuplicateNodes::tags() const | ||
{ | ||
return QObject::tr( "points,valid,overlapping" ).split( ',' ); | ||
} | ||
|
||
QString QgsAlgorithmRemoveDuplicateNodes::group() const | ||
{ | ||
return QObject::tr( "Vector geometry" ); | ||
} | ||
|
||
QString QgsAlgorithmRemoveDuplicateNodes::outputName() const | ||
{ | ||
return QObject::tr( "Cleaned" ); | ||
} | ||
|
||
QString QgsAlgorithmRemoveDuplicateNodes::shortHelpString() const | ||
{ | ||
return QObject::tr( "This algorithm removes duplicate nodes from features, wherever removing the nodes does " | ||
"not result in a degenerate geometry.\n\n" | ||
"The tolerance parameter specifies the tolerance for coordinates when determining whether " | ||
"vertices are identical.\n\n" | ||
"By default, z values are not considered when detecting duplicate nodes. E.g. two nodes " | ||
"with the same x and y coordinate but different z values will still be considered " | ||
"duplicate and one will be removed. If the Use Z Value parameter is true, then the z values are " | ||
"also tested and nodes with the same x and y but different z will be maintained.\n\n" | ||
"Note that duplicate nodes are not tested between different parts of a multipart geometry. E.g. " | ||
"a multipoint geometry with overlapping points will not be changed by this method." ); | ||
} | ||
|
||
QgsAlgorithmRemoveDuplicateNodes *QgsAlgorithmRemoveDuplicateNodes::createInstance() const | ||
{ | ||
return new QgsAlgorithmRemoveDuplicateNodes(); | ||
} | ||
|
||
void QgsAlgorithmRemoveDuplicateNodes::initParameters( const QVariantMap & ) | ||
{ | ||
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "TOLERANCE" ), | ||
QObject::tr( "Tolerance" ), QgsProcessingParameterNumber::Double, | ||
0.000001, false, 0, 10000000.0 ) ); | ||
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "USE_Z_VALUE" ), | ||
QObject::tr( "Use Z Value" ), false ) ); | ||
} | ||
|
||
bool QgsAlgorithmRemoveDuplicateNodes::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) | ||
{ | ||
mTolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context ); | ||
mUseZValues = parameterAsBool( parameters, QStringLiteral( "USE_Z_VALUE" ), context ); | ||
return true; | ||
} | ||
|
||
QgsFeature QgsAlgorithmRemoveDuplicateNodes::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * ) | ||
{ | ||
QgsFeature f = feature; | ||
if ( f.hasGeometry() ) | ||
{ | ||
QgsGeometry geometry = f.geometry(); | ||
geometry.removeDuplicateNodes( mTolerance, mUseZValues ); | ||
f.setGeometry( geometry ); | ||
} | ||
return f; | ||
} | ||
|
||
///@endcond | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/*************************************************************************** | ||
qgsalgorithmremoveduplicatenodes.h | ||
--------------------- | ||
begin : November 2017 | ||
copyright : (C) 2017 by Nyall Dawson | ||
email : nyall dot dawson at gmail dot com | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSALGORITHMREMOVEDUPLICATENODES_H | ||
#define QGSALGORITHMREMOVEDUPLICATENODES_H | ||
|
||
#define SIP_NO_FILE | ||
|
||
#include "qgis.h" | ||
#include "qgsprocessingalgorithm.h" | ||
|
||
///@cond PRIVATE | ||
|
||
/** | ||
* Native remove duplicate nodes algorithm. | ||
*/ | ||
class QgsAlgorithmRemoveDuplicateNodes : public QgsProcessingFeatureBasedAlgorithm | ||
{ | ||
|
||
public: | ||
|
||
QgsAlgorithmRemoveDuplicateNodes() = default; | ||
QString name() const override; | ||
QString displayName() const override; | ||
virtual QStringList tags() const override; | ||
QString group() const override; | ||
QString shortHelpString() const override; | ||
QgsAlgorithmRemoveDuplicateNodes *createInstance() const override SIP_FACTORY; | ||
void initParameters( const QVariantMap &configuration = QVariantMap() ) override; | ||
|
||
protected: | ||
QString outputName() const override; | ||
bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; | ||
QgsFeature processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback ) override; | ||
|
||
private: | ||
|
||
double mTolerance = 1.0; | ||
bool mUseZValues = false; | ||
|
||
}; | ||
|
||
|
||
///@endcond PRIVATE | ||
|
||
#endif // QGSALGORITHMSIMPLIFY_H | ||
|
||
|
Oops, something went wrong.