from future import annotations
import geopandas as gpd from osmnx import features
from cityseer.tools import io, graphs from cityseer.metrics import networks, layers
This example uses the momepy
bubenec.gpkg
GeoPandas GeoDataFrame as an example. Please download this file and place it in a locally accessible file. Update the filepaths in the next code block accordingly.
from pathlib import Path
import geopandas as gpd
from cityseer.tools import io, graphs
from cityseer.metrics import networks, layers
from osmnx import features
repo_path = Path.cwd()
if str (repo_path).endswith("examples" ):
repo_path = Path.cwd() / ".."
if not str (repo_path.resolve()).endswith("cityseer-examples" ):
raise ValueError (
"Please check your notebook working directory relative to your project and data paths."
)
bubenec_path = Path(repo_path / "temp/bubenec.gpkg" )
print ("data path:" , bubenec_path)
print ("path exists:" , bubenec_path.exists())
df_streets: gpd.GeoDataFrame = gpd.read_file(bubenec_path, layer= "streets" ) # type: ignore
nx_momepy = io.nx_from_generic_geopandas(df_streets)
INFO:cityseer.tools.graphs:Merging parallel edges within buffer of 1.
100%|██████████| 35/35 [00:00<00:00, 17268.63it/s]
data path: /Users/gareth/dev/benchmark-urbanism/cityseer-examples/examples/../temp/bubenec.gpkg
path exists: True
At this point the input GeoPandas file has been converted to a networkX
MultiGraph
with geom
attributes for the edges. This graph can now be fed to cityseer
graph
module methods if wanted. For running optimised network centrality or landuse accessibilities, use the io.network_structure_from_nx
method to prepare the necessary structures.
nodes_gdf, edges_gdf, network_structure = io.network_structure_from_nx(
nx_momepy, crs= df_streets.crs.to_epsg()
)
INFO:cityseer.tools.io:Preparing node and edge arrays from networkX graph.
100%|██████████| 29/29 [00:00<00:00, 14987.04it/s]
100%|██████████| 29/29 [00:00<00:00, 2427.94it/s]
The following block downloads some OSM data which will be used for demonstrating some landuse accessibility methods.
x1603585.64-y6464428.774
0
1.603586e+06
6.464429e+06
True
1
POINT (1603585.640 6464428.774)
x1603413.206-y6464228.73
1
1.603413e+06
6.464229e+06
True
1
POINT (1603413.206 6464228.730)
x1603268.502-y6464060.781
2
1.603269e+06
6.464061e+06
True
1
POINT (1603268.502 6464060.781)
x1603363.558-y6464031.885
3
1.603364e+06
6.464032e+06
True
1
POINT (1603363.558 6464031.885)
x1603607.303-y6464181.853
4
1.603607e+06
6.464182e+06
True
1
POINT (1603607.303 6464181.853)
x1603585.64-y6464428.774-x1603413.206-y6464228.73
0
0
1
0
x1603585.64-y6464428.774
x1603413.206-y6464228.73
264.103950
0.000000
1
-130.760729
-130.760729
-130.760729
LINESTRING (1603585.640 6464428.774, 1603413.2...
x1603585.64-y6464428.774-x1603561.74-y6464494.467
1
0
8
0
x1603585.64-y6464428.774
x1603561.74-y6464494.467
70.020202
8.483583
1
111.541453
103.057871
109.992304
LINESTRING (1603561.740 6464494.467, 1603564.6...
x1603585.64-y6464428.774-x1603650.45-y6464368.601
2
0
6
0
x1603585.64-y6464428.774
x1603650.45-y6464368.601
88.924305
19.246836
1
-42.077556
-55.845266
-42.875276
LINESTRING (1603585.640 6464428.774, 1603603.0...
data_gdf = features.features_from_point(
(50.1029248 , 14.4029967 ), tags= {"amenity" : ["pub" , "restaurant" ]}, dist= 400
)
data_gdf.to_crs(3857 , inplace= True )
data_gdf = data_gdf.loc["node" ]
data_gdf = data_gdf.reset_index(level= 0 , drop= True )
data_gdf.index = data_gdf.index.astype(str )
data_gdf = data_gdf[["amenity" , "geometry" ]]
print (data_gdf.head())
amenity geometry
0 restaurant POINT (1602992.986 6463522.177)
1 restaurant POINT (1602903.753 6463784.958)
2 restaurant POINT (1603489.527 6463552.391)
3 restaurant POINT (1602809.665 6464167.222)
4 restaurant POINT (1603027.863 6464060.660)
# compute metrics
nodes_gdf = networks.node_centrality_shortest(
network_structure, nodes_gdf, [250 , 500 , 1000 ]
)
nodes_gdf, data_gdf = layers.compute_accessibilities(
data_gdf,
landuse_column_label= "amenity" ,
accessibility_keys= ["restaurant" ],
nodes_gdf= nodes_gdf,
network_structure= network_structure,
distances= [100 , 200 , 400 ],
)
nodes_gdf.head()
INFO:cityseer.metrics.networks:Computing shortest path node centrality.
100%|██████████| 29/29 [00:01<00:00, 28.86it/s]
INFO:cityseer.metrics.layers:Computing land-use accessibility for: restaurant
100%|██████████| 29/29 [00:01<00:00, 28.87it/s]
x1603585.64-y6464428.774
0
1.603586e+06
6.464429e+06
True
1
POINT (1603585.640 6464428.774)
0.716697
2.050036
4.991603
0.0
...
0.105017
1.056299
6.454368
0.0
0.000000
0.0
0.000000
1.0
0.043205
314.179047
x1603413.206-y6464228.73
1
1.603413e+06
6.464229e+06
True
1
POINT (1603413.206 6464228.730)
0.121535
1.309901
5.305615
0.0
...
0.000000
0.089877
5.084879
1.0
0.134929
1.0
0.367327
2.0
0.660077
50.075100
x1603268.502-y6464060.781
2
1.603269e+06
6.464061e+06
True
1
POINT (1603268.502 6464060.781)
0.434456
1.921538
5.837987
0.0
...
0.036077
0.693734
4.369751
1.0
0.309082
1.0
0.555951
5.0
0.895136
29.353716
x1603363.558-y6464031.885
3
1.603364e+06
6.464032e+06
True
1
POINT (1603363.558 6464031.885)
0.390683
1.850008
6.036365
1.0
...
0.000000
0.676959
6.886633
0.0
0.000000
1.0
0.075615
2.0
0.354570
129.104904
x1603607.303-y6464181.853
4
1.603607e+06
6.464182e+06
True
1
POINT (1603607.303 6464181.853)
0.284579
1.452106
4.887573
1.0
...
0.000000
0.263284
3.326667
0.0
0.000000
0.0
0.000000
1.0
0.082232
249.821609
5 rows × 37 columns
# if using dual network
nx_dual = graphs.nx_to_dual(nx_momepy)
nodes_gdf_dual, _edges_gdf_dual, network_structure_dual = io.network_structure_from_nx(
nx_dual, df_streets.crs.to_epsg()
)
nodes_gdf_dual = networks.node_centrality_simplest(
network_structure_dual, nodes_gdf_dual, [500 ]
)
nodes_gdf_dual.head()
INFO:cityseer.tools.graphs:Converting graph to dual.
INFO:cityseer.tools.graphs:Preparing dual nodes
100%|██████████| 35/35 [00:00<00:00, 8927.85it/s]
INFO:cityseer.tools.graphs:Preparing dual edges (splitting and welding geoms)
100%|██████████| 35/35 [00:00<00:00, 397.32it/s]
INFO:cityseer.tools.io:Preparing node and edge arrays from networkX graph.
100%|██████████| 35/35 [00:00<00:00, 16494.45it/s]
100%|██████████| 35/35 [00:00<00:00, 1757.82it/s]
INFO:cityseer.metrics.networks:Computing simplest path node centrality.
100%|██████████| 35/35 [00:01<00:00, 34.94it/s]
x1603413.206-y6464228.73_x1603585.64-y6464428.774_k0
0
1.603499e+06
6.464329e+06
True
1
POINT (1603499.423 6464328.752)
x1603585.64-y6464428.774
x1603413.206-y6464228.73
0
18.0
11.511215
10.933968
29.632427
10.0
x1603561.74-y6464494.467_x1603585.64-y6464428.774_k0
1
1.603573e+06
6.464461e+06
True
1
POINT (1603572.785 6464461.339)
x1603585.64-y6464428.774
x1603561.74-y6464494.467
0
13.0
8.308631
7.956708
21.239941
11.0
x1603585.64-y6464428.774_x1603650.45-y6464368.601_k0
2
1.603619e+06
6.464400e+06
True
1
POINT (1603619.295 6464399.737)
x1603585.64-y6464428.774
x1603650.45-y6464368.601
0
13.0
8.324493
8.047422
21.000513
16.0
x1603413.206-y6464228.73_x1603607.303-y6464181.853_k0
3
1.603510e+06
6.464204e+06
True
1
POINT (1603510.094 6464204.494)
x1603413.206-y6464228.73
x1603607.303-y6464181.853
0
21.0
13.298367
12.854933
34.305897
10.0
x1603363.558-y6464031.885_x1603413.206-y6464228.73_k0
4
1.603388e+06
6.464130e+06
True
1
POINT (1603388.005 6464130.401)
x1603413.206-y6464228.73
x1603363.558-y6464031.885
0
24.0
15.826625
15.015126
38.361317
10.0