mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
[processing] optimise singlepart to multipart algorithm
- keep z/m/curved geometries intact - rewrite loop to avoid the cost of nb. feature x unique values
This commit is contained in:
parent
a44ea22880
commit
03e29d4f01
@ -65,7 +65,7 @@ class SinglePartsToMultiparts(GeoAlgorithm):
|
||||
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
|
||||
fieldName = self.getParameterValue(self.FIELD)
|
||||
|
||||
geomType = self.singleToMultiGeom(layer.wkbType())
|
||||
geomType = QgsWkbTypes.multiType(layer.wkbType())
|
||||
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
|
||||
layer.fields().toList(), geomType, layer.crs())
|
||||
@ -73,86 +73,35 @@ class SinglePartsToMultiparts(GeoAlgorithm):
|
||||
inFeat = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
inGeom = QgsGeometry()
|
||||
outGeom = QgsGeometry()
|
||||
|
||||
index = layer.fields().lookupField(fieldName)
|
||||
unique = vector.getUniqueValues(layer, index)
|
||||
|
||||
current = 0
|
||||
collection_geom = {}
|
||||
collection_attrs = {}
|
||||
|
||||
features = vector.features(layer)
|
||||
total = 100.0 / (len(features) * len(unique))
|
||||
if not len(unique) == layer.featureCount():
|
||||
for i in unique:
|
||||
multi_feature = []
|
||||
first = True
|
||||
current = 0
|
||||
total = 100.0 / (len(features))
|
||||
|
||||
features = vector.features(layer)
|
||||
for inFeat in features:
|
||||
atMap = inFeat.attributes()
|
||||
idVar = atMap[index]
|
||||
if str(idVar).strip() == str(i).strip():
|
||||
if first:
|
||||
attrs = atMap
|
||||
first = False
|
||||
key = str(idVar).strip()
|
||||
if not key in collection_geom:
|
||||
collection_geom[key] = []
|
||||
collection_attrs[key] = atMap
|
||||
|
||||
inGeom = inFeat.geometry()
|
||||
vType = inGeom.type()
|
||||
feature_list = self.extractAsMulti(inGeom)
|
||||
multi_feature.extend(feature_list)
|
||||
collection_geom[key].append(inGeom)
|
||||
|
||||
current += 1
|
||||
progress.setPercentage(int(current * total))
|
||||
|
||||
outFeat.setAttributes(attrs)
|
||||
outGeom = QgsGeometry(self.convertGeometry(multi_feature,
|
||||
vType))
|
||||
outFeat.setGeometry(outGeom)
|
||||
for key, geoms in collection_geom.items():
|
||||
outFeat.setAttributes(collection_attrs[key])
|
||||
outFeat.setGeometry(QgsGeometry.collectGeometry(geoms))
|
||||
writer.addFeature(outFeat)
|
||||
|
||||
del writer
|
||||
else:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('At least two features must have same attribute '
|
||||
'value! Please choose another field...'))
|
||||
|
||||
def singleToMultiGeom(self, wkbType):
|
||||
try:
|
||||
if wkbType in (QgsWkbTypes.Point, QgsWkbTypes.MultiPoint,
|
||||
QgsWkbTypes.Point25D, QgsWkbTypes.MultiPoint25D):
|
||||
return QgsWkbTypes.MultiPoint
|
||||
elif wkbType in (QgsWkbTypes.LineString, QgsWkbTypes.MultiLineString,
|
||||
QgsWkbTypes.MultiLineString25D,
|
||||
QgsWkbTypes.LineString25D):
|
||||
|
||||
return QgsWkbTypes.MultiLineString
|
||||
elif wkbType in (QgsWkbTypes.Polygon, QgsWkbTypes.MultiPolygon,
|
||||
QgsWkbTypes.MultiPolygon25D, QgsWkbTypes.Polygon25D):
|
||||
|
||||
return QgsWkbTypes.MultiPolygon
|
||||
else:
|
||||
return QgsWkbTypes.Unknown
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def extractAsMulti(self, geom):
|
||||
if geom.type() == QgsWkbTypes.PointGeometry:
|
||||
if geom.isMultipart():
|
||||
return geom.asMultiPoint()
|
||||
else:
|
||||
return [geom.asPoint()]
|
||||
elif geom.type() == QgsWkbTypes.LineGeometry:
|
||||
if geom.isMultipart():
|
||||
return geom.asMultiPolyline()
|
||||
else:
|
||||
return [geom.asPolyline()]
|
||||
else:
|
||||
if geom.isMultipart():
|
||||
return geom.asMultiPolygon()
|
||||
else:
|
||||
return [geom.asPolygon()]
|
||||
|
||||
def convertGeometry(self, geom_list, vType):
|
||||
if vType == QgsWkbTypes.PointGeometry:
|
||||
return QgsGeometry().fromMultiPoint(geom_list)
|
||||
elif vType == QgsWkbTypes.LineGeometry:
|
||||
return QgsGeometry().fromMultiPolyline(geom_list)
|
||||
else:
|
||||
return QgsGeometry().fromMultiPolygon(geom_list)
|
||||
|
Loading…
x
Reference in New Issue
Block a user