Skip to content

Commit cdda581

Browse files
committed
[processing] Add test & adjust handling of negative distance value
for multi ring (constant) algorithm
1 parent 5f6dff0 commit cdda581

File tree

7 files changed

+316
-1
lines changed

7 files changed

+316
-1
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.

python/plugins/processing/tests/testdata/expected/multiring_negative_buffer.gml

+223
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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="multiring_negative_buffer" type="ogr:multiring_negative_buffer_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="multiring_negative_buffer_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="name" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:string">
22+
<xs:maxLength value="5"/>
23+
</xs:restriction>
24+
</xs:simpleType>
25+
</xs:element>
26+
<xs:element name="intval" nillable="true" minOccurs="0" maxOccurs="1">
27+
<xs:simpleType>
28+
<xs:restriction base="xs:integer">
29+
<xs:totalDigits value="10"/>
30+
</xs:restriction>
31+
</xs:simpleType>
32+
</xs:element>
33+
<xs:element name="floatval" nillable="true" minOccurs="0" maxOccurs="1">
34+
<xs:simpleType>
35+
<xs:restriction base="xs:decimal">
36+
</xs:restriction>
37+
</xs:simpleType>
38+
</xs:element>
39+
<xs:element name="ringId" nillable="true" minOccurs="0" maxOccurs="1">
40+
<xs:simpleType>
41+
<xs:restriction base="xs:integer">
42+
<xs:totalDigits value="10"/>
43+
</xs:restriction>
44+
</xs:simpleType>
45+
</xs:element>
46+
<xs:element name="distance" nillable="true" minOccurs="0" maxOccurs="1">
47+
<xs:simpleType>
48+
<xs:restriction base="xs:decimal">
49+
<xs:totalDigits value="21"/>
50+
<xs:fractionDigits value="6"/>
51+
</xs:restriction>
52+
</xs:simpleType>
53+
</xs:element>
54+
</xs:sequence>
55+
</xs:extension>
56+
</xs:complexContent>
57+
</xs:complexType>
58+
</xs:schema>

python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -5329,6 +5329,19 @@ tests:
53295329
name: expected/multiring_buffer.gml
53305330
type: vector
53315331

5332+
- algorithm: native:multiringconstantbuffer
5333+
name: Multi-ring negative buffer with polygons
5334+
params:
5335+
DISTANCE: -0.05
5336+
INPUT:
5337+
name: polys.gml
5338+
type: vector
5339+
RINGS: 3
5340+
results:
5341+
OUTPUT:
5342+
name: expected/multiring_negative_buffer.gml
5343+
type: vector
5344+
53325345
- algorithm: native:segmentizebymaxangle
53335346
name: Segmentize by angle
53345347
params:

src/analysis/processing/qgsalgorithmmultiringconstantbuffer.cpp

+22-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ QgsFeatureList QgsMultiRingConstantBufferAlgorithm::processFeature( const QgsFea
133133

134134
QgsFeatureList outputs;
135135

136+
// Set previous geometry to a zero-distance buffer of the original geometry,
137+
// this is needed for negative distance values
138+
previousGeometry = feature.geometry().buffer( 0.0, 40 );
139+
previousGeometry.convertToMultiType();
140+
136141
for ( int i = 1; i <= rings; ++i )
137142
{
138143
QgsFeature out;
@@ -145,7 +150,11 @@ QgsFeatureList QgsMultiRingConstantBufferAlgorithm::processFeature( const QgsFea
145150
continue;
146151
}
147152

148-
if ( i == 1 )
153+
if ( distance < 0.0 )
154+
{
155+
out.setGeometry( previousGeometry.symDifference( outputGeometry ) );
156+
}
157+
else if ( i == 1 )
149158
{
150159
out.setGeometry( outputGeometry );
151160
}
@@ -159,6 +168,18 @@ QgsFeatureList QgsMultiRingConstantBufferAlgorithm::processFeature( const QgsFea
159168
out.setAttributes( attrs );
160169
outputs.append( out );
161170
}
171+
172+
// For negative distance values, the last generated buffer geometry needs to be added
173+
if ( distance < 0.0 )
174+
{
175+
QgsFeature out;
176+
out.setGeometry( previousGeometry );
177+
QgsAttributes attrs = feature.attributes();
178+
attrs << 0 << 0.0;
179+
out.setAttributes( attrs );
180+
outputs.append( out );
181+
}
182+
162183
return outputs;
163184
}
164185

0 commit comments

Comments
 (0)