mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-05 00:04:40 -05:00
[FEATURE] New algorithm for 'collecting' geometries
This is basically the equivalent of the dissolve algorithm, but instead of a dissolving overlapping geometries the geometries are instead just collected together into a multipart geometry. It's designed to slot between the 'promote to multipart' algorithm (which performs no collection of geometries - it just converts singleparts to multiparts with 1 part) and the more complex all-encompassing 'aggregate' algorithm.
This commit is contained in:
parent
3484eb019c
commit
16c4f830b3
@ -231,7 +231,7 @@ def createTest(text):
|
||||
params[param.name()] = float(token)
|
||||
elif isinstance(param, QgsProcessingParameterEnum):
|
||||
params[param.name()] = int(token)
|
||||
else:
|
||||
elif token:
|
||||
if token[0] == '"':
|
||||
token = token[1:]
|
||||
if token[-1] == '"':
|
||||
|
||||
32
python/plugins/processing/tests/testdata/expected/collect_all.gfs
vendored
Normal file
32
python/plugins/processing/tests/testdata/expected/collect_all.gfs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<GMLFeatureClassList>
|
||||
<GMLFeatureClass>
|
||||
<Name>collect_all</Name>
|
||||
<ElementPath>collect_all</ElementPath>
|
||||
<!--MULTIPOLYGON-->
|
||||
<GeometryType>6</GeometryType>
|
||||
<SRSName>EPSG:4326</SRSName>
|
||||
<DatasetSpecificInfo>
|
||||
<FeatureCount>1</FeatureCount>
|
||||
<ExtentXMin>-1.00000</ExtentXMin>
|
||||
<ExtentXMax>9.16296</ExtentXMax>
|
||||
<ExtentYMin>-3.00000</ExtentYMin>
|
||||
<ExtentYMax>6.08868</ExtentYMax>
|
||||
</DatasetSpecificInfo>
|
||||
<PropertyDefn>
|
||||
<Name>name</Name>
|
||||
<ElementPath>name</ElementPath>
|
||||
<Type>String</Type>
|
||||
<Width>2</Width>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>intval</Name>
|
||||
<ElementPath>intval</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>floatval</Name>
|
||||
<ElementPath>floatval</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
22
python/plugins/processing/tests/testdata/expected/collect_all.gml
vendored
Normal file
22
python/plugins/processing/tests/testdata/expected/collect_all.gml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ogr:FeatureCollection
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation=""
|
||||
xmlns:ogr="http://ogr.maptools.org/"
|
||||
xmlns:gml="http://www.opengis.net/gml">
|
||||
<gml:boundedBy>
|
||||
<gml:Box>
|
||||
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
|
||||
<gml:coord><gml:X>9.162955854126682</gml:X><gml:Y>6.088675623800385</gml:Y></gml:coord>
|
||||
</gml:Box>
|
||||
</gml:boundedBy>
|
||||
|
||||
<gml:featureMember>
|
||||
<ogr:collect_all fid="polys.0">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6.24145873320538,-0.054510556621882 7.24145873320538,-1.05451055662188 5.24145873320538,-1.05451055662188 6.24145873320538,-0.054510556621882</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.44337811900192,4.42360844529751 2.44337811900192,5.42360844529751 3.44337811900192,5.42360844529751 3.44337811900192,4.42360844529751 2.44337811900192,4.42360844529751</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>4.17255278310941,4.82264875239923 4.17255278310941,5.82264875239923 5.17255278310941,5.82264875239923 5.17255278310941,4.82264875239923 4.17255278310941,4.82264875239923</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>8.16295585412668,2.73877159309021 8.16295585412668,3.73877159309021 9.16295585412668,3.73877159309021 9.16295585412668,2.73877159309021 8.16295585412668,2.73877159309021</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.62072936660269,5.08867562380038 2.62072936660269,6.08867562380038 3.62072936660269,6.08867562380038 3.62072936660269,5.08867562380038 2.62072936660269,5.08867562380038</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>aa</ogr:name>
|
||||
<ogr:intval>1</ogr:intval>
|
||||
<ogr:floatval>44.123456</ogr:floatval>
|
||||
</ogr:collect_all>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
||||
32
python/plugins/processing/tests/testdata/expected/collect_one_field.gfs
vendored
Normal file
32
python/plugins/processing/tests/testdata/expected/collect_one_field.gfs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<GMLFeatureClassList>
|
||||
<GMLFeatureClass>
|
||||
<Name>collect_one_field</Name>
|
||||
<ElementPath>collect_one_field</ElementPath>
|
||||
<!--MULTIPOLYGON-->
|
||||
<GeometryType>6</GeometryType>
|
||||
<SRSName>EPSG:4326</SRSName>
|
||||
<DatasetSpecificInfo>
|
||||
<FeatureCount>5</FeatureCount>
|
||||
<ExtentXMin>-1.00000</ExtentXMin>
|
||||
<ExtentXMax>9.16296</ExtentXMax>
|
||||
<ExtentYMin>-3.00000</ExtentYMin>
|
||||
<ExtentYMax>6.08868</ExtentYMax>
|
||||
</DatasetSpecificInfo>
|
||||
<PropertyDefn>
|
||||
<Name>name</Name>
|
||||
<ElementPath>name</ElementPath>
|
||||
<Type>String</Type>
|
||||
<Width>2</Width>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>intval</Name>
|
||||
<ElementPath>intval</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>floatval</Name>
|
||||
<ElementPath>floatval</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
50
python/plugins/processing/tests/testdata/expected/collect_one_field.gml
vendored
Normal file
50
python/plugins/processing/tests/testdata/expected/collect_one_field.gml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ogr:FeatureCollection
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation=""
|
||||
xmlns:ogr="http://ogr.maptools.org/"
|
||||
xmlns:gml="http://www.opengis.net/gml">
|
||||
<gml:boundedBy>
|
||||
<gml:Box>
|
||||
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
|
||||
<gml:coord><gml:X>9.162955854126682</gml:X><gml:Y>6.088675623800385</gml:Y></gml:coord>
|
||||
</gml:Box>
|
||||
</gml:boundedBy>
|
||||
|
||||
<gml:featureMember>
|
||||
<ogr:collect_one_field fid="polys.0">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>aa</ogr:name>
|
||||
<ogr:intval>1</ogr:intval>
|
||||
<ogr:floatval>44.123456</ogr:floatval>
|
||||
</ogr:collect_one_field>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_one_field fid="polys.1">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6.24145873320538,-0.054510556621882 7.24145873320538,-1.05451055662188 5.24145873320538,-1.05451055662188 6.24145873320538,-0.054510556621882</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>dd</ogr:name>
|
||||
<ogr:floatval>0</ogr:floatval>
|
||||
</ogr:collect_one_field>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_one_field fid="polys.2">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.44337811900192,4.42360844529751 2.44337811900192,5.42360844529751 3.44337811900192,5.42360844529751 3.44337811900192,4.42360844529751 2.44337811900192,4.42360844529751</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>4.17255278310941,4.82264875239923 4.17255278310941,5.82264875239923 5.17255278310941,5.82264875239923 5.17255278310941,4.82264875239923 4.17255278310941,4.82264875239923</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.62072936660269,5.08867562380038 2.62072936660269,6.08867562380038 3.62072936660269,6.08867562380038 3.62072936660269,5.08867562380038 2.62072936660269,5.08867562380038</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>bb</ogr:name>
|
||||
<ogr:intval>1</ogr:intval>
|
||||
<ogr:floatval>0.123</ogr:floatval>
|
||||
</ogr:collect_one_field>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_one_field fid="polys.7">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>8.16295585412668,2.73877159309021 8.16295585412668,3.73877159309021 9.16295585412668,3.73877159309021 9.16295585412668,2.73877159309021 8.16295585412668,2.73877159309021</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>cc</ogr:name>
|
||||
<ogr:floatval>0.123</ogr:floatval>
|
||||
</ogr:collect_one_field>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_one_field fid="polys.3">
|
||||
<ogr:intval>120</ogr:intval>
|
||||
<ogr:floatval>-100291.43213</ogr:floatval>
|
||||
</ogr:collect_one_field>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
||||
32
python/plugins/processing/tests/testdata/expected/collect_two_fields.gfs
vendored
Normal file
32
python/plugins/processing/tests/testdata/expected/collect_two_fields.gfs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<GMLFeatureClassList>
|
||||
<GMLFeatureClass>
|
||||
<Name>collect_two_fields</Name>
|
||||
<ElementPath>collect_two_fields</ElementPath>
|
||||
<!--MULTIPOLYGON-->
|
||||
<GeometryType>6</GeometryType>
|
||||
<SRSName>EPSG:4326</SRSName>
|
||||
<DatasetSpecificInfo>
|
||||
<FeatureCount>6</FeatureCount>
|
||||
<ExtentXMin>-1.00000</ExtentXMin>
|
||||
<ExtentXMax>9.16296</ExtentXMax>
|
||||
<ExtentYMin>-3.00000</ExtentYMin>
|
||||
<ExtentYMax>6.08868</ExtentYMax>
|
||||
</DatasetSpecificInfo>
|
||||
<PropertyDefn>
|
||||
<Name>name</Name>
|
||||
<ElementPath>name</ElementPath>
|
||||
<Type>String</Type>
|
||||
<Width>2</Width>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>intval</Name>
|
||||
<ElementPath>intval</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>floatval</Name>
|
||||
<ElementPath>floatval</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
58
python/plugins/processing/tests/testdata/expected/collect_two_fields.gml
vendored
Normal file
58
python/plugins/processing/tests/testdata/expected/collect_two_fields.gml
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ogr:FeatureCollection
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation=""
|
||||
xmlns:ogr="http://ogr.maptools.org/"
|
||||
xmlns:gml="http://www.opengis.net/gml">
|
||||
<gml:boundedBy>
|
||||
<gml:Box>
|
||||
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
|
||||
<gml:coord><gml:X>9.162955854126682</gml:X><gml:Y>6.088675623800385</gml:Y></gml:coord>
|
||||
</gml:Box>
|
||||
</gml:boundedBy>
|
||||
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.8">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.62072936660269,5.08867562380038 2.62072936660269,6.08867562380038 3.62072936660269,6.08867562380038 3.62072936660269,5.08867562380038 2.62072936660269,5.08867562380038</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>bb</ogr:name>
|
||||
<ogr:intval>2</ogr:intval>
|
||||
<ogr:floatval>0.123</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.0">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>aa</ogr:name>
|
||||
<ogr:intval>1</ogr:intval>
|
||||
<ogr:floatval>44.123456</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.7">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>8.16295585412668,2.73877159309021 8.16295585412668,3.73877159309021 9.16295585412668,3.73877159309021 9.16295585412668,2.73877159309021 8.16295585412668,2.73877159309021</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>cc</ogr:name>
|
||||
<ogr:floatval>0.123</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.1">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6.24145873320538,-0.054510556621882 7.24145873320538,-1.05451055662188 5.24145873320538,-1.05451055662188 6.24145873320538,-0.054510556621882</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>dd</ogr:name>
|
||||
<ogr:floatval>0</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.3">
|
||||
<ogr:intval>120</ogr:intval>
|
||||
<ogr:floatval>-100291.43213</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:collect_two_fields fid="polys.2">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.44337811900192,4.42360844529751 2.44337811900192,5.42360844529751 3.44337811900192,5.42360844529751 3.44337811900192,4.42360844529751 2.44337811900192,4.42360844529751</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>4.17255278310941,4.82264875239923 4.17255278310941,5.82264875239923 5.17255278310941,5.82264875239923 5.17255278310941,4.82264875239923 4.17255278310941,4.82264875239923</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>bb</ogr:name>
|
||||
<ogr:intval>1</ogr:intval>
|
||||
<ogr:floatval>0.123</ogr:floatval>
|
||||
</ogr:collect_two_fields>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
||||
@ -3437,3 +3437,42 @@ tests:
|
||||
OUTPUT:
|
||||
name: expected/promote_multipart_already_multi.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: native:collect
|
||||
name: Test (native:collect)
|
||||
params:
|
||||
INPUT:
|
||||
name: dissolve_polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/collect_all.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: native:collect
|
||||
name: Test (native:collect)
|
||||
params:
|
||||
FIELD:
|
||||
- name
|
||||
INPUT:
|
||||
name: dissolve_polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/collect_one_field.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: native:collect
|
||||
name: Test (native:collect)
|
||||
params:
|
||||
FIELD:
|
||||
- intval
|
||||
- name
|
||||
INPUT:
|
||||
name: dissolve_polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/collect_two_fields.gml
|
||||
type: vector
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
#include "qgsgeometryengine.h"
|
||||
#include "qgswkbtypes.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
QgsNativeAlgorithms::QgsNativeAlgorithms( QObject *parent )
|
||||
@ -62,6 +64,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
|
||||
addAlgorithm( new QgsCentroidAlgorithm() );
|
||||
addAlgorithm( new QgsClipAlgorithm() );
|
||||
addAlgorithm( new QgsDissolveAlgorithm() );
|
||||
addAlgorithm( new QgsCollectAlgorithm() );
|
||||
addAlgorithm( new QgsExtractByAttributeAlgorithm() );
|
||||
addAlgorithm( new QgsExtractByExpressionAlgorithm() );
|
||||
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
|
||||
@ -243,7 +246,8 @@ QgsDissolveAlgorithm *QgsDissolveAlgorithm::createInstance() const
|
||||
return new QgsDissolveAlgorithm();
|
||||
}
|
||||
|
||||
QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
QVariantMap QgsCollectorAlgorithm::processCollection( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback,
|
||||
std::function<QgsGeometry( const QList< QgsGeometry >& )> collector, int maxQueueLength )
|
||||
{
|
||||
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
|
||||
if ( !source )
|
||||
@ -289,10 +293,10 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
|
||||
if ( f.hasGeometry() && f.geometry() )
|
||||
{
|
||||
geomQueue.append( f.geometry() );
|
||||
if ( geomQueue.length() > 10000 )
|
||||
if ( maxQueueLength > 0 && geomQueue.length() > maxQueueLength )
|
||||
{
|
||||
// queue too long, combine it
|
||||
QgsGeometry tempOutputGeometry = QgsGeometry::unaryUnion( geomQueue );
|
||||
QgsGeometry tempOutputGeometry = collector( geomQueue );
|
||||
geomQueue.clear();
|
||||
geomQueue << tempOutputGeometry;
|
||||
}
|
||||
@ -302,7 +306,7 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
|
||||
current++;
|
||||
}
|
||||
|
||||
outputFeature.setGeometry( QgsGeometry::unaryUnion( geomQueue ) );
|
||||
outputFeature.setGeometry( collector( geomQueue ) );
|
||||
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );
|
||||
}
|
||||
else
|
||||
@ -355,7 +359,7 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
|
||||
QgsFeature outputFeature;
|
||||
if ( geometryHash.contains( attrIt.key() ) )
|
||||
{
|
||||
QgsGeometry geom = QgsGeometry::unaryUnion( geometryHash.value( attrIt.key() ) );
|
||||
QgsGeometry geom = collector( geometryHash.value( attrIt.key() ) );
|
||||
if ( !geom.isMultipart() )
|
||||
{
|
||||
geom.convertToMultiType();
|
||||
@ -375,6 +379,23 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
|
||||
return outputs;
|
||||
}
|
||||
|
||||
QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
{
|
||||
return processCollection( parameters, context, feedback, []( const QList< QgsGeometry > &parts )->QgsGeometry
|
||||
{
|
||||
return QgsGeometry::unaryUnion( parts );
|
||||
}, 10000 );
|
||||
}
|
||||
|
||||
QVariantMap QgsCollectAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
{
|
||||
return processCollection( parameters, context, feedback, []( const QList< QgsGeometry > &parts )->QgsGeometry
|
||||
{
|
||||
return QgsGeometry::collectGeometry( parts );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
void QgsClipAlgorithm::initAlgorithm( const QVariantMap & )
|
||||
{
|
||||
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
|
||||
@ -1289,6 +1310,31 @@ QgsFeature QgsPromoteToMultipartAlgorithm::processFeature( const QgsFeature &fea
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
void QgsCollectAlgorithm::initAlgorithm( const QVariantMap & )
|
||||
{
|
||||
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
|
||||
addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ), QObject::tr( "Unique ID fields" ), QVariant(),
|
||||
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true, true ) );
|
||||
|
||||
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Collected" ) ) );
|
||||
}
|
||||
|
||||
QString QgsCollectAlgorithm::shortHelpString() const
|
||||
{
|
||||
return QObject::tr( "This algorithm takes a vector layer and collects its geometries into new multipart geometries. One or more attributes can "
|
||||
"be specified to collect only geometries belonging to the same class (having the same value for the specified attributes), alternatively "
|
||||
"all geometries can be collected.\n\n"
|
||||
"All output geometries will be converted to multi geometries, even those with just a single part. "
|
||||
"This algorithm does not dissolve overlapping geometries - they will be collected together without modifying the shape of each geometry part." );
|
||||
}
|
||||
|
||||
QgsCollectAlgorithm *QgsCollectAlgorithm::createInstance() const
|
||||
{
|
||||
return new QgsCollectAlgorithm();
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
||||
|
||||
|
||||
@ -131,10 +131,21 @@ class QgsBufferAlgorithm : public QgsProcessingAlgorithm
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for dissolve/collect type algorithms.
|
||||
*/
|
||||
class QgsCollectorAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
protected:
|
||||
|
||||
QVariantMap processCollection( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback,
|
||||
std::function<QgsGeometry( const QList< QgsGeometry >& )> collector, int maxQueueLength = 0 );
|
||||
};
|
||||
|
||||
/**
|
||||
* Native dissolve algorithm.
|
||||
*/
|
||||
class QgsDissolveAlgorithm : public QgsProcessingAlgorithm
|
||||
class QgsDissolveAlgorithm : public QgsCollectorAlgorithm
|
||||
{
|
||||
|
||||
public:
|
||||
@ -155,6 +166,30 @@ class QgsDissolveAlgorithm : public QgsProcessingAlgorithm
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Native collect geometries algorithm.
|
||||
*/
|
||||
class QgsCollectAlgorithm : public QgsCollectorAlgorithm
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
QgsCollectAlgorithm() = default;
|
||||
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
|
||||
QString name() const override { return QStringLiteral( "collect" ); }
|
||||
QString displayName() const override { return QObject::tr( "Collect geometries" ); }
|
||||
virtual QStringList tags() const override { return QObject::tr( "union,combine,collect,multipart,parts,single" ).split( ',' ); }
|
||||
QString group() const override { return QObject::tr( "Vector geometry" ); }
|
||||
QString shortHelpString() const override;
|
||||
QgsCollectAlgorithm *createInstance() const override SIP_FACTORY;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Native extract by attribute algorithm.
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user