Skip to content

Commit

Permalink
review Voronoi tool
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent 5ceedfd commit 7362994
Showing 1 changed file with 64 additions and 41 deletions.
105 changes: 64 additions & 41 deletions python/plugins/sextante/ftools/VoronoiPolygons.py
@@ -1,65 +1,95 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
import os.path
from sets import Set

from PyQt4 import QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *
from sextante.parameters.ParameterVector import ParameterVector

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

from sextante.parameters.ParameterVector import ParameterVector

from sextante.outputs.OutputVector import OutputVector
import voronoi
from sets import Set

from sextante.ftools import voronoi

class VoronoiPolygons(GeoAlgorithm):

INPUT = "INPUT"
OUTPUT = "OUTPUT"

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

def defineCharacteristics(self):
self.name = "Voronoi polygons"
self.group = "Geometry tools"

self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_POINT))

self.addOutput(OutputVector(self.OUTPUT, "Voronoi polygons"))

def processAlgorithm(self, progress):
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(VoronoiPolygons.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
writer = self.getOutputFromName(VoronoiPolygons.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
settings = QSettings()
encoding = settings.value( "/UI/encoding", "System" ).toString()

layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))

output = self.getOutputValue(self.OUTPUT)

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

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

inFeat = QgsFeature()
outFeat = QgsFeature()
extent = vlayer.extent()
extent = layer.extent()
height = extent.height()
width = extent.width()
c = voronoi.Context()
pts = []
ptDict = {}
ptNdx = -1
while vprovider.nextFeature(inFeat):
geom = QgsGeometry(inFeat.geometry())
point = geom.asPoint()
x = point.x()-extent.xMinimum()
y = point.y()-extent.yMinimum()
pts.append((x, y))
ptNdx +=1
ptDict[ptNdx] = inFeat.id()
#self.vlayer = None

while layer.nextFeature(inFeat):
geom = QgsGeometry(inFeat.geometry())
point = geom.asPoint()
x = point.x()-extent.xMinimum()
y = point.y()-extent.yMinimum()
pts.append((x, y))
ptNdx +=1
ptDict[ptNdx] = inFeat.id()

if len(pts) < 3:
return False
raise GeoAlgorithmExecutionException("Input file should contain at least 3 points. Choose another file and try again.")

uniqueSet = Set(item for item in pts)
ids = [pts.index(item) for item in uniqueSet]
sl = voronoi.SiteList([voronoi.Site(i[0], i[1], sitenum=j) for j, i in enumerate(uniqueSet)])
voronoi.voronoi(sl, c)
inFeat = QgsFeature()
nFeat = len(c.polygons)
nElement = 0

current = 0
total = 100.0 / float(len(c.polygons))

for site, edges in c.polygons.iteritems():
vprovider.featureAtId(ptDict[ids[site]], inFeat, True, allAttrs)
lines = self.clip_voronoi(edges, c, width, height, extent, 0, 0)
geom = QgsGeometry.fromMultiPoint(lines)
geom = QgsGeometry(geom.convexHull())
outFeat.setGeometry(geom)
outFeat.setAttributeMap(inFeat.attributeMap())
writer.addFeature(outFeat)
nElement += 1
progress.setPercentage(nElement/nFeat * 100)
del writer
return True
layer.featureAtId(ptDict[ids[site]], inFeat)
lines = self.clip_voronoi(edges, c, width, height, extent, 0, 0)

geom = QgsGeometry.fromMultiPoint(lines)
geom = QgsGeometry(geom.convexHull())
outFeat.setGeometry(geom)
outFeat.setAttributeMap(inFeat.attributeMap())
writer.addFeature(outFeat)

current += 1
progress.setPercentage(int(current * total))

del writer

def clip_voronoi(self, edges, c, width, height, extent, exX, exY):
""" Clip voronoi function based on code written for Inkscape
Expand Down Expand Up @@ -153,10 +183,3 @@ def clip_line(x1, y1, x2, y2, w, h, x, y):
if hasYMin:
lines.append(QgsPoint(width+extent.xMinimum()+exX, extent.yMinimum()-exY))
return lines

def defineCharacteristics(self):
self.name = "Voronoi polygons"
self.group = "Geometry tools"
self.addParameter(ParameterVector(VoronoiPolygons.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_POINT))
self.addOutput(OutputVector(VoronoiPolygons.OUTPUT, "Voronoi polygons"))

0 comments on commit 7362994

Please sign in to comment.