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))
|
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
|
||||||
fieldName = self.getParameterValue(self.FIELD)
|
fieldName = self.getParameterValue(self.FIELD)
|
||||||
|
|
||||||
geomType = self.singleToMultiGeom(layer.wkbType())
|
geomType = QgsWkbTypes.multiType(layer.wkbType())
|
||||||
|
|
||||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
|
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
|
||||||
layer.fields().toList(), geomType, layer.crs())
|
layer.fields().toList(), geomType, layer.crs())
|
||||||
@ -73,86 +73,35 @@ class SinglePartsToMultiparts(GeoAlgorithm):
|
|||||||
inFeat = QgsFeature()
|
inFeat = QgsFeature()
|
||||||
outFeat = QgsFeature()
|
outFeat = QgsFeature()
|
||||||
inGeom = QgsGeometry()
|
inGeom = QgsGeometry()
|
||||||
outGeom = QgsGeometry()
|
|
||||||
|
|
||||||
index = layer.fields().lookupField(fieldName)
|
index = layer.fields().lookupField(fieldName)
|
||||||
unique = vector.getUniqueValues(layer, index)
|
|
||||||
|
|
||||||
current = 0
|
collection_geom = {}
|
||||||
|
collection_attrs = {}
|
||||||
|
|
||||||
features = vector.features(layer)
|
features = vector.features(layer)
|
||||||
total = 100.0 / (len(features) * len(unique))
|
current = 0
|
||||||
if not len(unique) == layer.featureCount():
|
total = 100.0 / (len(features))
|
||||||
for i in unique:
|
|
||||||
multi_feature = []
|
|
||||||
first = True
|
|
||||||
features = vector.features(layer)
|
features = vector.features(layer)
|
||||||
for inFeat in features:
|
for inFeat in features:
|
||||||
atMap = inFeat.attributes()
|
atMap = inFeat.attributes()
|
||||||
idVar = atMap[index]
|
idVar = atMap[index]
|
||||||
if str(idVar).strip() == str(i).strip():
|
key = str(idVar).strip()
|
||||||
if first:
|
if not key in collection_geom:
|
||||||
attrs = atMap
|
collection_geom[key] = []
|
||||||
first = False
|
collection_attrs[key] = atMap
|
||||||
|
|
||||||
inGeom = inFeat.geometry()
|
inGeom = inFeat.geometry()
|
||||||
vType = inGeom.type()
|
vType = inGeom.type()
|
||||||
feature_list = self.extractAsMulti(inGeom)
|
collection_geom[key].append(inGeom)
|
||||||
multi_feature.extend(feature_list)
|
|
||||||
|
|
||||||
current += 1
|
current += 1
|
||||||
progress.setPercentage(int(current * total))
|
progress.setPercentage(int(current * total))
|
||||||
|
|
||||||
outFeat.setAttributes(attrs)
|
for key, geoms in collection_geom.items():
|
||||||
outGeom = QgsGeometry(self.convertGeometry(multi_feature,
|
outFeat.setAttributes(collection_attrs[key])
|
||||||
vType))
|
outFeat.setGeometry(QgsGeometry.collectGeometry(geoms))
|
||||||
outFeat.setGeometry(outGeom)
|
|
||||||
writer.addFeature(outFeat)
|
writer.addFeature(outFeat)
|
||||||
|
|
||||||
del writer
|
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