Port processing Densify Geometries algorithm to use c++ densify

Rough benchmark using 50k geometry polygon shapefile

Before: 1m25s
After:  21s
This commit is contained in:
Nyall Dawson 2017-03-25 15:17:22 +10:00
parent 249c6fcb20
commit b90aa916e6
2 changed files with 5 additions and 47 deletions

View File

@ -132,7 +132,9 @@ qgis:deleteholes: >
An optional minimum area parameter allows removing only holes which are smaller than a specified area threshold. Leaving this parameter as 0.0 results in all holes being removed.
qgis:densifygeometries:
This algorithm takes a polygon or line layer and generaates a new one in which the geometries have a larger number of vertices than the original one.
This algorithm takes a polygon or line layer and generates a new one in which the geometries have a larger number of vertices than the original one.
If the geometries have z or m values present then these will be linearly interpolated at the added nodes.
The number of new vertices to add to each feature geometry is specified as an input parameter.

View File

@ -48,6 +48,7 @@ class DensifyGeometries(GeoAlgorithm):
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Densify geometries')
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')
self.tags = self.tr('add,vertices,points')
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'),
@ -74,54 +75,9 @@ class DensifyGeometries(GeoAlgorithm):
for current, f in enumerate(features):
feature = f
if feature.hasGeometry():
new_geometry = self.densifyGeometry(feature.geometry(), int(vertices),
isPolygon)
new_geometry = feature.geometry().densifyByCount(int(vertices))
feature.setGeometry(new_geometry)
writer.addFeature(feature)
feedback.setProgress(int(current * total))
del writer
def densifyGeometry(self, geometry, pointsNumber, isPolygon):
output = []
if isPolygon:
if geometry.isMultipart():
polygons = geometry.asMultiPolygon()
for poly in polygons:
p = []
for ring in poly:
p.append(self.densify(ring, pointsNumber))
output.append(p)
return QgsGeometry.fromMultiPolygon(output)
else:
rings = geometry.asPolygon()
for ring in rings:
output.append(self.densify(ring, pointsNumber))
return QgsGeometry.fromPolygon(output)
else:
if geometry.isMultipart():
lines = geometry.asMultiPolyline()
for points in lines:
output.append(self.densify(points, pointsNumber))
return QgsGeometry.fromMultiPolyline(output)
else:
points = geometry.asPolyline()
output = self.densify(points, pointsNumber)
return QgsGeometry.fromPolyline(output)
def densify(self, polyline, pointsNumber):
output = []
multiplier = 1.0 / float(pointsNumber + 1)
for i in range(len(polyline) - 1):
p1 = polyline[i]
p2 = polyline[i + 1]
output.append(p1)
for j in range(pointsNumber):
delta = multiplier * (j + 1)
x = p1.x() + delta * (p2.x() - p1.x())
y = p1.y() + delta * (p2.y() - p1.y())
output.append(QgsPoint(x, y))
if j + 1 == pointsNumber:
break
output.append(polyline[len(polyline) - 1])
return output