@@ -49,6 +49,7 @@ In this first example, we will construct a simple graph using the `networkx` lib
4949
5050``` python
5151import networkx as nx
52+ import matplotlib.pyplot as plt
5253
5354G = nx.Graph()
5455G
@@ -348,7 +349,7 @@ What is the path length and route from `e` to `a` using the directed graph?
348349<!-- #endregion -->
349350
350351<!-- #region editable=true slideshow={"slide_type": ""} -->
351- Data was obtained from
352+ Data was obtained from Digiroad
352353<!-- #endregion -->
353354
354355``` python editable=true slideshow={"slide_type": ""}
@@ -358,5 +359,147 @@ from contextily import add_basemap
358359```
359360
360361``` python editable=true slideshow={"slide_type": ""}
362+ fp = " data/digiroad_helsinki.gpkg"
363+ streets = gpd.read_file(fp)
364+ streets.head()
365+ ```
366+
367+ ``` python
368+ streets.plot();
369+ ```
370+
371+ The ` direction ` column includes information about the allowed direction of the traffic flow, i.e. whether the traffic is permitted in both directions or whether it is a oneway street. In this street network dataset the values are coded as shown in Table 8.1.
372+
373+
374+
375+ : _ ** Table 8.1** . The rules for directed graph in terms of permitted direction of traffic._
376+
377+ | Value | Direction of traffic flow |
378+ | -------| ---------------------------------------------------------------------------------------|
379+ | 2 | Traffic is permitted in both directions |
380+ | 3 | Traffic is permitted against the direction of digitalisation (end-node to start-node) |
381+ | 4 | Traffic is permitted in the direction of digitalisation (start-node to end-node) |
382+
383+ ``` python
384+ def gdf_to_directed_graph (gdf , direction = ' direction' , both_ways = 2 , against = 3 , along = 4 ):
385+ """ Creates a NetworkX MultiDiGraph from road network GeoDataFrame.
386+
387+ Parameters
388+ ----------
389+
390+ gdf : GeoDataFrame
391+ GeoDataFrame containing the road network data.
392+
393+ direction : str
394+ Name for column that contains information about the allowed driving directions
395+
396+ both_ways : int
397+ Value specifying that the road is drivable to both directions.
398+
399+ against : int
400+ Value specifying that the road is drivable against the digitizing direction.
401+
402+ along : int
403+ Value specifying that the road is drivable along the digitizing direction.
404+
405+ """
406+ import networkx as nx
407+
408+ # Create the NetworkX graph
409+ graph = nx.MultiDiGraph()
410+
411+ columns = list (gdf.columns)
412+
413+ # Generate edge dictionary
414+ for edge in gdf.itertuples():
415+ coords = edge.geometry.coords
416+
417+ # Get first and last coordinates (drop possible Z information)
418+ first, last = coords[0 ][:2 ], coords[- 1 ][:2 ]
419+
420+ # Edge attributes
421+ edge_attr = dict (edge._asdict())
422+
423+ # Create edges according the direction rules
424+ if edge_attr[direction] == both_ways:
425+
426+ # If road is bi-directional add it in both ways
427+ graph.add_edge(first, last, ** edge_attr)
428+ graph.add_edge(last, first, ** edge_attr)
429+
430+ elif edge_attr[direction] == along:
431+
432+ # Add the edge along digitization direction
433+ graph.add_edge(first, last, ** edge_attr)
434+
435+ elif edge_attr[direction] == against:
436+
437+ # Add the edge against digitization direction
438+ graph.add_edge(last, first, ** edge_attr)
439+
440+ # Generate node attributes
441+ node_attrs = {node: {" coords" : node, " x" : node[0 ], " y" : node[1 ]} for node in graph.nodes}
442+ nx.set_node_attributes(graph, node_attrs)
443+
444+ # Relabel the indices
445+ graph = nx.convert_node_labels_to_integers(graph)
446+
447+ # Add some useful attributes
448+ graph.graph[' crs' ] = gdf.crs
449+
450+ return graph
451+ ```
452+
453+ ``` python
454+ G = gdf_to_directed_graph(streets)
455+ ```
456+
457+ ``` python
458+ positions = {node: attrs[" coords" ] for node, attrs in G.nodes.data()}
459+ ```
460+
461+ ``` python
462+ edge_colors = [" blue" if attrs[" direction" ] == 2 else " red" for u, v, attrs in G.edges.data()]
463+ ```
464+
465+ ``` python
466+ fig, ax = plt.subplots(figsize = (10 ,10 ))
467+
468+ nx.draw(G,
469+ ax = ax,
470+ pos = positions,
471+ node_color = " black" ,
472+ node_size = 0.5 ,
473+ edge_color = edge_colors,
474+ arrows = False ,
475+ )
476+ ```
477+
478+ ``` python
479+ import osmnx as ox
480+ ```
481+
482+ ``` python
483+ nodes, edges = ox.graph_to_gdfs(G)
484+ ```
485+
486+ ``` python
487+ nodes.head()
488+ ```
489+
490+ ``` python
491+ edges.head()
492+ ```
493+
494+ As many Python libraries related to working with have been
495+
496+ ``` python
497+ import neatnet
498+
499+ streets_cleaned = neatnet.remove_interstitial_nodes(streets)
500+ streets_cleaned.shape
501+ ```
502+
503+ ``` python
361504
362505```
0 commit comments