Skip to content

Commit a2af3a9

Browse files
committedJul 6, 2017
Make concave hull alg more efficient
- remove temporary layers from context, delete them as soon as they are finished with - directly remove features via data provider, instead of selecting and using edit buffer - use native geometry methods for splitting to single features and removing rings
1 parent 70cc196 commit a2af3a9

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed
 

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

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def processAlgorithm(self, parameters, context, feedback):
8888
# Delaunay triangulation from input point layer
8989
feedback.setProgressText(self.tr('Creating Delaunay triangles...'))
9090
delone_triangles = processing.run("qgis:delaunaytriangulation", {'INPUT': parameters[ConcaveHull.INPUT], 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']
91-
delaunay_layer = QgsProcessingUtils.mapLayerFromString(delone_triangles, context)
91+
delaunay_layer = context.takeResultLayer(delone_triangles)
9292

9393
# Get max edge length from Delaunay triangles
9494
feedback.setProgressText(self.tr('Computing edges max length...'))
@@ -127,48 +127,45 @@ def processAlgorithm(self, parameters, context, feedback):
127127
i += 1
128128

129129
# Remove features
130-
delaunay_layer.selectByIds(ids)
131-
delaunay_layer.startEditing()
132-
delaunay_layer.deleteSelectedFeatures()
133-
delaunay_layer.commitChanges()
130+
delaunay_layer.dataProvider().deleteFeatures(ids)
134131

135132
# Dissolve all Delaunay triangles
136133
feedback.setProgressText(self.tr('Dissolving Delaunay triangles...'))
137-
dissolved = processing.run("native:dissolve", {'INPUT': delaunay_layer.id(), 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']
138-
dissolved_layer = QgsProcessingUtils.mapLayerFromString(dissolved, context)
134+
dissolved = processing.run("native:dissolve", {'INPUT': delaunay_layer, 'OUTPUT': 'memory:'}, feedback=feedback, context=context)['OUTPUT']
135+
dissolved_layer = context.takeResultLayer(dissolved)
139136

140137
# Save result
141138
feedback.setProgressText(self.tr('Saving data...'))
142139
feat = QgsFeature()
143140
dissolved_layer.getFeatures().nextFeature(feat)
144141

142+
# Not needed anymore, free up some resources
143+
del delaunay_layer
144+
del dissolved_layer
145+
145146
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
146147
layer.fields(), QgsWkbTypes.Polygon, layer.sourceCrs())
147148

148149
geom = feat.geometry()
149150
if no_multigeom and geom.isMultipart():
150151
# Only singlepart geometries are allowed
151-
geom_list = geom.asMultiPolygon()
152-
for single_geom_list in geom_list:
152+
geom_list = geom.asGeometryCollection()
153+
for single_geom in geom_list:
153154
if feedback.isCanceled():
154155
break
155156

156157
single_feature = QgsFeature()
157-
single_geom = QgsGeometry.fromPolygon(single_geom_list)
158158
if not holes:
159159
# Delete holes
160-
deleted = True
161-
while deleted:
162-
deleted = single_geom.deleteRing(1)
160+
single_geom = single_geom.removeInteriorRings()
163161
single_feature.setGeometry(single_geom)
164162
sink.addFeature(single_feature, QgsFeatureSink.FastInsert)
165163
else:
166164
# Multipart geometries are allowed
167165
if not holes:
168166
# Delete holes
169-
deleted = True
170-
while deleted:
171-
deleted = geom.deleteRing(1)
167+
geom = geom.removeInteriorRings()
168+
feat.setGeometry(geom)
172169
sink.addFeature(feat, QgsFeatureSink.FastInsert)
173170

174171
return {self.OUTPUT: dest_id}

0 commit comments

Comments
 (0)
Please sign in to comment.