Generate a network
For more details on downloading for a boundary, see this example .
Assume we have the following network.
import osmnx as ox
from cityseer.tools import io, plot
# retrieve a boundary from OSM
bounds_gdf = ox.geocode_to_gdf(
"R1536593" , # OSM relation ID
by_osmid= True ,
)
# project
bounds_gdf = bounds_gdf.to_crs(3035 ) # projected CRS
# extract geom
bounds_geom = bounds_gdf.union_all().simplify(500 )
# extract network for geom
G_nx = io.osm_graph_from_poly(
bounds_geom,
poly_crs_code= 3035 , # set to your CRS
to_crs_code= 3035 , # output CRS
simplify= False , # set to True for automatic simplification
)
plot.plot_nx(G_nx, plot_geoms= True )
INFO:cityseer.tools.io:Converting networkX graph from EPSG code 4326 to EPSG code 3035.
INFO:cityseer.tools.io:Processing node x, y coordinates.
0%| | 0/20190 [00:00<?, ?it/s]100%|██████████| 20190/20190 [00:00<00:00, 556279.59it/s]
INFO:cityseer.tools.io:Processing edge geom coordinates, if present.
0%| | 0/22340 [00:00<?, ?it/s]100%|██████████| 22340/22340 [00:00<00:00, 1124926.48it/s]
INFO:cityseer.tools.graphs:Generating interpolated edge geometries.
0%| | 0/22340 [00:00<?, ?it/s] 46%|████▋ | 10370/22340 [00:00<00:00, 103694.66it/s] 93%|█████████▎| 20825/22340 [00:00<00:00, 104191.13it/s]100%|██████████| 22340/22340 [00:00<00:00, 103916.70it/s]
INFO:cityseer.tools.graphs:Removing filler nodes.
0%| | 0/20190 [00:00<?, ?it/s] 4%|▍ | 769/20190 [00:00<00:02, 7673.09it/s] 8%|▊ | 1537/20190 [00:00<00:02, 7099.94it/s] 11%|█ | 2250/20190 [00:00<00:02, 6629.48it/s] 14%|█▍ | 2917/20190 [00:00<00:02, 6174.46it/s] 18%|█▊ | 3543/20190 [00:00<00:02, 6200.47it/s] 21%|██ | 4272/20190 [00:00<00:02, 6503.04it/s] 25%|██▌ | 5143/20190 [00:00<00:02, 7190.74it/s] 29%|██▉ | 5868/20190 [00:00<00:02, 7119.83it/s] 33%|███▎ | 6598/20190 [00:00<00:01, 7167.52it/s] 37%|███▋ | 7401/20190 [00:01<00:01, 7412.78it/s] 41%|████ | 8285/20190 [00:01<00:01, 7837.32it/s] 47%|████▋ | 9467/20190 [00:01<00:01, 9031.53it/s] 52%|█████▏ | 10526/20190 [00:01<00:01, 9495.84it/s] 57%|█████▋ | 11527/20190 [00:01<00:00, 9645.78it/s] 63%|██████▎ | 12663/20190 [00:01<00:00, 10159.85it/s] 69%|██████▉ | 13981/20190 [00:01<00:00, 11064.50it/s] 76%|███████▌ | 15272/20190 [00:01<00:00, 11610.60it/s] 83%|████████▎ | 16816/20190 [00:01<00:00, 12746.15it/s] 90%|████████▉ | 18092/20190 [00:01<00:00, 11968.24it/s] 96%|█████████▌| 19299/20190 [00:02<00:00, 11545.02it/s]100%|██████████| 20190/20190 [00:02<00:00, 9341.66it/s]
INFO:cityseer.tools.plot:Preparing graph nodes
INFO:cityseer.tools.plot:Preparing graph edges
0%| | 0/8718 [00:00<?, ?it/s] 7%|▋ | 617/8718 [00:00<00:02, 3752.96it/s] 27%|██▋ | 2361/8718 [00:00<00:00, 10109.79it/s] 42%|████▏ | 3664/8718 [00:00<00:00, 11272.16it/s] 56%|█████▌ | 4900/8718 [00:00<00:00, 10734.10it/s] 69%|██████▉ | 6042/8718 [00:00<00:00, 9901.05it/s] 81%|████████ | 7082/8718 [00:00<00:00, 9288.63it/s] 92%|█████████▏| 8045/8718 [00:00<00:00, 8283.71it/s]100%|██████████| 8718/8718 [00:01<00:00, 8688.51it/s]
Convert to GeoPandas
You can now convert the network to a geopandas
GeoDataFrame
.
# convert to a LineString GeoDataFrame
edges_gdf = io.geopandas_from_nx(G_nx, crs= 3035 )
edges_gdf.head()
INFO:cityseer.tools.io:Preparing node and edge arrays from networkX graph.
0
LINESTRING (3686215.164 2665464.119, 3686209.1...
[rue de gireugne, rue francoise dolto]
[]
[tertiary]
[0]
False
False
448239596
10746741880
0
1
LINESTRING (3686586.641 2665354.037, 3686435.5...
[]
[]
[track]
[0]
False
False
10746741880
10746741876
0
2
LINESTRING (3686215.164 2665464.119, 3686216.1...
[rue de gireugne]
[]
[tertiary]
[0]
False
False
10746741880
1969279930
0
3
LINESTRING (3683478.127 2667452.761, 3683490.1...
[rue de chatellerault]
[d 925]
[secondary]
[0]
False
False
1563458310
1527199968
0
4
LINESTRING (3683926.884 2667717.073, 3683959.4...
[rue de chatellerault]
[d 925]
[secondary]
[0]
False
False
1527199968
9328420068
0
Save
It is then possible to save the GeoDataFrame
. Create a temp
folder or update your path accordingly:
from pathlib import Path
# create the directory if necessary
Path.mkdir(Path("temp" ), exist_ok= True )
edges_gdf.to_file("temp/output_file.gpkg" )
INFO:pyogrio._io:Created 8,718 records
The GPKG file can now be explored or modified in GIS software such as QGIS.
Reload
To reload, you can read the data with geopandas
.
import geopandas as gpd
in_edges_gdf = gpd.read_file("temp/output_file.gpkg" )
in_edges_gdf.head()
0
['rue de gireugne', 'rue francoise dolto']
[]
['tertiary']
[0]
False
False
448239596
10746741880
0
LINESTRING (3686215.164 2665464.119, 3686209.1...
1
[]
[]
['track']
[0]
False
False
10746741880
10746741876
0
LINESTRING (3686586.641 2665354.037, 3686435.5...
2
['rue de gireugne']
[]
['tertiary']
[0]
False
False
10746741880
1969279930
0
LINESTRING (3686215.164 2665464.119, 3686216.1...
3
['rue de chatellerault']
['d 925']
['secondary']
[0]
False
False
1563458310
1527199968
0
LINESTRING (3683478.127 2667452.761, 3683490.1...
4
['rue de chatellerault']
['d 925']
['secondary']
[0]
False
False
1527199968
9328420068
0
LINESTRING (3683926.884 2667717.073, 3683959.4...
Convert back to nx
Then use cityseer
to convert the LineString
GeoDataFrame
back into a networkx
graph.
in_G_nx = io.nx_from_generic_geopandas(in_edges_gdf)
plot.plot_nx(in_G_nx, plot_geoms= True )
0%| | 0/8718 [00:00<?, ?it/s] 8%|▊ | 659/8718 [00:00<00:01, 6587.16it/s] 15%|█▌ | 1318/8718 [00:00<00:01, 6483.41it/s] 23%|██▎ | 1989/8718 [00:00<00:01, 6583.74it/s] 30%|███ | 2648/8718 [00:00<00:00, 6517.38it/s] 38%|███▊ | 3308/8718 [00:00<00:00, 6545.63it/s] 46%|████▌ | 3985/8718 [00:00<00:00, 6620.08it/s] 53%|█████▎ | 4648/8718 [00:00<00:00, 6618.89it/s] 61%|██████ | 5327/8718 [00:00<00:00, 6670.68it/s] 69%|██████▉ | 5995/8718 [00:00<00:00, 5711.27it/s] 76%|███████▌ | 6590/8718 [00:01<00:00, 5271.53it/s] 82%|████████▏ | 7138/8718 [00:01<00:00, 4744.09it/s] 89%|████████▉ | 7791/8718 [00:01<00:00, 5192.62it/s] 97%|█████████▋| 8445/8718 [00:01<00:00, 5548.70it/s]100%|██████████| 8718/8718 [00:01<00:00, 5863.09it/s]
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 1.
0%| | 0/8717 [00:00<?, ?it/s]100%|██████████| 8717/8717 [00:00<00:00, 155091.55it/s]
INFO:cityseer.tools.plot:Preparing graph nodes
INFO:cityseer.tools.plot:Preparing graph edges
0%| | 0/8715 [00:00<?, ?it/s] 29%|██▉ | 2545/8715 [00:00<00:00, 25433.77it/s] 58%|█████▊ | 5089/8715 [00:00<00:00, 13810.38it/s] 77%|███████▋ | 6752/8715 [00:00<00:00, 10313.08it/s] 92%|█████████▏| 7978/8715 [00:00<00:00, 8679.72it/s] 100%|██████████| 8715/8715 [00:00<00:00, 9406.89it/s]