Skip to content

Commit

Permalink
[FEATURE] add Densify geometries tool to SEXTANTE
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent 13b4d7f commit 708b679
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 2 deletions.
133 changes: 133 additions & 0 deletions python/plugins/sextante/ftools/DensifyGeometries.py
@@ -0,0 +1,133 @@
import os.path

from PyQt4 import QtGui
from PyQt4.QtCore import *

from qgis.core import *

from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.core.QGisLayers import QGisLayers
from sextante.core.SextanteLog import SextanteLog

from sextante.parameters.ParameterVector import ParameterVector
from sextante.parameters.ParameterNumber import ParameterNumber
from sextante.parameters.ParameterBoolean import ParameterBoolean

from sextante.outputs.OutputVector import OutputVector

class DensifyGeometries(GeoAlgorithm):

INPUT = "INPUT"
VERTICES = "VERTICES"
USE_SELECTION = "USE_SELECTION"
OUTPUT = "OUTPUT"

#def getIcon(self):
# return QtGui.QIcon(os.path.dirname(__file__) + "/icons/de.png")

def defineCharacteristics(self):
self.name = "Densify geometries"
self.group = "Geometry tools"

self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addParameter(ParameterNumber(self.VERTICES, "Vertices to add", 1, 10000000, 1))
self.addParameter(ParameterBoolean(self.USE_SELECTION, "Use only selected features", False))

self.addOutput(OutputVector(self.OUTPUT, "Simplified layer"))

def processAlgorithm(self, progress):
settings = QSettings()
encoding = settings.value( "/UI/encoding", "System" ).toString()

layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
useSelection = self.getParameterValue(self.USE_SELECTION)
vertices =self.getParameterValue(self.VERTICES)
output = self.getOutputValue(self.OUTPUT)

isPolygon = layer.geometryType() == QGis.Polygon

provider = layer.dataProvider()
layer.select(layer.pendingAllAttributesList())

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.pendingFields(),
layer.wkbType(), provider.crs())

current = 0
if useSelection:
total = 100.0 / float(len(layer.selectedFeatures()))
for f in selection:
featGeometry = QgsGeometry(f.geometry())
attrMap = f.attributeMap()
newGeometry = self.densifyGeometry(featGeometry, int(vertices), isPolygon)

feature = QgsFeature()
feature.setGeometry(newGeometry)
feature.setAttributeMap(attrMap)
writer.addFeature(feature)

current += 1
progress.setPercentage(int(current * total))
else:
total = 100.0 / float(provider.featureCount())
f = QgsFeature()
while layer.nextFeature(f):
featGeometry = QgsGeometry(f.geometry())
attrMap = f.attributeMap()
newGeometry = self.densifyGeometry(featGeometry, int(vertices), isPolygon)

feature = QgsFeature()
feature.setGeometry(newGeometry)
feature.setAttributeMap(attrMap)
writer.addFeature(feature)

current += 1
progress.setPercentage(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 = []
if pointsNumber != 1:
multiplier = 1.0 / float(pointsNumber + 1)
else:
multiplier = 1
for i in xrange(len(polyline) - 1):
p1 = polyline[i]
p2 = polyline[i + 1]
output.append(p1)
for j in xrange(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
6 changes: 4 additions & 2 deletions python/plugins/sextante/ftools/FToolsAlgorithmProvider.py
Expand Up @@ -24,6 +24,7 @@
from sextante.ftools.VoronoiPolygons import VoronoiPolygons
from sextante.ftools.LinesToPolygons import LinesToPolygons
from sextante.ftools.PolygonsToLines import PolygonsToLines
from sextante.ftools.DensifyGeometries import DensifyGeometries
from sextante.ftools.SimplifyGeometries import SimplifyGeometries
from sextante.ftools.ExportGeometryInfo import ExportGeometryInfo
from sextante.ftools.MultipartToSingleparts import MultipartToSingleparts
Expand Down Expand Up @@ -55,8 +56,9 @@ def __init__(self):
# data management
# geometry
ExportGeometryInfo(), Centroids(), Delaunay(), VoronoiPolygons(),
SimplifyGeometries(), MultipartToSingleparts(), SinglePartsToMultiparts(),
PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
SimplifyGeometries(), DensifyGeometries(), MultipartToSingleparts(),
SinglePartsToMultiparts(), PolygonsToLines(), LinesToPolygons(),
ExtractNodes(),
# geoprocessing
ConvexHull(), FixedDistanceBuffer(), VariableDistanceBuffer(),
Dissolve(), Difference(), Intersection(), Union(), Clip(),
Expand Down

0 comments on commit 708b679

Please sign in to comment.