[processing] Add "Keep disjoint results separate" option to buffer

algorithm

If checked, then any disjoint parts in the buffer results will be
output as separate single-part features. This setting is designed
to expose a similar functionality as is available for the 'dissolve'
algorithm.

Sponsored by City of Canning
This commit is contained in:
Nyall Dawson 2023-03-08 14:51:45 +10:00
parent 3c1e4fe723
commit 4647cfccef
8 changed files with 395 additions and 9 deletions

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
gml:id="aFeatureCollection"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ buffer_dissolve_keep_disjoint.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml/3.2">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-1.6 -0.6</gml:lowerCorner><gml:upperCorner>6.6 9.6</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:featureMember>
<ogr:buffer_dissolve_keep_disjoint gml:id="buffer_dissolve_keep_disjoint.0">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-0.6 -0.6</gml:lowerCorner><gml:upperCorner>3.6 4.6</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_dissolve_keep_disjoint.geom.0"><gml:surfaceMember><gml:Polygon gml:id="buffer_dissolve_keep_disjoint.geom.0.0"><gml:exterior><gml:LinearRing><gml:posList>-0.570633909777092 -0.185410196624969 -0.485410196624968 -0.352671151375484 -0.352671151375484 -0.485410196624969 -0.185410196624968 -0.570633909777092 0.0 -0.6 1.0 -0.6 1.18541019662497 -0.570633909777092 1.35267115137548 -0.485410196624968 1.48541019662497 -0.352671151375484 1.57063390977709 -0.185410196624968 1.6 0.0 1.6 1.0 1.57063390977709 1.18541019662497 1.48541019662497 1.35267115137548 1.43808134800045 1.4 2.0 1.4 2.18541019662497 1.42936609022291 2.35267115137548 1.51458980337503 2.48541019662497 1.64732884862452 2.57063390977709 1.81458980337503 2.6 2.0 2.6 2.4 3.0 2.4 3.18541019662497 2.42936609022291 3.35267115137548 2.51458980337503 3.48541019662497 2.64732884862452 3.57063390977709 2.81458980337503 3.6 3.0 3.6 4.0 3.57063390977709 4.18541019662497 3.48541019662497 4.35267115137548 3.35267115137548 4.48541019662497 3.18541019662497 4.57063390977709 3.0 4.6 1.0 4.6 0.814589803375032 4.57063390977709 0.647328848624516 4.48541019662497 0.514589803375032 4.35267115137548 0.429366090222908 4.18541019662497 0.4 4.0 0.4 2.0 0.429366090222908 1.81458980337503 0.514589803375032 1.64732884862452 0.561918651999547 1.6 0.0 1.6 -0.185410196624968 1.57063390977709 -0.352671151375484 1.48541019662497 -0.485410196624968 1.35267115137548 -0.570633909777092 1.18541019662497 -0.6 1.0 -0.6 0.0 -0.570633909777092 -0.185410196624969</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>multipolys.0</ogr:fid>
<ogr:Bname>Test</ogr:Bname>
<ogr:Bintval>1</ogr:Bintval>
<ogr:Bfloatval>0.123</ogr:Bfloatval>
</ogr:buffer_dissolve_keep_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_dissolve_keep_disjoint gml:id="buffer_dissolve_keep_disjoint.1">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-1.6 6.4</gml:lowerCorner><gml:upperCorner>6.6 9.6</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_dissolve_keep_disjoint.geom.1"><gml:surfaceMember><gml:Polygon gml:id="buffer_dissolve_keep_disjoint.geom.1.0"><gml:exterior><gml:LinearRing><gml:posList>3.18541019662497 6.42936609022291 3.35267115137548 6.51458980337503 3.48541019662497 6.64732884862452 3.5 6.67596295000161 3.51458980337503 6.64732884862452 3.64732884862452 6.51458980337503 3.81458980337503 6.42936609022291 4.0 6.4 6.0 6.4 6.18541019662497 6.42936609022291 6.35267115137548 6.51458980337503 6.48541019662497 6.64732884862452 6.57063390977709 6.81458980337503 6.6 7.0 6.6 9.0 6.57063390977709 9.18541019662497 6.48541019662497 9.35267115137548 6.35267115137548 9.48541019662497 6.18541019662497 9.57063390977709 6.0 9.6 5.0 9.6 4.84470857293849 9.57955549577344 4.7 9.51961524227066 4.57573593128807 9.42426406871193 3.57573593128807 8.42426406871193 3.5037927124169 8.31659343276463 3.48541019662497 8.35267115137548 3.35267115137548 8.48541019662497 3.18541019662497 8.57063390977709 3.0 8.6 -1 8.6 -1.18541019662497 8.57063390977709 -1.35267115137548 8.48541019662497 -1.48541019662497 8.35267115137548 -1.57063390977709 8.18541019662497 -1.6 8.0 -1.6 7.0 -1.57063390977709 6.81458980337503 -1.48541019662497 6.64732884862452 -1.35267115137548 6.51458980337503 -1.18541019662497 6.42936609022291 -1 6.4 3.0 6.4 3.18541019662497 6.42936609022291</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>multipolys.0</ogr:fid>
<ogr:Bname>Test</ogr:Bname>
<ogr:Bintval>1</ogr:Bintval>
<ogr:Bfloatval>0.123</ogr:Bfloatval>
</ogr:buffer_dissolve_keep_disjoint>
</ogr:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,73 @@
<?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/3.2"
xmlns:gmlsf="http://www.opengis.net/gmlsf/2.0"
elementFormDefault="qualified"
version="1.0">
<xs:annotation>
<xs:appinfo source="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd">
<gmlsf:ComplianceLevel>0</gmlsf:ComplianceLevel>
</xs:appinfo>
</xs:annotation>
<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<xs:import namespace="http://www.opengis.net/gmlsf/2.0" schemaLocation="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="featureMember">
<xs:complexType>
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureMemberType">
<xs:sequence>
<xs:element ref="gml:AbstractFeature"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="buffer_dissolve_keep_disjoint" type="ogr:buffer_dissolve_keep_disjoint_Type" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="buffer_dissolve_keep_disjoint_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:MultiSurfacePropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> <!-- restricted to MultiPolygon --><!-- srsName="urn:ogc:def:crs:EPSG::4326" -->
<xs:element name="fid" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Bname" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Bintval" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Bfloatval" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:decimal">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
gml:id="aFeatureCollection"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ buffer_keep_disjoint.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml/3.2">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-2 -1</gml:lowerCorner><gml:upperCorner>5.11935388287542 6.02403819033747</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:featureMember>
<ogr:buffer_keep_disjoint gml:id="buffer_keep_disjoint.0">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-2 -1</gml:lowerCorner><gml:upperCorner>0 1</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint.geom.0"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint.geom.0.0"><gml:exterior><gml:LinearRing><gml:posList>0 1 -2 1 -2 -1 0 -1 0 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.1</ogr:fid>
</ogr:buffer_keep_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint gml:id="buffer_keep_disjoint.1">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0 3</gml:lowerCorner><gml:upperCorner>2.43187079079239 6.02403819033747</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint.geom.1"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint.geom.1.0"><gml:exterior><gml:LinearRing><gml:posList>2.0 4.01694792505525 2.43187079079239 4.02433033173546 2.39768775047441 6.02403819033747 0.982908479841009 5.999853929301 1 5 0 5 0 3 2 3 2.0 4.01694792505525</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.2</ogr:fid>
</ogr:buffer_keep_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint gml:id="buffer_keep_disjoint.2">
<ogr:fid>lines.3</ogr:fid>
</ogr:buffer_keep_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint gml:id="buffer_keep_disjoint.3">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0 1</gml:lowerCorner><gml:upperCorner>5.11935388287542 5.60102187972956</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint.geom.3"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint.geom.3.0"><gml:exterior><gml:LinearRing><gml:posList>3 1 3 2 3 3 3.04843535420162 3.00099796140389 3.04763268142401 2.97317197178012 5.04680109976601 2.91550365202026 5.11935388287542 5.43066679981296 3.94943547662952 5.46441444614698 3.94662081885636 5.60102187972956 1.94704520801505 5.55982265002092 1.9791837734759 4.0 1 4 1 3 0 3 0 1 3 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.4</ogr:fid>
</ogr:buffer_keep_disjoint>
</ogr:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,53 @@
<?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/3.2"
xmlns:gmlsf="http://www.opengis.net/gmlsf/2.0"
elementFormDefault="qualified"
version="1.0">
<xs:annotation>
<xs:appinfo source="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd">
<gmlsf:ComplianceLevel>0</gmlsf:ComplianceLevel>
</xs:appinfo>
</xs:annotation>
<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<xs:import namespace="http://www.opengis.net/gmlsf/2.0" schemaLocation="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="featureMember">
<xs:complexType>
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureMemberType">
<xs:sequence>
<xs:element ref="gml:AbstractFeature"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="buffer_keep_disjoint" type="ogr:buffer_keep_disjoint_Type" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="buffer_keep_disjoint_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:MultiSurfacePropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> <!-- restricted to MultiPolygon --><!-- srsName="urn:ogc:def:crs:EPSG::4326" -->
<xs:element name="fid" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
gml:id="aFeatureCollection"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ buffer_keep_disjoint_features_disjoint.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml/3.2">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-1.3 -1</gml:lowerCorner><gml:upperCorner>4.41964493645572 5.58660214933154</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:featureMember>
<ogr:buffer_keep_disjoint_features_disjoint gml:id="buffer_keep_disjoint_features_disjoint.0">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-1.3 -1</gml:lowerCorner><gml:upperCorner>-0.7 1.0</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint_features_disjoint.geom.0"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint_features_disjoint.geom.0.0"><gml:exterior><gml:LinearRing><gml:posList>-0.7 1.0 -1.3 1.0 -1.3 -1 -0.7 -1 -0.7 1.0</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.1</ogr:fid>
</ogr:buffer_keep_disjoint_features_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint_features_disjoint gml:id="buffer_keep_disjoint_features_disjoint.1">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0.7 3.0</gml:lowerCorner><gml:upperCorner>2.4199067266811 5.32414043982677</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint_features_disjoint.geom.1"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint_features_disjoint.geom.1.0"><gml:exterior><gml:LinearRing><gml:posList>1.3 4.70508437751658 2.4199067266811 4.72422808224617 2.4096518145857 5.32414043982677 0.994872543952303 5.2999561787903 1.0 5.0 0.7 5.0 0.7 3.0 1.3 3.0 1.3 4.70508437751658</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.2</ogr:fid>
</ogr:buffer_keep_disjoint_features_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint_features_disjoint gml:id="buffer_keep_disjoint_features_disjoint.2">
<ogr:fid>lines.3</ogr:fid>
</ogr:buffer_keep_disjoint_features_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint_features_disjoint gml:id="buffer_keep_disjoint_features_disjoint.3">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0.0 1.7</gml:lowerCorner><gml:upperCorner>3.2999363416262 5.58660214933154</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint_features_disjoint.geom.3"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint_features_disjoint.geom.3.0"><gml:exterior><gml:LinearRing><gml:posList>2.3 1.7 2.3 2.7 3.0 2.7 3 3 3.2999363416262 3.0061798844563 3.2467693550619 5.58660214933154 2.6468966718095 5.57424238041894 2.69375513204277 3.3 1.7 3.3 1.7 2.3 0.0 2.3 0.0 1.7 2.3 1.7</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.4</ogr:fid>
</ogr:buffer_keep_disjoint_features_disjoint>
</ogr:featureMember>
<ogr:featureMember>
<ogr:buffer_keep_disjoint_features_disjoint gml:id="buffer_keep_disjoint_features_disjoint.4">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>3.74734162784371 2.93568756393621</gml:lowerCorner><gml:upperCorner>4.41964493645572 5.46815120765688</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:MultiSurface srsName="urn:ogc:def:crs:EPSG::4326" gml:id="buffer_keep_disjoint_features_disjoint.geom.4"><gml:surfaceMember><gml:Polygon gml:id="buffer_keep_disjoint_features_disjoint.geom.4.0"><gml:exterior><gml:LinearRing><gml:posList>4.41964493645572 5.45085071172892 3.81989441095311 5.46815120765688 3.74734162784371 2.95298805986417 4.34709215334631 2.93568756393621 4.41964493645572 5.45085071172892</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></ogr:geometryProperty>
<ogr:fid>lines.4</ogr:fid>
</ogr:buffer_keep_disjoint_features_disjoint>
</ogr:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,53 @@
<?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/3.2"
xmlns:gmlsf="http://www.opengis.net/gmlsf/2.0"
elementFormDefault="qualified"
version="1.0">
<xs:annotation>
<xs:appinfo source="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd">
<gmlsf:ComplianceLevel>0</gmlsf:ComplianceLevel>
</xs:appinfo>
</xs:annotation>
<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<xs:import namespace="http://www.opengis.net/gmlsf/2.0" schemaLocation="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="featureMember">
<xs:complexType>
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureMemberType">
<xs:sequence>
<xs:element ref="gml:AbstractFeature"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="buffer_keep_disjoint_features_disjoint" type="ogr:buffer_keep_disjoint_features_disjoint_Type" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="buffer_keep_disjoint_features_disjoint_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:MultiSurfacePropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> <!-- restricted to MultiPolygon --><!-- srsName="urn:ogc:def:crs:EPSG::4326" -->
<xs:element name="fid" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View File

@ -70,3 +70,57 @@ tests:
gml_id: skip
geometry:
normalize: True
- algorithm: native:buffer
name: Buffer, dissolve with separate disjoint
params:
DISSOLVE: true
DISTANCE: 0.6
END_CAP_STYLE: 0
INPUT:
name: multipolys.gml
type: vector
JOIN_STYLE: 0
MITER_LIMIT: 2.0
SEGMENTS: 5
SEPARATE_DISJOINT: true
results:
OUTPUT:
name: expected/buffer_dissolve_keep_disjoint.gml
type: vector
- algorithm: native:buffer
name: Buffer, separate disjoint with disjoint results
params:
DISSOLVE: false
DISTANCE: 0.3
END_CAP_STYLE: 1
INPUT:
name: multilines.gml
type: vector
JOIN_STYLE: 1
MITER_LIMIT: 2.0
SEGMENTS: 5
SEPARATE_DISJOINT: true
results:
OUTPUT:
name: expected/buffer_keep_disjoint_features_disjoint.gml
type: vector
- algorithm: native:buffer
name: Buffer, separate disjoint with non-disjoint results
params:
DISSOLVE: false
DISTANCE: 1.0
END_CAP_STYLE: 1
INPUT:
name: multilines.gml
type: vector
JOIN_STYLE: 1
MITER_LIMIT: 2.0
SEGMENTS: 5
SEPARATE_DISJOINT: true
results:
OUTPUT:
name: expected/buffer_keep_disjoint.gml
type: vector

