3

I've been trying to build a graph from a projected (EPSG 27700) clean (no pseudo-nodes) street network. I followed the tutorial here presented employing the QGIS 3.0 functions; now the network analysis tutorial is included in the analysis module of PyQgis.

This is the code:

layer = qgis.utils.iface.mapCanvas().currentLayer()

# undirected graph and distance strategy
graphDirector = QgsVectorLayerDirector(layer, -1, '', '', '', 3) 
strategy = QgsNetworkDistanceStrategy()
graphDirector.addStrategy(strategy)

startPoint = QgsPointXY(531389.8,181641.4)
builder = QgsGraphBuilder(lay.sourceCrs(), topologyTolerance = 0.0)
tiedPoints = graphDirector.makeGraph(builder, [startPoint])

graph = builder.graph()
graph.vertexCount()
graph.edgeCount()

The graph is apparently composed by 15358 nodes, even though I was expecting 3799. The edgeCount results in 0 edges instead. I also tried to computed the shortest path and no path was existing between different nodes (as expected, due to the abscence of edges).

Essentially, my question is: what I am doing wrong? Moreover, is the part where I tie the points to the network crucial for creating the graph? I don't understand why that would be relevant for obtaining the graph representation.

1 Answer 1

3

I can see a couple of issues with the code.

First:

graphDirector = QgsVectorLayerDirector(layer, -1, '', '', '', 3) 

I believe that should be

graphDirector = QgsVectorLayerDirector(layer, -1, '', '', '', 2) 

or (better - more explicit)

graphDirector = QgsVectorLayerDirector(layer, -1, '', '', '', QgsVectorLayerDirector.DirectionBoth) 

Note that QgsVectorLayerDirector.DirectionBoth has a value of 2, not 3. There's actually no Direction enum value corresponding to 3, so this will have unintended side effects.

strategy = QgsNetworkDistanceStrategy()
graphDirector.addStrategy(QgsNetworkDistanceStrategy())

Should be:

strategy = QgsNetworkDistanceStrategy()
graphDirector.addStrategy(strategy)

(although this probably won't affect the result)

4
  • Right, the misuse of the strategy variable was indeed a typo, while I was probably still using the old parameters for what concerns the direction. Edges are now created but their count still does not make too sense; graph.edgeCount() is equal to 33722 instead of 5297 features. May 8, 2018 at 14:24
  • 1
    The graph builder "explodes" input lines, creating an edge for every segment in input lines. Perhaps that explains the difference in counts?
    – ndawson
    May 8, 2018 at 18:22
  • yes, that could explain the explosion of lines. But I would be surprised if a plug-in explicitly designed for network analysis within a GIS environment was not able to manage multi-segments lines. Almost all kind of network measures would be affected by such an explosion of lines. May 22, 2018 at 13:38
  • 1
    It's not very efficient, but it's how it works at the moment - all edges in the graph consist only of a segment with a start and end node. This is done transparently, so multiline inputs are properly handled. You just need to make sure to union (dissolve) the resultant paths to get them back to standard linestrings.
    – ndawson
    May 22, 2018 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.