Skip to content

Commit 18fc0c6

Browse files
committed
[processing] optimise multipart to singlepart algorithm
- simplify code - keep z/m/curved geometries intact - might be a bit faster
1 parent 5e3bef7 commit 18fc0c6

File tree

1 file changed

+12
-59
lines changed

1 file changed

+12
-59
lines changed

python/plugins/processing/algs/qgis/MultipartToSingleparts.py

Lines changed: 12 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from qgis.core import QgsFeature, QgsGeometry, QgsWkbTypes
3434

3535
from processing.core.GeoAlgorithm import GeoAlgorithm
36-
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
3736
from processing.core.parameters import ParameterVector
3837
from processing.core.outputs import OutputVector
3938
from processing.tools import dataobjects, vector
@@ -58,74 +57,28 @@ def defineCharacteristics(self):
5857

5958
def processAlgorithm(self, progress):
6059
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
61-
geomType = self.multiToSingleGeom(layer.wkbType())
60+
geomType = QgsWkbTypes.singleType(layer.wkbType())
6261

6362
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
6463
layer.fields().toList(), geomType, layer.crs())
6564

6665
features = vector.features(layer)
6766
total = 100.0 / len(features)
6867
for current, f in enumerate(features):
69-
outFeat = QgsFeature()
70-
attrs = f.attributes()
71-
outFeat.setAttributes(attrs)
72-
73-
inGeom = f.geometry()
74-
if inGeom:
75-
geometries = self.extractAsSingle(inGeom)
76-
77-
for g in geometries:
78-
outFeat.setGeometry(g)
79-
writer.addFeature(outFeat)
68+
input_geometry = f.geometry()
69+
if input_geometry:
70+
if input_geometry.isMultipart():
71+
for i in range(input_geometry.geometry().numGeometries()):
72+
singlepart_geometry = QgsGeometry(input_geometry.geometry().geometryN(i).clone())
73+
output_feature = f
74+
output_feature.setGeometry( singlepart_geometry )
75+
writer.addFeature(output_feature)
76+
else:
77+
writer.addFeature(f)
8078
else:
8179
#input feature with null geometry
82-
writer.addFeature(outFeat)
80+
writer.addFeature(f)
8381

8482
progress.setPercentage(int(current * total))
8583

8684
del writer
87-
88-
def multiToSingleGeom(self, wkbType):
89-
try:
90-
if wkbType in (QgsWkbTypes.Point, QgsWkbTypes.MultiPoint,
91-
QgsWkbTypes.Point25D, QgsWkbTypes.MultiPoint25D):
92-
return QgsWkbTypes.Point
93-
elif wkbType in (QgsWkbTypes.LineString, QgsWkbTypes.MultiLineString,
94-
QgsWkbTypes.MultiLineString25D,
95-
QgsWkbTypes.LineString25D):
96-
97-
return QgsWkbTypes.LineString
98-
elif wkbType in (QgsWkbTypes.Polygon, QgsWkbTypes.MultiPolygon,
99-
QgsWkbTypes.MultiPolygon25D, QgsWkbTypes.Polygon25D):
100-
101-
return QgsWkbTypes.Polygon
102-
else:
103-
return QgsWkbTypes.Unknown
104-
except Exception as err:
105-
raise GeoAlgorithmExecutionException(str(err))
106-
107-
def extractAsSingle(self, geom):
108-
multiGeom = QgsGeometry()
109-
geometries = []
110-
if geom.type() == QgsWkbTypes.PointGeometry:
111-
if geom.isMultipart():
112-
multiGeom = geom.asMultiPoint()
113-
for i in multiGeom:
114-
geometries.append(QgsGeometry().fromPoint(i))
115-
else:
116-
geometries.append(geom)
117-
elif geom.type() == QgsWkbTypes. LineGeometry:
118-
if geom.isMultipart():
119-
multiGeom = geom.asMultiPolyline()
120-
for i in multiGeom:
121-
geometries.append(QgsGeometry().fromPolyline(i))
122-
else:
123-
geometries.append(geom)
124-
elif geom.type() == QgsWkbTypes.PolygonGeometry:
125-
if geom.isMultipart():
126-
multiGeom = geom.asMultiPolygon()
127-
for i in multiGeom:
128-
geometries.append(QgsGeometry().fromPolygon(i))
129-
else:
130-
geometries.append(geom)
131-
return geometries

0 commit comments

Comments
 (0)