I try to make a script to find the shortest path between two bridges in a network. The goal is to get after each calculation a line that I insert as an entity in a predefined layer. For now I do well to make calculations but when I change the coordinates to make another calculation nothing appears even if I heard the new entity that is inserted in my table.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.networkanalysis import *
#building the graph**
vl = qgis.utils.iface.mapCanvas().currentLayer()
director = QgsLineVectorLayerDirector(vl, -1, '', '', '', 3)
properter = QgsDistanceArcProperter()
director.addProperter(properter)
crs = qgis.utils.iface.mapCanvas().mapRenderer().destinationCrs()
builder = QgsGraphBuilder(crs)
#coordinates of the Start point and endPoint**
pStart = QgsPoint(4.820590,45.838684)
pStop = QgsPoint(4.822459,45.837933)
tiedPoints = director.makeGraph(builder, [pStart, pStop])
graph = builder.graph()
#Calculation of the shortest path**
tStart = tiedPoints[0]
tStop = tiedPoints[1]
idStart = graph.findVertex(tStart)
idStop = graph.findVertex(tStop)
(tree, cost) = QgsGraphAnalyzer.dijkstra(graph, idStart, 0)
if tree[idStop] == -1:
print "Path not found"
else:
p = []
curPos = idStop
while curPos != idStart:
pnt = graph.vertex(graph.arc(tree[curPos]).inVertex()).point()
p.append(pnt)
curPos = graph.arc(tree[curPos]).outVertex()
p.append(tStart)
# Object generated after the calculation a qgsRubberBand**
rb = QgsRubberBand(qgis.utils.iface.mapCanvas())
rb.setColor(Qt.red)
#I build here a polyline based on the points in the p[] array
geom = QgsGeometry.fromPolyline(p)
for pnt in p:
rb.addPoint(pnt)
# I add here my result in a memory layer called cable and i want to do it for every feature i get after transforming the qgsrubberband object
v_layer = None
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if layer.name() == 'cable':
v_layer = layer
if v_layer is None:
v_layer = QgsVectorLayer("LineString", "cable", "memory")
v_layer.addAttribute(QgsField("id", QVariant.String))
v_layer.addAttribute(QgsField("type", QVariant.String))
QgsMapLayerRegistry.instance().addMapLayers([v_layer])
pr = v_layer.dataProvider()
v_layer.startEditing()
seg = QgsFeature()
seg.setGeometry(geom)
pr.addFeatures( [seg] )
v_layer.commitChanges()
Answer
Your code is working for me without problem. I've try it in the QGIS python console.
When i run it with a first start and end point, i get the red line in the cable layer then i run the script with others start and end point and i get the yellow line added in the same layer.
and what i get in the attribute table (length and geom calculate with the field calculator)
I just remove the part of the code using QgsRubberBand as it was useless. The code I used:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.networkanalysis import *
#building the graph**
vl = qgis.utils.iface.mapCanvas().currentLayer()
director = QgsLineVectorLayerDirector(vl, -1, '', '', '', 3)
properter = QgsDistanceArcProperter()
director.addProperter(properter)
crs = qgis.utils.iface.mapCanvas().mapRenderer().destinationCrs()
builder = QgsGraphBuilder(crs)
#coordinates of the Start point and endPoint**
pStart = QgsPoint(-1.041,0.916)
pStop = QgsPoint(-0.813,0.152)
tiedPoints = director.makeGraph(builder, [pStart, pStop])
graph = builder.graph()
#Calculation of the shortest path**
tStart = tiedPoints[0]
tStop = tiedPoints[1]
idStart = graph.findVertex(tStart)
idStop = graph.findVertex(tStop)
(tree, cost) = QgsGraphAnalyzer.dijkstra(graph, idStart, 0)
if tree[idStop] == -1:
print "Path not found"
else:
p = []
curPos = idStop
while curPos != idStart:
pnt = graph.vertex(graph.arc(tree[curPos]).inVertex()).point()
p.append(pnt)
curPos = graph.arc(tree[curPos]).outVertex()
p.append(tStart)
#I build here a polyline based on the points in the p[] array
geom = QgsGeometry.fromPolyline(p)
# I add here my result in a memory layer called cable and i want to do it for every feature i get after transforming the qgsrubberband object
v_layer = None
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if layer.name() == 'cable':
v_layer = layer
if v_layer is None:
v_layer = QgsVectorLayer("LineString", "cable", "memory")
v_layer.addAttribute(QgsField("id", QVariant.String))
v_layer.addAttribute(QgsField("type", QVariant.String))
QgsMapLayerRegistry.instance().addMapLayers([v_layer])
pr = v_layer.dataProvider()
v_layer.startEditing()
seg = QgsFeature()
seg.setGeometry(geom)
pr.addFeatures( [seg] )
v_layer.commitChanges()
No comments:
Post a Comment