Saving a network to a file

Save a cityseer prepared networkx graph to a file.

To save a graph or to visualise it from QGIS, convert it to a GeoDataFrame and save it using geopandas.

First, let’s create a simple OSM graph from a bounding box, using the same approach as before.

from shapely import geometry

from cityseer.tools import io

poly_wgs = geometry.box(
    -0.14115725966109327,
    51.509220662095714,
    -0.12676440185383622,
    51.51820111033659,
)
G = io.osm_graph_from_poly(poly_wgs)
print(G)
WARNING:cityseer.tools.io:Merging node 12450391665 into 25544116 due to identical x, y coords.
INFO:cityseer.tools.graphs:Generating interpolated edge geometries.
100%|██████████| 4040/4040 [00:00<00:00, 51675.10it/s]
INFO:cityseer.tools.io:Converting networkX graph to CRS code 32630.
INFO:cityseer.tools.io:Processing node x, y coordinates.
100%|██████████| 3735/3735 [00:00<00:00, 1023836.71it/s]
INFO:cityseer.tools.io:Processing edge geom coordinates, if present.
100%|██████████| 4040/4040 [00:00<00:00, 18823.10it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 3735/3735 [00:00<00:00, 24011.87it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 2222/2222 [00:00<00:00, 1494267.03it/s]
100%|██████████| 2222/2222 [00:00<00:00, 10737.09it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 1917/1917 [00:00<00:00, 67329.43it/s]
100%|██████████| 1427/1427 [00:00<00:00, 328049.98it/s]
INFO:cityseer.tools.graphs:Removing dangling nodes.
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 1687/1687 [00:00<00:00, 1271480.84it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1364/1364 [00:00<00:00, 1726321.86it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 1090/1090 [00:00<00:00, 302787.69it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1364/1364 [00:00<00:00, 301154.43it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1362/1362 [00:00<00:00, 1786875.84it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 1090/1090 [00:00<00:00, 33829.79it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1372/1372 [00:00<00:00, 337354.03it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1371/1371 [00:00<00:00, 1830168.93it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 1090/1090 [00:00<00:00, 115563.09it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1372/1372 [00:00<00:00, 507369.52it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1372/1372 [00:00<00:00, 1230664.05it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 1090/1090 [00:00<00:00, 88210.84it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1372/1372 [00:00<00:00, 460698.51it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 1090/1090 [00:00<00:00, 54305.19it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 1090/1090 [00:00<00:00, 324401.57it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1372/1372 [00:00<00:00, 531355.96it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 1090/1090 [00:00<00:00, 931687.66it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 1087/1087 [00:00<00:00, 57506.95it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 1087/1087 [00:00<00:00, 4431.35it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1269/1269 [00:00<00:00, 80188.20it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 1008/1008 [00:00<00:00, 747367.59it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 1003/1003 [00:00<00:00, 57710.01it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 1003/1003 [00:00<00:00, 25783.97it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1229/1229 [00:00<00:00, 244083.51it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 992/992 [00:00<00:00, 1064130.32it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 990/990 [00:00<00:00, 55910.50it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 990/990 [00:00<00:00, 8382.09it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1201/1201 [00:00<00:00, 281463.88it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 973/973 [00:00<00:00, 1138052.93it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 972/972 [00:00<00:00, 55574.90it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1198/1198 [00:00<00:00, 1657248.08it/s]
INFO:cityseer.tools.graphs:Snapping gapped endings.
100%|██████████| 972/972 [00:00<00:00, 16148.17it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 1237/1237 [00:00<00:00, 1212798.98it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 972/972 [00:00<00:00, 15660.01it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 1416/1416 [00:00<00:00, 462441.37it/s]
INFO:cityseer.tools.graphs:Removing dangling nodes.
100%|██████████| 1074/1074 [00:00<00:00, 671739.11it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 889/889 [00:00<00:00, 32969.95it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 984/984 [00:00<00:00, 1828619.91it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 642/642 [00:00<00:00, 11644.40it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 991/991 [00:00<00:00, 157977.85it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 642/642 [00:00<00:00, 57604.95it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 642/642 [00:00<00:00, 1640.42it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 758/758 [00:00<00:00, 42529.36it/s]
INFO:cityseer.tools.util:Creating edges STR tree.
100%|██████████| 715/715 [00:00<00:00, 1589256.68it/s]
INFO:cityseer.tools.graphs:Splitting opposing edges.
100%|██████████| 487/487 [00:00<00:00, 12877.48it/s]
INFO:cityseer.tools.graphs:Squashing opposing nodes
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 715/715 [00:00<00:00, 354357.48it/s]
INFO:cityseer.tools.util:Creating nodes STR tree
100%|██████████| 487/487 [00:00<00:00, 53568.65it/s]
INFO:cityseer.tools.graphs:Consolidating nodes.
100%|██████████| 487/487 [00:00<00:00, 2046.42it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 25.
100%|██████████| 638/638 [00:00<00:00, 103187.67it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 413/413 [00:00<00:00, 155735.64it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 50.
100%|██████████| 611/611 [00:00<00:00, 92858.89it/s]
INFO:cityseer.tools.graphs:Ironing edges.
100%|██████████| 605/605 [00:00<00:00, 21146.28it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 1.
100%|██████████| 605/605 [00:00<00:00, 599044.83it/s]
INFO:cityseer.tools.graphs:Removing dangling nodes.
100%|██████████| 395/395 [00:00<00:00, 908305.96it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
100%|██████████| 392/392 [00:00<00:00, 256060.92it/s]
MultiGraph with 384 nodes and 594 edges

Use the geopandas_from_nx function to convert the networkx dataset into a geopandas LineString GeoDataFrame.

streets_gpd = io.geopandas_from_nx(G)
streets_gpd.head()
INFO:cityseer.tools.io:Preparing node and edge arrays from networkX graph.
names routes highways levels is_tunnel is_bridge geom start_nd_key end_nd_key edge_idx
0 [beak street] [] [unclassified] [0] False False LINESTRING (698573.946 5710658.889, 698597.952... 108070 25473512 0
1 [beak street] [] [unclassified] [0] False False LINESTRING (698573.946 5710658.889, 698556.667... 108070 25473371 0
2 [kingly court] [] [pedestrian, footway] [0] True False LINESTRING (698573.946 5710658.889, 698573.05 ... 108070 5568839679 0
3 [upper john street] [] [unclassified] [0] False False LINESTRING (698573.946 5710658.889, 698575.964... 108070 25473286 0
4 [great marlborough street] [] [tertiary] [0] False False LINESTRING (698482.48 5710892.514, 698538.717 ... 9791491 21665965 0

Since this is now a geopandas GeoDataFrame, you can use it accordingly.

streets_gpd.plot()

geopandas can now be used to save the file to disk, it can then be accessed and edited from an application such as QGIS.

streets_gpd.to_file(
    "temp/save_streets_demo.gpkg",
    driver="GPKG",
)
INFO:pyogrio._io:Created 594 records