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%20Street%20Continuity%20from%20OSM%20Data%0A%0A%20%20%20%20Compute%20street%20continuity%20metrics%20from%20OpenStreetMap%20data.%20Continuity%20measures%20how%20far%20streets%20extend%20as%20continuous%20entities%20based%20on%20shared%20names%2C%20route%20numbers%2C%20or%20highway%20classifications.%0A%0A%20%20%20%20Continuity%20analysis%20operates%20directly%20on%20the%20%60networkx%60%20graph%20through%20the%20lower-level%20functional%20API%3B%20it%20is%20not%20wrapped%20by%20the%20higher-level%20%5B%60CityNetwork%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Ffundamentals%23citynetwork-api)%20class.%0A%0A%20%20%20%20Network%20data%20%C2%A9%20%5BOpenStreetMap%5D(https%3A%2F%2Fwww.openstreetmap.org%2Fcopyright)%20contributors%2C%20available%20under%20the%20Open%20Database%20Licence.%0A%20%20%20%20%22%22%22)%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%20Preparation%0A%20%20%20%20%22%22%22)%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%20Set%20the%20coordinates%20and%20buffer%20distances%20to%20your%20preferred%20extents.%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%20from%20cityseer.tools%20import%20io%0A%0A%20%20%20%20%23%20lng%2C%20lat%2C%20buffer_dist%2C%20plot_buffer%20%3D%20-1.7063649924889566%2C%2052.19277374082795%2C%201500%2C%201250%20%20%23%20stratford-upon-avon%0A%20%20%20%20lng%2C%20lat%2C%20buffer_dist%2C%20plot_buffer%20%3D%20(%0A%20%20%20%20%20%20%20%20-0.13039709427587876%2C%0A%20%20%20%20%20%20%20%2051.516434828344366%2C%0A%20%20%20%20%20%20%20%206000%2C%0A%20%20%20%20%20%20%20%205000%2C%0A%20%20%20%20)%20%20%23%20london%0A%20%20%20%20%23%20lng%2C%20lat%2C%20buffer_dist%2C%20plot_buffer%20%3D%2018.425702641104582%2C%20-33.9204746754594%2C%203000%2C%202500%20%20%23%20cape%20town%0A%20%20%20%20poly_wgs%2C%20_%20%3D%20io.buffered_point_poly(lng%2C%20lat%2C%20buffer_dist)%0A%20%20%20%20poly_utm%2C%20_%20%3D%20io.buffered_point_poly(lng%2C%20lat%2C%20buffer_dist%2C%20projected%3DTrue)%0A%20%20%20%20%23%20select%20extents%20for%20plotting%0A%20%20%20%20plot_bbox%20%3D%20poly_utm.centroid.buffer(plot_buffer).bounds%0A%20%20%20%20return%20io%2C%20plot_bbox%2C%20poly_wgs%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%20Loading%20data%20from%20OSM%0A%20%20%20%20%22%22%22)%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%20This%20example%20uses%20a%20custom%20OSM%20query%20that%20excludes%20footways%2C%20because%20the%20continuity%20analysis%20needs%20OSM%20ways%20carrying%20street%20name%20or%20route%20number%20information.%0A%0A%20%20%20%20Only%20basic%20cleaning%20is%20recommended%20for%20this%20form%20of%20analysis.%20Avoid%20consolidating%20nodes%2C%20since%20consolidation%20risks%20dropping%20%60highway%60%2C%20%60ref%60%2C%20or%20%60name%60%20attributes.%20Unlike%20closeness%20or%20betweenness%20measures%2C%20continuity%20is%20not%20particularly%20sensitive%20to%20topological%20distortions%2C%20so%20aggressive%20simplification%20brings%20little%20benefit.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(io%2C%20poly_wgs)%3A%0A%20%20%20%20query%20%3D%20%22%22%22%0A%20%20%20%20%5Bout%3Ajson%5D%3B%0A%20%20%20%20(%0A%20%20%20%20%20%20%20%20way%5B%22highway%22%5D%0A%20%20%20%20%20%20%20%20%5B%22area%22!%3D%22yes%22%5D%0A%20%20%20%20%20%20%20%20%5B%22highway%22!~%22footway%7Cpedestrian%7Csteps%7Cbus_guideway%7Cescape%7Craceway%7Cproposed%7Cplanned%7Cabandoned%7Cplatform%7Cconstruction%22%5D%0A%20%20%20%20%20%20%20%20%5B%22service%22!~%22parking_aisle%22%5D%0A%20%20%20%20%20%20%20%20%5B%22amenity%22!~%22charging_station%7Cparking%7Cfuel%7Cmotorcycle_parking%7Cparking_entrance%7Cparking_space%22%5D%0A%20%20%20%20%20%20%20%20%5B%22access%22!~%22private%7Ccustomers%22%5D%0A%20%20%20%20%20%20%20%20%5B%22indoor%22!%3D%22yes%22%5D%0A%20%20%20%20%20%20%20%20(poly%3A%22%7Bgeom_osm%7D%22)%3B%0A%20%20%20%20)%3B%0A%20%20%20%20out%20body%3B%0A%20%20%20%20%3E%3B%0A%20%20%20%20out%20qt%3B%0A%20%20%20%20%22%22%22%0A%20%20%20%20G_osm%20%3D%20io.osm_graph_from_poly(poly_wgs%2C%20custom_request%3Dquery%2C%20simplify%3DTrue)%0A%20%20%20%20return%20(G_osm%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%23%20Observe%20continuity%20metrics%0A%0A%20%20%20%20We%20can%20now%20run%20the%20continuity%20metrics.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(G_osm)%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20cityseer.metrics%20import%20observe%0A%20%20%20%20from%20cityseer.tools%20import%20plot%0A%0A%20%20%20%20print(%22Continuity%20by%20street%20names%22)%0A%20%20%20%20G_cont%2C%20NamesContReport%20%3D%20observe.street_continuity(G_osm%2C%20method%3D%22names%22)%0A%20%20%20%20%23%20methods%20can%20be%20%22names%22%2C%20%22routes%22%2C%20%22highways%22%0A%20%20%20%20NamesContReport.report_by_count(n_items%3D5)%0A%20%20%20%20NamesContReport.report_by_length(n_items%3D5)%0A%20%20%20%20print(%22Continuity%20by%20route%20numbers%22)%0A%20%20%20%20G_cont%2C%20RoutesContReport%20%3D%20observe.street_continuity(G_cont%2C%20method%3D%22routes%22)%0A%20%20%20%20RoutesContReport.report_by_count(n_items%3D5)%0A%20%20%20%20RoutesContReport.report_by_length(n_items%3D5)%0A%20%20%20%20print(%22Continuity%20by%20highway%20types%22)%0A%20%20%20%20G_cont%2C%20HwyContReport%20%3D%20observe.street_continuity(G_cont%2C%20method%3D%22highways%22)%0A%20%20%20%20HwyContReport.report_by_count(n_items%3D5)%0A%20%20%20%20HwyContReport.report_by_length(n_items%3D5)%0A%20%20%20%20print(%22Continuity%20by%20overlapping%20routes%20and%20names%20types%22)%0A%20%20%20%20G_cont%2C%20HybridContReport%20%3D%20observe.hybrid_street_continuity(G_cont)%0A%20%20%20%20HybridContReport.report_by_count(n_items%3D5)%0A%20%20%20%20HybridContReport.report_by_length(n_items%3D5)%0A%20%20%20%20return%20G_cont%2C%20plot%2C%20plt%0A%0A%0A%40app.cell%0Adef%20_(G_cont%2C%20plot%2C%20plot_bbox%2C%20plt)%3A%0A%20%20%20%20for%20method%2C%20shape_exp%2C%20descriptor%2C%20cmap%2C%20inverse%2C%20col_by_categ%20in%20zip(%0A%20%20%20%20%20%20%20%20%5B%22names%22%2C%20%22routes%22%2C%20%22highways%22%2C%20%22hybrid%22%5D%2C%20%20%23%0A%20%20%20%20%20%20%20%20%5B1%2C%200.75%2C%200.5%2C%201%5D%2C%20%20%23%0A%20%20%20%20%20%20%20%20%5B%22Street%20names%22%2C%20%22Routes%22%2C%20%22Road%20types%22%2C%20%22Hybrid%20routes%20%26%20names%22%5D%2C%20%20%23%0A%20%20%20%20%20%20%20%20%5B%22plasma%22%2C%20%22viridis%22%2C%20%22tab10%22%2C%20%22tab10%22%5D%2C%20%20%23%0A%20%20%20%20%20%20%20%20%5BFalse%2C%20False%2C%20True%2C%20False%5D%2C%20%20%23%0A%20%20%20%20%20%20%20%20%5BFalse%2C%20False%2C%20True%2C%20True%5D%2C%0A%20%20%20%20%20%20%20%20strict%3DFalse%2C%0A%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20print(f%22Plotting%20results%20for%20method%3A%20%7Bmethod%7D%22)%0A%20%20%20%20%20%20%20%20%23%20plot%0A%20%20%20%20%20%20%20%20bg_colour%20%3D%20%22%231d1d1d%22%0A%20%20%20%20%20%20%20%20fig%2C%20axes%20%3D%20plt.subplots(2%2C%201%2C%20dpi%3D150%2C%20figsize%3D(8%2C%2012)%2C%20facecolor%3Dbg_colour%2C%20constrained_layout%3DTrue)%0A%20%20%20%20%20%20%20%20fig.suptitle(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22OSM%20network%20plotted%20by%20%7Bdescriptor%7D%20continuity%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D%22small%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ha%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%23%20by%20count%0A%20%20%20%20%20%20%20%20plot.plot_nx_edges(%0A%20%20%20%20%20%20%20%20%20%20%20%20axes%5B0%5D%2C%20%20%23%20type%3A%20ignore%0A%20%20%20%20%20%20%20%20%20%20%20%20nx_multigraph%3DG_cont%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20edge_metrics_key%3Df%22%7Bmethod%7D_cont_by_count%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20bbox_extents%3Dplot_bbox%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20cmap_key%3Dcmap%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lw_min%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lw_max%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20edge_label_key%3Df%22%7Bmethod%7D_cont_by_label%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colour_by_categorical%3Dcol_by_categ%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20shape_exp%3Dshape_exp%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20face_colour%3Dbg_colour%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20invert_plot_order%3Dinverse%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20axes%5B0%5D.set_xlabel(f%22%7Bdescriptor%7D%20by%20count%22%2C%20fontsize%3D%22x-small%22)%20%20%23%20type%3A%20ignore%0A%20%20%20%20%20%20%20%20%23%20by%20length%0A%20%20%20%20%20%20%20%20plot.plot_nx_edges(%0A%20%20%20%20%20%20%20%20%20%20%20%20axes%5B1%5D%2C%20%20%23%20type%3A%20ignore%0A%20%20%20%20%20%20%20%20%20%20%20%20nx_multigraph%3DG_cont%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20edge_metrics_key%3Df%22%7Bmethod%7D_cont_by_length%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20bbox_extents%3Dplot_bbox%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20cmap_key%3Dcmap%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lw_min%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lw_max%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20edge_label_key%3Df%22%7Bmethod%7D_cont_by_label%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colour_by_categorical%3Dcol_by_categ%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20shape_exp%3Dshape_exp%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20face_colour%3Dbg_colour%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20invert_plot_order%3Dinverse%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20axes%5B1%5D.set_xlabel(f%22%7Bdescriptor%7D%20by%20length%20(metres)%22%2C%20fontsize%3D%22x-small%22)%20%20%23%20type%3A%20ignore%0A%20%20%20%20%20%20%20%20plt.show()%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%20Longer%20continuous%20routes%20(brighter%20colours)%20indicate%20streets%20that%20maintain%20their%20name%20or%20classification%20over%20greater%20distances%2C%20suggesting%20major%20through-routes.%20Fragmented%20streets%20(darker)%20are%20typically%20local%20or%20residential.%0A%20%20%20%20%22%22%22)%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%20compute%20street%20continuity%20metrics%20from%20OpenStreetMap%20data%20for%20London%2C%20using%20street%20names%2C%20route%20numbers%2C%20highway%20types%2C%20and%20a%20hybrid%20approach%20to%20measure%20how%20far%20streets%20extend%20as%20continuous%20entities.%20The%20analysis%20reveals%20the%20hierarchical%20structure%20of%20the%20road%20network%2C%20with%20major%20routes%20like%20the%20A4%20and%20A501%20achieving%20the%20longest%20continuous%20extents.%0A%0A%20%20%20%20**Next%20steps%3A**%20For%20continuity%20from%20Ordnance%20Survey%20data%2C%20see%20%5BOS%20Open%20Roads%20Continuity%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fcontinuity%2Fcontinuity-os-open).%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
3cb2a4fa81df9db5275653c032b8b293