Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Definition of inputs and outputs
- #==================================
- ##GeoHealth=group
- ##points=vector
- ##network=vector
- ##speed_field=field network
- ##speed_default=number 70
- ##perpendicular_roads=output vector
- ##centroid_cell=output vector
- ##centroid_buffer=output vector
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- from qgis.core import *
- from qgis.gui import *
- from qgis.networkanalysis import *
- import qgis.utils
- from processing import runalg, runandload
- try :
- from processing.tools.vector import VectorWriter
- except ImportError:
- from processing.core.VectorWriter import VectorWriter #Old API Versions
- class ghAccessibility:
- def __init__(self, points, network, perpendicular_roads, centroid_cell, centroid_buffer):
- #Get objects
- #===============
- self.pointLayer = processing.getObject(points)
- self.pFeatures = processing.features(self.pointLayer)
- self.networkLayer = processing.getObject(network)
- self.perpendicular_roads = perpendicular_roads
- self.centroid_cell = centroid_cell
- self.centroidBuffer = centroid_buffer
- self.director = QgsLineVectorLayerDirector(self.networkLayer,-1,'','','',3)
- properter = QgsDistanceArcProperter()
- self.director.addProperter(properter)
- crs = self.networkLayer.crs()
- self.graphBuilder = QgsGraphBuilder(crs)
- self.graph = None
- self.checkLayerGeometry()
- gridCentroid = self.gridCentroid( )
- tiedPoints = self.makeGraph(gridCentroid)
- self.computeRouting(gridCentroid, tiedPoints)
- #self.bufferCentroidIntersection(gridCentroid)
- return
- """ check if layers geometry is valid
- :return error in case of invalid geometry
- """
- def checkLayerGeometry(self):
- progress.setText(u'Step 1 :Check geometry')
- pointLayerGeometryType = self.pointLayer.geometryType()
- if pointLayerGeometryType == QGis.Line or pointLayerGeometryType == QGis.Polygon :
- err = "error : Invalid geometry type for point layer (must be point)"
- print err
- raise Exception(err)
- networkLayerGeometryType = self.networkLayer.geometryType()
- if networkLayerGeometryType == QGis.Point or networkLayerGeometryType == QGis.Polygon :
- err = "error : Invalid geometry type for network layer (must be line)"
- print err
- raise Exception(err)
- """ compute the bouding box of the point layer. Then creates a grid and for each cell compute the centroid.
- :return temporary points layer
- """
- def gridCentroid(self):
- progress.setText(u'Step 2 :Create Grid & Grid Centroid')
- progress.setPercentage(0)
- pBoxBuffer = self.pointLayer.extent().buffer(10)
- xmin, xmax, ymin, ymax = pBoxBuffer.xMinimum(), pBoxBuffer.xMaximum(), pBoxBuffer.yMinimum(), pBoxBuffer.yMaximum()
- gridExtent = "{xMin},{xMax},{yMin},{yMax}".format(xMin=xmin, xMax=xmax, yMin=ymin, yMax=ymax)
- vectorgrid = runalg('qgis:vectorgrid', gridExtent , 20000, 20000, 0, None)
- progress.setPercentage(50)
- gridCentroid = runalg('saga:polygoncentroids', vectorgrid['OUTPUT'], False, None)
- if gridCentroid is None :
- err = "error : Saga must be installed"
- raise Exception(err)
- else:
- runandload('saga:polygoncentroids', vectorgrid['OUTPUT'], False, self.centroid_cell)
- progress.setPercentage(100)
- return gridCentroid['CENTROIDS']
- def makeGraph(self, gridCentroid) :
- progress.setText(u'Step 3 : Compute routing graph')
- routingPoints = []
- gridCentroidFeats = processing.features(processing.getObject(gridCentroid))
- for feat in gridCentroidFeats:
- routingPoints.append(feat.geometry().asPoint())
- progress.setPercentage(30)
- for feat in processing.features(self.pointLayer):
- routingPoints.append(feat.geometry().asPoint())
- progress.setPercentage(70)
- tiedPoints = self.director.makeGraph(self.graphBuilder, routingPoints)
- self.graph = self.graphBuilder.graph()
- progress.setPercentage(100)
- return tiedPoints
- """ compute for each grid point a buffer that expands until it intersects a health point. It is us to select the nearest points.
- :return health feature
- """
- def bufferCentroidIntersection(self, gridCentroidFeatGeom, centroidBufferWriter):
- defaultBuffer = 100.0
- centroidIntersect = False
- pFeatIntersect = []
- #until there is a valid intersection with the point layers and the points of the grid
- while centroidIntersect == False :
- bb = gridCentroidFeatGeom.buffer(defaultBuffer,5).boundingBox()
- request = QgsFeatureRequest().setFilterRect(bb)
- intersectedPointFeatures = self.pointLayer.getFeatures(request)
- #if an intersection is found the routing is computed
- firstFeat = True
- for intersectedFeat in intersectedPointFeatures:
- pFeatIntersect.append(intersectedFeat)
- centroidIntersect = True
- if firstFeat is True:
- fet = QgsFeature()
- fet.setGeometry(QgsGeometry.fromPolygon(gridCentroidFeatGeom.buffer(defaultBuffer,5).asPolygon()))
- centroidBufferWriter.addFeature(fet)
- firstFeat = False
- #in case of no intersection the size of the radius is increased
- defaultBuffer+= defaultBuffer
- return pFeatIntersect
- def computeRouting(self, gridCentroid, tiedPoints):
- progress.setText(u'Step 4 : Compute routing for each feature')
- progress.setPercentage(0)
- centroidBufferWriter = VectorWriter(self.centroidBuffer, None, [QgsField("id", QVariant.Int)], QGis.WKBPolygon, self.networkLayer.crs() )
- trajectoryWriter = VectorWriter(self.perpendicular_roads, None, [QgsField("id", QVariant.Int)], QGis.WKBLineString, self.networkLayer.crs() )
- gridCentroidFeats = processing.features(processing.getObject(gridCentroid))
- nFeat = len(gridCentroidFeats)
- i = 0
- for gridCentroidFeat in gridCentroidFeats:
- progress.setPercentage(int(100 * i / nFeat))
- i+=1
- gridCentroidFeatGeom = gridCentroidFeat.geometry()
- intersectedPointFeatures = self.bufferCentroidIntersection(gridCentroidFeatGeom, centroidBufferWriter)
- for feat in intersectedPointFeatures :
- from_point = gridCentroidFeat.geometry().asPoint()
- from_id = self.graph.findVertex(from_point)
- to_id = self.graph.findVertex(feat.geometry().asPoint())
- if from_id != -1:
- (tree, cost) = QgsGraphAnalyzer.dijkstra(self.graph, from_id, 0)
- if tree[to_id] == -1:
- print "Path not found"
- else:
- # collect all the vertices between the points
- route_points = []
- curPos = to_id
- while curPos != from_id:
- route_points.append(
- self.graph.vertex(self.graph.arc(tree[curPos]).inVertex()).point()
- )
- curPos = self.graph.arc(tree[curPos]).outVertex()
- route_points.append(from_point)
- trajectoryWriter.addFeature(route_points)
- else:
- #Do something ?
- pass
- del centroidBufferWriter
- del trajectoryWriter
- return
- ghAccessibility(points, network, perpendicular_roads, centroid_cell, centroid_buffer)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement