Skip to content

Commit 03e29d4

Browse files
committedNov 3, 2016
[processing] optimise singlepart to multipart algorithm
- keep z/m/curved geometries intact - rewrite loop to avoid the cost of nb. feature x unique values
1 parent a44ea22 commit 03e29d4

File tree

1 file changed

+28
-79
lines changed

1 file changed

+28
-79
lines changed
 

‎python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py

Lines changed: 28 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -65,94 +65,43 @@ def processAlgorithm(self, progress):
6565
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
6666
fieldName = self.getParameterValue(self.FIELD)
6767

68-
geomType = self.singleToMultiGeom(layer.wkbType())
68+
geomType = QgsWkbTypes.multiType(layer.wkbType())
6969

7070
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
7171
layer.fields().toList(), geomType, layer.crs())
7272

7373
inFeat = QgsFeature()
7474
outFeat = QgsFeature()
7575
inGeom = QgsGeometry()
76-
outGeom = QgsGeometry()
7776

7877
index = layer.fields().lookupField(fieldName)
79-
unique = vector.getUniqueValues(layer, index)
8078

79+
collection_geom = {}
80+
collection_attrs = {}
81+
82+
features = vector.features(layer)
8183
current = 0
84+
total = 100.0 / (len(features))
85+
8286
features = vector.features(layer)
83-
total = 100.0 / (len(features) * len(unique))
84-
if not len(unique) == layer.featureCount():
85-
for i in unique:
86-
multi_feature = []
87-
first = True
88-
features = vector.features(layer)
89-
for inFeat in features:
90-
atMap = inFeat.attributes()
91-
idVar = atMap[index]
92-
if str(idVar).strip() == str(i).strip():
93-
if first:
94-
attrs = atMap
95-
first = False
96-
inGeom = inFeat.geometry()
97-
vType = inGeom.type()
98-
feature_list = self.extractAsMulti(inGeom)
99-
multi_feature.extend(feature_list)
100-
101-
current += 1
102-
progress.setPercentage(int(current * total))
103-
104-
outFeat.setAttributes(attrs)
105-
outGeom = QgsGeometry(self.convertGeometry(multi_feature,
106-
vType))
107-
outFeat.setGeometry(outGeom)
108-
writer.addFeature(outFeat)
109-
110-
del writer
111-
else:
112-
raise GeoAlgorithmExecutionException(
113-
self.tr('At least two features must have same attribute '
114-
'value! Please choose another field...'))
115-
116-
def singleToMultiGeom(self, wkbType):
117-
try:
118-
if wkbType in (QgsWkbTypes.Point, QgsWkbTypes.MultiPoint,
119-
QgsWkbTypes.Point25D, QgsWkbTypes.MultiPoint25D):
120-
return QgsWkbTypes.MultiPoint
121-
elif wkbType in (QgsWkbTypes.LineString, QgsWkbTypes.MultiLineString,
122-
QgsWkbTypes.MultiLineString25D,
123-
QgsWkbTypes.LineString25D):
124-
125-
return QgsWkbTypes.MultiLineString
126-
elif wkbType in (QgsWkbTypes.Polygon, QgsWkbTypes.MultiPolygon,
127-
QgsWkbTypes.MultiPolygon25D, QgsWkbTypes.Polygon25D):
128-
129-
return QgsWkbTypes.MultiPolygon
130-
else:
131-
return QgsWkbTypes.Unknown
132-
except Exception:
133-
pass
134-
135-
def extractAsMulti(self, geom):
136-
if geom.type() == QgsWkbTypes.PointGeometry:
137-
if geom.isMultipart():
138-
return geom.asMultiPoint()
139-
else:
140-
return [geom.asPoint()]
141-
elif geom.type() == QgsWkbTypes.LineGeometry:
142-
if geom.isMultipart():
143-
return geom.asMultiPolyline()
144-
else:
145-
return [geom.asPolyline()]
146-
else:
147-
if geom.isMultipart():
148-
return geom.asMultiPolygon()
149-
else:
150-
return [geom.asPolygon()]
151-
152-
def convertGeometry(self, geom_list, vType):
153-
if vType == QgsWkbTypes.PointGeometry:
154-
return QgsGeometry().fromMultiPoint(geom_list)
155-
elif vType == QgsWkbTypes.LineGeometry:
156-
return QgsGeometry().fromMultiPolyline(geom_list)
157-
else:
158-
return QgsGeometry().fromMultiPolygon(geom_list)
87+
for inFeat in features:
88+
atMap = inFeat.attributes()
89+
idVar = atMap[index]
90+
key = str(idVar).strip()
91+
if not key in collection_geom:
92+
collection_geom[key] = []
93+
collection_attrs[key] = atMap
94+
95+
inGeom = inFeat.geometry()
96+
vType = inGeom.type()
97+
collection_geom[key].append(inGeom)
98+
99+
current += 1
100+
progress.setPercentage(int(current * total))
101+
102+
for key, geoms in collection_geom.items():
103+
outFeat.setAttributes(collection_attrs[key])
104+
outFeat.setGeometry(QgsGeometry.collectGeometry(geoms))
105+
writer.addFeature(outFeat)
106+
107+
del writer

0 commit comments

Comments
 (0)
Please sign in to comment.