import%20marimo%0A%0A__generated_with%20%3D%20%220.23.13%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Custom%20Network%20from%20a%20Streets%20Dataset%0A%0A%20%20%20%20Use%20%60geopandas%60%20to%20open%20a%20street%20network%20file%20and%20convert%20it%20to%20a%20%60networkx%60%20graph.%0A%0A%20%20%20%20If%20you%20have%20a%20street%20network%20file%20in%20a%20GeoPackage%2C%20shapefile%2C%20or%20similar%20format%2C%20then%20you%20can%20load%20this%20file%20and%20convert%20it%20to%20a%20%60networkx%60%20graph.%0A%0A%20%20%20%20The%20bundled%20datasets%20and%20their%20source%20attributions%20are%20documented%20on%20the%20%5Bdatasets%20page%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fdatasets).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20geopandas%20as%20gpd%0A%20%20%20%20from%20cityseer.tools%20import%20io%2C%20plot%0A%0A%20%20%20%20return%20gpd%2C%20io%2C%20plot%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Use%20%60geopandas%60%20to%20load%20the%20street%20network%20file.%20Check%20that%20your%20file%20path%20is%20correct!%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gpd)%3A%0A%20%20%20%20streets_gpd%20%3D%20gpd.read_file(%22..%2F..%2Fdata%2Fmadrid_streets%2Fstreet_network.gpkg%22)%0A%20%20%20%20streets_gpd.head()%0A%20%20%20%20return%20(streets_gpd%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Take%20note%20of%20your%20data's%20CRS.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(streets_gpd)%3A%0A%20%20%20%20epsg_code%20%3D%20streets_gpd.crs.to_epsg()%0A%20%20%20%20print(epsg_code)%0A%20%20%20%20print(streets_gpd.crs.is_projected)%0A%20%20%20%20return%20(epsg_code%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20If%20your%20street%20network%20is%20not%20in%20a%20projected%20CRS%2C%20it%20is%20recommended%20to%20convert%20your%20dataset%20to%20a%20locally%20projected%20coordinate%20system.%20This%20can%20be%20done%20with%20the%20built-in%20%60to_crs%60%20method%20in%20%60geopandas%60.%20The%20EPSG%20code%20for%20the%20UTM%20zone%20can%20be%20found%20at%20%5Bepsg.io%5D(https%3A%2F%2Fepsg.io%2F).%0A%0A%20%20%20%20Alternatively%2C%20you%20can%20project%20the%20graph%20after%20creation.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(epsg_code%2C%20streets_gpd)%3A%0A%20%20%20%20%23%20shown%20as%20example%20-%20unnecessary%20step%20for%20current%20dataset%0A%20%20%20%20streets_gpd_1%20%3D%20streets_gpd.to_crs(epsg%3D25830)%0A%20%20%20%20print(epsg_code)%0A%20%20%20%20print(streets_gpd_1.crs.is_projected)%0A%20%20%20%20return%20(streets_gpd_1%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Take%20note%20of%20the%20geometry%20type.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(streets_gpd_1)%3A%0A%20%20%20%20streets_gpd_1.geometry.type.unique()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20If%20your%20data%20consists%20of%20%60MultiLineString%60%20geometries%2C%20then%20these%20should%20first%20be%20converted%20to%20unnested%20%60LineString%60%20geometries.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(streets_gpd_1)%3A%0A%20%20%20%20streets_gpd_2%20%3D%20streets_gpd_1.explode(ignore_index%3DTrue)%0A%20%20%20%20%23%20the%20source%20data%20contains%20a%20small%20number%20of%20exact%20duplicate%20geometries%0A%20%20%20%20streets_gpd_2%20%3D%20streets_gpd_2.drop_duplicates(subset%3D%22geometry%22)%0A%20%20%20%20streets_gpd_2.geometry.type.unique()%0A%20%20%20%20return%20(streets_gpd_2%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Use%20the%20%5B%60nx_from_generic_geopandas%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Ftools%2Fio%23nx-from-generic-geopandas)%20function%20to%20convert%20the%20%60geopandas%60%20LineStrings%20dataset%20to%20a%20%60networkx%60%20graph.%20This%20function%20will%20automatically%20create%20nodes%20and%20edges%20from%20the%20LineStrings%20in%20the%20dataset.%0A%0A%20%20%20%20The%20function%20expects%20that%20all%20features%20are%20%60LineString%60%20geometries%2C%20where%20the%20geometries%20represent%20individual%20street%20segments%20that%20meet%20at%20intersections.%20Street%20segments%20which%20share%20endpoints%20will%20be%20connected%20by%20a%20node%20in%20the%20graph.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(io%2C%20streets_gpd_2)%3A%0A%20%20%20%20G%20%3D%20io.nx_from_generic_geopandas(streets_gpd_2)%0A%20%20%20%20print(G)%0A%20%20%20%20return%20(G%2C)%0A%0A%0A%40app.cell%0Adef%20_(G%2C%20plot)%3A%0A%20%20%20%20plot.plot_nx(%0A%20%20%20%20%20%20%20%20G%2C%0A%20%20%20%20%20%20%20%20plot_geoms%3DTrue%2C%0A%20%20%20%20%20%20%20%20x_lim%3D(438500%2C%20438500%20%2B%203500)%2C%0A%20%20%20%20%20%20%20%20y_lim%3D(4472500%2C%204472500%20%2B%203500)%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20If%20your%20data%20is%20not%20in%20a%20projected%20CRS%20(and%20if%20you%20did%20not%20already%20reproject%20the%20%60GeoDataFrame%60%20before%20creating%20the%20graph)%2C%20then%20reproject%20your%20%60networkx%60%20graph%20to%20a%20locally%20projected%20coordinate%20system%20before%20doing%20further%20analysis.%0A%0A%20%20%20%20If%20the%20data%20is%20currently%20in%20geographic%20longitudes%20and%20latitudes%20(WGS84%20%2F%204326)%20then%20the%20%5B%60nx_wgs_to_utm%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Ftools%2Fio%23nx-wgs-to-utm)%20function%20can%20be%20used%20to%20convert%20it%20to%20the%20local%20UTM%20projection.%20Alternatively%2C%20the%20%5Bnx_epsg_conversion%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Ftools%2Fio%23nx-epsg-conversion)%20function%20can%20be%20used%20to%20specify%20input%20and%20output%20CRS.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(G%2C%20io)%3A%0A%20%20%20%20%23%20shown%20as%20an%20example%20-%20unnecessary%20step%20for%20current%20dataset%0A%20%20%20%20G_utm%20%3D%20io.nx_epsg_conversion(G%2C%20to_crs_code%3D32630)%0A%20%20%20%20print(G_utm)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Conclusion%0A%0A%20%20%20%20This%20notebook%20demonstrated%20how%20to%20load%20a%20custom%20street%20network%20file%20(e.g.%20GeoPackage%20or%20shapefile)%20using%20%60geopandas%60%20and%20convert%20it%20to%20a%20%60cityseer%60-compatible%20%60networkx%60%20graph%20with%20%60nx_from_generic_geopandas%60.%20It%20covered%20handling%20MultiLineString%20geometries%20by%20exploding%20them%20to%20LineStrings%2C%20verifying%20the%20CRS%2C%20and%20optionally%20reprojecting%20the%20resulting%20graph.%0A%0A%20%20%20%20To%20continue%20into%20analysis%2C%20hand%20the%20prepared%20graph%20to%20the%20high-level%20API%20with%20%5B%60CityNetwork.from_nx%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fapi%2Fnetwork%23from_nx)%2C%20which%20builds%20the%20dual%20network%20and%20exposes%20the%20centrality%20and%20land-use%20methods.%0A%0A%20%20%20%20**Next%20steps%3A**%20To%20convert%20networks%20from%20other%20libraries%2C%20see%20%5Bosmnx%20conversion%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks%2Fosmnx-to-cityseer)%20or%20%5Bmomepy%20conversion%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks%2Fmomepy-to-cityseer).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
71f8a77137edef54a513c438b2c5aebc