Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from pywps.Process.Process import WPSProcess
- from osgeo import ogr
- from decimal import Decimal
- import time
- import math
- class Process(WPSProcess):
- def __init__(self):
- WPSProcess.__init__(self,
- identifier = "poll_tin_reducer", # must be same, as filename
- title="Tin-Reducer",
- version = "0.1",
- storeSupported = "true",
- statusSupported = "true",
- abstract="reduces the points of a given triangulated irregular network by a variable factor",
- grassLocation =False)
- self.Output1=self.addLiteralOutput(identifier="output1", title="reduced TIN points as WKT or GMl")
- self.Output2=self.addLiteralOutput(identifier="output2", title="computation time (to compare different approaches)")
- self.Input1 = self.addLiteralInput(identifier="input1", title = "path of the shapefile to be processed", type = type(""))
- self.Input2 = self.addLiteralInput(identifier="input2", title = "minimal distance between points")
- def execute(self):
- #initialize clock
- startTime = time.clock()
- global lowDists
- lowDists = []
- #list for all points
- allPoints = []
- allPointsCleaned = []
- #list for each cell of the raster
- points00, points01, points10, points11 = [], [], [], []
- #list for the resulting points
- resultPoints = []
- #minimal distance to be allowed between points
- global minDist
- minDist = self.Input2.getValue()
- #open the shapefile
- shp = ogr.Open(self.Input1.getValue())
- if shp is None:
- return "failed to open shape"
- #get the first layer
- lyr = shp.GetLayer(0)
- lyr.ResetReading()
- #copy all points to the list
- self.pointsToList(lyr, allPoints, allPointsCleaned)
- #calculate the bbox of the dataset
- self.calcRange(lyr)
- #fill the raster cells with the corresponding points (5 % overlapp added)
- self.fillCells(allPointsCleaned, points00, points01, points10, points11)
- #calculate the distance between the points of each cell, copy points with enough distance to all others into the result list
- self.calcDist(points00, resultPoints)
- self.calcDist(points01, resultPoints)
- self.calcDist(points10, resultPoints)
- self.calcDist(points11, resultPoints)
- #create new point geoemtry from the resulting points
- pointGeom = ogr.Geometry(ogr.wkbMultiPoint)
- newPoint = ogr.Geometry(ogr.wkbPoint)
- for point in resultPoints:
- newPoint.AddPoint(point[0], point[1], point[2])
- pointGeom.AddGeometry(newPoint)
- wkt = pointGeom.ExportToWkt()
- #calculate elapsed time
- elapsedTime = time.clock() - startTime
- self.Output1.setValue(wkt)
- self.Output2.setValue(lowDists)
- return
- def pointsToList(self, lyr, allPoints, allPointsCleaned):
- #iterate over all features of the layer
- for feat in lyr:
- #get the polygon geometry
- geom = feat.GetGeometryRef()
- #extracting the exterior ring
- exRing = geom.GetGeometryRef(0)
- #get the exterior rings point count
- points = exRing.GetPointCount()
- #iterate over the points and put them in the list
- for p in range(points):
- x, y, z = exRing.GetPoint(p)
- point = x, y, z
- allPoints.append(point)
- #delete the last point of each triangle (we only need three point for our calculations)
- for i in range(3, len(allPoints), 4):
- allPointsCleaned.append(allPoints[i-3])
- allPointsCleaned.append(allPoints[i-1])
- allPointsCleaned.append(allPoints[i-1])
- return
- def calcRange(self, lyr):
- extent = lyr.GetExtent()
- boundary = str(extent).split(",")
- global bbox_xmin, bbox_xmax, bbox_ymin, bbox_ymax
- bbox_xmin = boundary[0]
- bbox_xmax = boundary[1]
- bbox_ymin = boundary[2]
- bbox_ymax = boundary[3]
- #delete useless characters
- bbox_xmin = bbox_xmin.replace("(","")
- bbox_ymax = bbox_ymax.replace(")","")
- def fillCells(self, inputPoints, points00, points01, points10, points11):
- #fill the cells with the corresponding points
- for point in inputPoints:
- pointString = str(point)
- pointString = pointString.replace("(", "")
- pointString = pointString.replace(")", "")
- x, y, z = pointString.split(",")
- x, y, z = float(x), float(y), float(z)
- pointAsFloat = x, y, z
- #cell00
- if(x < float(bbox_xmax) - ((float(bbox_xmax) - float(bbox_xmin))/2) and y < float(bbox_ymax) - ((float(bbox_ymax) - float(bbox_ymin))/2)):
- points00.append(pointAsFloat)
- #cell01
- elif(x > float(bbox_xmax) - ((float(bbox_xmax) - float(bbox_xmin))/2) and y < float(bbox_ymax) - ((float(bbox_ymax) - float(bbox_ymin))/2)):
- points01.append(pointAsFloat)
- #cell10
- elif(x < float(bbox_xmax) - ((float(bbox_xmax) - float(bbox_xmin))/2) and y > float(bbox_ymax) - ((float(bbox_ymax) - float(bbox_ymin))/2)):
- points10.append(pointAsFloat)
- #cell11
- elif(x > float(bbox_xmax) - ((float(bbox_xmax) - float(bbox_xmin))/2) and y > float(bbox_ymax) - ((float(bbox_ymax) - float(bbox_ymin))/2)):
- points10.append(pointAsFloat)
- return
- def calcDist(self, points, resultPoints):
- #boolean for marking a point for as valid or not valid
- valid = True
- #calculate the distance to all other points
- for pStart in points:
- valid = True
- for pAim in points:
- dist = ((pStart[0] - pAim[0])**2 + (pStart[1] - pAim[1])**2 + (pStart[2] - pAim[2])**2)
- #avoid comparision with point to itsself
- if dist < minDist and dist != 0.0:
- valid = False
- #lowDists.append(dist)
- if valid:
- #avoid duplicates
- if pStart not in resultPoints:
- resultPoints.append(pStart)
- return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement