Skip to content

Commit 6f5405a

Browse files
committedJun 28, 2018
[processing] Be more careful with output geometries added as a
result of clipping
1 parent 31330dd commit 6f5405a

File tree

6 files changed

+37
-24
lines changed

6 files changed

+37
-24
lines changed
 

‎python/plugins/processing/tests/testdata/expected/clip_lines_by_multipolygon.gfs

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<ogr:FeatureCollection
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation=""
4+
xsi:schemaLocation="http://ogr.maptools.org/ clip_lines_by_multipolygon.xsd"
55
xmlns:ogr="http://ogr.maptools.org/"
66
xmlns:gml="http://www.opengis.net/gml">
77
<gml:boundedBy>
88
<gml:Box>
9-
<gml:coord><gml:X>2</gml:X><gml:Y>-1</gml:Y></gml:coord>
9+
<gml:coord><gml:X>2</gml:X><gml:Y>1</gml:Y></gml:coord>
1010
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
1111
</gml:Box>
1212
</gml:boundedBy>
13-
13+
1414
<gml:featureMember>
1515
<ogr:clip_lines_by_multipolygon fid="lines.2">
1616
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>2,1 2,2</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>2,2 3,2</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>3,2 3,3</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
@@ -26,9 +26,4 @@
2626
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>7,2 8,2</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
2727
</ogr:clip_lines_by_multipolygon>
2828
</gml:featureMember>
29-
<gml:featureMember>
30-
<ogr:clip_lines_by_multipolygon fid="lines.5">
31-
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>8,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
32-
</ogr:clip_lines_by_multipolygon>
33-
</gml:featureMember>
3429
</ogr:FeatureCollection>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="clip_lines_by_multipolygon" type="ogr:clip_lines_by_multipolygon_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="clip_lines_by_multipolygon_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiLineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
</xs:sequence>
20+
</xs:extension>
21+
</xs:complexContent>
22+
</xs:complexType>
23+
</xs:schema>

‎src/analysis/processing/qgsalgorithmclip.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "qgsalgorithmclip.h"
1919
#include "qgsgeometryengine.h"
20+
#include "qgsoverlayutils.h"
2021

2122
///@cond PRIVATE
2223

@@ -78,6 +79,7 @@ QVariantMap QgsClipAlgorithm::processAlgorithm( const QVariantMap &parameters, Q
7879
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
7980

8081
QString dest;
82+
QgsWkbTypes::GeometryType sinkType = QgsWkbTypes::geometryType( featureSource->wkbType() );
8183
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, featureSource->fields(), QgsWkbTypes::multiType( featureSource->wkbType() ), featureSource->sourceCrs() ) );
8284

8385
if ( !sink )
@@ -184,6 +186,9 @@ QVariantMap QgsClipAlgorithm::processAlgorithm( const QVariantMap &parameters, Q
184186
newGeometry = inputFeature.geometry();
185187
}
186188

189+
if ( !QgsOverlayUtils::sanitizeIntersectionResult( newGeometry, sinkType ) )
190+
continue;
191+
187192
QgsFeature outputFeature;
188193
outputFeature.setGeometry( newGeometry );
189194
outputFeature.setAttributes( inputFeature.attributes() );

‎src/analysis/processing/qgsoverlayutils.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020

2121
///@cond PRIVATE
2222

23-
//! Makes sure that what came out from intersection of two geometries is good to be used in the output
24-
static bool sanitizeIntersectionResult( QgsGeometry &geom, QgsWkbTypes::GeometryType geometryType )
23+
bool QgsOverlayUtils::sanitizeIntersectionResult( QgsGeometry &geom, QgsWkbTypes::GeometryType geometryType )
2524
{
2625
if ( geom.isNull() )
2726
{

‎src/analysis/processing/qgsoverlayutils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define QGSOVERLAYUTILS_H
1818

1919
#include <QList>
20+
#include "qgswkbtypes.h"
2021

2122
#define SIP_NO_FILE
2223

@@ -27,6 +28,7 @@ class QgsFeatureSink;
2728
class QgsFields;
2829
class QgsProcessingContext;
2930
class QgsProcessingFeedback;
31+
class QgsGeometry;
3032

3133
namespace QgsOverlayUtils
3234
{
@@ -43,6 +45,9 @@ namespace QgsOverlayUtils
4345

4446
void intersection( const QgsFeatureSource &sourceA, const QgsFeatureSource &sourceB, QgsFeatureSink &sink, QgsProcessingContext &context, QgsProcessingFeedback *feedback, int &count, int totalCount, const QList<int> &fieldIndicesA, const QList<int> &fieldIndicesB );
4547

48+
//! Makes sure that what came out from intersection of two geometries is good to be used in the output
49+
bool sanitizeIntersectionResult( QgsGeometry &geom, QgsWkbTypes::GeometryType geometryType );
50+
4651
/**
4752
* Copies features from the source to the sink and resolves overlaps: for each pair of overlapping features A and B
4853
* it will produce:

0 commit comments

Comments
 (0)
Please sign in to comment.