View File

@ -16,7 +16,6 @@
***************************************************************************/
#include "qgsalgorithmbuffer.h"
#include "qgswkbtypes.h"
#include "qgsvectorlayer.h"
///@cond PRIVATE
@ -63,6 +62,12 @@ void QgsBufferAlgorithm::initAlgorithm( const QVariantMap & )
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MITER_LIMIT" ), QObject::tr( "Miter limit" ), QgsProcessingParameterNumber::Double, 2, false, 1 ) );
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "DISSOLVE" ), QObject::tr( "Dissolve result" ), false ) );
auto keepDisjointParam = std::make_unique < QgsProcessingParameterBoolean >( QStringLiteral( "SEPARATE_DISJOINT" ), QObject::tr( "Keep disjoint results separate" ), false );
keepDisjointParam->setFlags( keepDisjointParam->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
keepDisjointParam->setHelp( QObject::tr( "If checked, then any disjoint parts in the buffer results will be output as separate single-part features." ) );
addParameter( keepDisjointParam.release() );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Buffered" ), QgsProcessing::TypeVectorPolygon, QVariant(), false, true, true ) );
}
@ -93,6 +98,7 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
// fixed parameters
const bool dissolve = parameterAsBoolean( parameters, QStringLiteral( "DISSOLVE" ), context );
const bool keepDisjointSeparate = parameterAsBoolean( parameters, QStringLiteral( "SEPARATE_DISJOINT" ), context );
const int segments = parameterAsInt( parameters, QStringLiteral( "SEGMENTS" ), context );
const Qgis::EndCapStyle endCapStyle = static_cast< Qgis::EndCapStyle >( 1 + parameterAsInt( parameters, QStringLiteral( "END_CAP_STYLE" ), context ) );
const Qgis::JoinStyle joinStyle = static_cast< Qgis::JoinStyle>( 1 + parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) );
@ -143,15 +149,35 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
QgsMessageLog::logMessage( QObject::tr( "Error calculating buffer for feature %1" ).arg( f.id() ), QObject::tr( "Processing" ), Qgis::MessageLevel::Warning );
}
if ( dissolve )
{
bufferedGeometriesForDissolve << outputGeometry;
}
else
{
outputGeometry.convertToMultiType();
out.setGeometry( outputGeometry );
if ( !keepDisjointSeparate )
{
out.setGeometry( outputGeometry );
if ( !sink->addFeature( out, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
}
else
{
for ( auto partIt = outputGeometry.const_parts_begin(); partIt != outputGeometry.const_parts_end(); ++partIt )
{
if ( const QgsAbstractGeometry *part = *partIt )
{
out.setGeometry( QgsGeometry( part->clone() ) );
if ( !sink->addFeature( out, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
}
}
}
}
}
if ( !dissolve )
else if ( !dissolve )
{
if ( !sink->addFeature( out, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
@ -166,10 +192,26 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
QgsGeometry finalGeometry = QgsGeometry::unaryUnion( bufferedGeometriesForDissolve );
finalGeometry.convertToMultiType();
QgsFeature f;
f.setGeometry( finalGeometry );
f.setAttributes( dissolveAttrs );
if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
if ( !keepDisjointSeparate )
{
f.setGeometry( finalGeometry );
if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
}
else
{
for ( auto partIt = finalGeometry.const_parts_begin(); partIt != finalGeometry.const_parts_end(); ++partIt )
{
if ( const QgsAbstractGeometry *part = *partIt )
{
f.setGeometry( QgsGeometry( part->clone() ) );
if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
}
}
}
}
QVariantMap outputs;
@ -186,6 +228,8 @@ QgsProcessingAlgorithm::Flags QgsBufferAlgorithm::flags() const
QgsProcessingAlgorithm::VectorProperties QgsBufferAlgorithm::sinkProperties( const QString &sink, const QVariantMap &parameters, QgsProcessingContext &context, const QMap<QString, QgsProcessingAlgorithm::VectorProperties> &sourceProperties ) const
{
const bool keepDisjointSeparate = parameterAsBoolean( parameters, QStringLiteral( "SEPARATE_DISJOINT" ), context );
QgsProcessingAlgorithm::VectorProperties result;
if ( sink == QLatin1String( "OUTPUT" ) )
{
@ -194,7 +238,7 @@ QgsProcessingAlgorithm::VectorProperties QgsBufferAlgorithm::sinkProperties( con
const VectorProperties inputProps = sourceProperties.value( QStringLiteral( "INPUT" ) );
result.fields = inputProps.fields;
result.crs = inputProps.crs;
result.wkbType = Qgis::WkbType::MultiPolygon;
result.wkbType = keepDisjointSeparate ? Qgis::WkbType::Polygon : Qgis::WkbType::MultiPolygon;
result.availability = Available;
return result;
}
@ -205,7 +249,7 @@ QgsProcessingAlgorithm::VectorProperties QgsBufferAlgorithm::sinkProperties( con
{
result.fields = source->fields();
result.crs = source->sourceCrs();
result.wkbType = Qgis::WkbType::MultiPolygon;
result.wkbType = keepDisjointSeparate ? Qgis::WkbType::Polygon : Qgis::WkbType::MultiPolygon;
result.availability = Available;
return result;
}