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%20Quickstart%0A%0A%20%20%20%20This%20page%20bridges%20the%20Python%20fundamentals%20from%20the%20%5BPython%20101%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fstart%2F1-notebooks)%20series%20with%20the%20practical%20%5BCityseer%20Recipes%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples).%20It%20introduces%20the%20core%20concepts%20and%20walks%20through%20a%20minimal%20end-to-end%20workflow.%0A%0A%20%20%20%20%3E%20**Tip%3A**%0A%20%20%20%20%3E%20If%20you%20are%20already%20familiar%20with%20%60cityseer%60%20and%20want%20to%20jump%20into%20specific%20analyses%2C%20head%20directly%20to%20the%20%5BRecipes%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples).%0A%0A%20%20%20%20%23%23%20Core%20Concepts%0A%0A%20%20%20%20%23%23%23%20The%20cityseer%20workflow%0A%0A%20%20%20%20The%20recommended%20entry%20point%20is%20the%20high-level%20%5B%60CityNetwork%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fapi%2Fnetwork)%20class%2C%20which%20wraps%20network%20preparation%20and%20metrics%20behind%20a%20lean%20interface%3A%0A%0A%20%20%20%201.%20**Build%20a%20network**%20with%20a%20constructor%20such%20as%20%60CityNetwork.from_osm%60%20(download%20from%20OpenStreetMap)%2C%20%60from_geopandas%60%20(a%20%60GeoDataFrame%60%20of%20LineStrings)%2C%20or%20%60from_nx%60%20(a%20%60networkx%60%20graph).%20Graph%20cleaning%20and%20dual-graph%20construction%20are%20handled%20automatically.%0A%20%20%20%202.%20**Compute%20metrics**%20%E2%80%94%20centrality%2C%20accessibility%2C%20mixed%20uses%2C%20or%20statistics.%20Methods%20return%20%60self%60%2C%20so%20calls%20can%20be%20chained.%0A%20%20%20%203.%20**Export%20results**%20%E2%80%94%20%60to_geopandas()%60%20returns%20a%20%60GeoDataFrame%60%20with%20the%20original%20street%20geometries%20and%20all%20computed%20columns%2C%20ready%20for%20plotting%20or%20saving.%0A%0A%20%20%20%20The%20lower-level%20API%20(%60cityseer.tools%60%2C%20%60cityseer.metrics%60)%20offers%20step-by-step%20control%20over%20graph%20cleaning%2C%20network%20construction%2C%20and%20metric%20computation.%20It%20is%20covered%20by%20the%20%5BNetwork%20Preparation%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks)%20recipes%20and%20is%20useful%20when%20integrating%20%60cityseer%60%20into%20an%20existing%20%60networkx%60%20pipeline.%0A%0A%20%20%20%20%23%23%23%20Primal%20vs.%20dual%20graphs%0A%0A%20%20%20%20By%20default%2C%20a%20street%20network%20is%20a%20**primal%20graph**%3A%20intersections%20are%20nodes%20and%20streets%20are%20edges.%20This%20is%20the%20representation%20provided%20by%20most%20data%20sources.%0A%0A%20%20%20%20%60cityseer%60%20can%20convert%20a%20primal%20graph%20into%20a%20**dual%20graph**%2C%20where%20the%20representation%20is%20inverted%3A%20streets%20become%20nodes%20and%20intersections%20become%20edges.%20Metrics%20are%20then%20expressed%20per%20street%20segment%20rather%20than%20per%20intersection%2C%20which%20is%20usually%20more%20intuitive%20for%20urban%20analysis%20because%20outputs%20can%20be%20visualised%20on%20street%20geometries.%20It%20also%20corresponds%20naturally%20with%20simplest-path%20(angular)%20centralities%2C%20which%20track%20turning%20angles%20from%20street%20to%20street.%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Primal%20graph%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Dual%20graph%0A%20%20%20%20(intersections%20%3D%20nodes)%20%20%20%20%20%20%20%20%20(streets%20%3D%20nodes)%0A%0A%20%20%20%20%20%20%20%20A%20%E2%80%94%E2%80%94%E2%80%94%20B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20AB%0A%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%E2%86%92%20%20%20%20%20%20%20%20%20%20%20%20%2F%20%20%5C%0A%20%20%20%20%20%20%20%20C%20%E2%80%94%E2%80%94%E2%80%94%20D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20AC%20%20%20%20BD%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5C%20%20%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20CD%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%3E%20**Important%3A**%0A%20%20%20%20%3E%20**Angular%20centrality%20measures%20require%20the%20dual%20graph.**%20%60CityNetwork%60%20builds%20the%20dual%20graph%20automatically.%20When%20using%20the%20lower-level%20API%2C%20convert%20a%20primal%20graph%20with%20%5B%60graphs.nx_to_dual%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Ftools%2Fgraphs%23nx-to-dual)%20before%20computing%20angular%20centralities%3B%20see%20the%20%5Bdual%20graph%20recipe%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks%2Fcreate-dual-graph).%0A%0A%20%20%20%20%23%23%23%20Where%20results%20are%20stored%0A%0A%20%20%20%20%60CityNetwork%60%20exposes%20a%20%60nodes_gdf%60%20property%3A%20one%20row%20per%20street%20segment%20(dual%20node)%2C%20with%20computed%20metrics%20added%20as%20columns.%20For%20mapping%20and%20export%2C%20%60to_geopandas()%60%20returns%20the%20same%20columns%20joined%20to%20the%20original%20LineString%20geometries.%0A%0A%20%20%20%20In%20the%20lower-level%20API%2C%20%5B%60network_structure_from_nx%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Ftools%2Fio%23network-structure-from-nx)%20converts%20a%20%60networkx%60%20graph%20into%20a%20nodes%20%60GeoDataFrame%60%2C%20an%20edges%20%60GeoDataFrame%60%2C%20and%20a%20%60NetworkStructure%60%20%E2%80%94%20the%20internal%20Rust%20data%20structure%20used%20by%20the%20metric%20functions.%20The%20%60NetworkStructure%60%20can%20be%20reused%20across%20multiple%20metric%20computations%20as%20long%20as%20the%20network%20does%20not%20change.%0A%0A%20%20%20%20%23%23%23%20Distance%20thresholds%0A%0A%20%20%20%20Most%20%60cityseer%60%20functions%20accept%20a%20%60distances%60%20parameter%20specifying%20network%20distance%20thresholds%20(in%20metres).%20Multiple%20thresholds%20can%20be%20computed%20at%20once.%20See%20the%20%5Bdistance%20thresholds%20table%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Ffundamentals%23distance-thresholds)%20for%20common%20choices%20and%20their%20real-world%20meaning.%0A%0A%20%20%20%20Alternatively%2C%20use%20the%20%60minutes%60%20parameter%20to%20specify%20walking-time%20thresholds%2C%20converted%20internally%20to%20metres%20at%20a%20default%20walking%20speed%20of%201.33m%2Fs%20(about%2080m%20per%20minute).%0A%0A%20%20%20%20%23%23%23%20Reading%20output%20columns%0A%0A%20%20%20%20%60cityseer%60%20adds%20result%20columns%20to%20the%20nodes%20%60GeoDataFrame%60%20using%20a%20naming%20convention%3A%0A%0A%20%20%20%20%7C%20Pattern%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20Example%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20Meaning%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%20%20%20%20%7C%20-------------------------------------%20%7C%20-------------------------------%20%7C%20----------------------------------------------------------------%20%7C%0A%20%20%20%20%7C%20%60cc_%7Bmetric%7D_%7Bdistance%7D%60%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%60cc_betweenness_800%60%20%20%20%20%20%20%20%20%20%20%20%20%7C%20Metric%20centrality%3A%20betweenness%20at%20800m%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%20%20%20%20%7C%20%60cc_%7Bmetric%7D_%7Bdistance%7D_ang%60%20%20%20%20%20%20%20%20%20%20%7C%20%60cc_harmonic_500_ang%60%20%20%20%20%20%20%20%20%20%20%20%7C%20Angular%20centrality%3A%20harmonic%20closeness%20at%20500m%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%20%20%20%20%7C%20%60cc_%7Blanduse%7D_%7Bdistance%7D%60%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%60cc_restaurant_400%60%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20Accessibility%3A%20count%20of%20restaurants%20within%20400m%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%20%20%20%20%7C%20%60cc_%7Blanduse%7D_nearest_max_%7Bdistance%7D%60%20%7C%20%60cc_restaurant_nearest_max_800%60%20%7C%20Accessibility%3A%20distance%20to%20nearest%20restaurant%20(max%20search%20800m)%20%20%7C%0A%20%20%20%20%7C%20%60cc_%7Bcolumn%7D_%7Bstat%7D_%7Bdistance%7D%60%20%20%20%20%20%20%20%7C%20%60cc_height_mean_400%60%20%20%20%20%20%20%20%20%20%20%20%20%7C%20Statistics%3A%20mean%20of%20%60height%60%20column%20within%20400m%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%0A%20%20%20%20The%20%60cc_%60%20prefix%20identifies%20columns%20computed%20by%20%60cityseer%60.%20For%20centrality%2C%20the%20%60_ang%60%20suffix%20indicates%20angular%20(simplest-path)%20analysis%3B%20its%20absence%20indicates%20metric%20(shortest-path)%20analysis.%20For%20accessibility%20and%20statistics%2C%20%60CityNetwork%60%20produces%20plain%20(unweighted)%20aggregations%20by%20default%3B%20pass%20a%20%60decay_fn%60%20expression%20for%20distance-weighted%20variants%2C%20in%20which%20case%20dict%20labels%20are%20embedded%20in%20the%20column%20names.%20The%20lower-level%20%60layers%60%20functions%2C%20when%20%60decay_fn%60%20is%20omitted%2C%20retain%20a%20legacy%20default%20that%20emits%20both%20an%20unweighted%20(%60_nw%60)%20and%20a%20decay-weighted%20(%60_wt%60)%20column.%20By%20default%2C%20%60CityNetwork%60%20centrality%20emits%20harmonic%20closeness%20(%60cc_harmonic_%7Bd%7D%60)%20and%20betweenness%20(%60cc_betweenness_%7Bd%7D%60)%3B%20further%20metrics%20can%20be%20requested%20via%20expression%20dictionaries%2C%20as%20described%20in%20the%20%5Bguide%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Fcentrality%23centrality).%0A%0A%20%20%20%20%23%23%20A%20minimal%20example%0A%0A%20%20%20%20Here%20is%20a%20complete%20%60cityseer%60%20workflow%20in%20a%20few%20lines.%20It%20downloads%20a%20street%20network%2C%20computes%20centrality%2C%20and%20plots%20betweenness.%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%0Adef%20_()%3A%0A%20%20%20%20import%20os%0A%0A%20%20%20%20os.environ%5B%22CITYSEER_QUIET_MODE%22%5D%20%3D%20%221%22%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20cityseer.network%20import%20CityNetwork%0A%20%20%20%20from%20cityseer.tools%20import%20io%0A%0A%20%20%20%20%23%201.%20Define%20area%20of%20interest%20(a%201000m%20buffer%20around%20a%20central%20point)%0A%20%20%20%20poly_wgs%2C%20_%20%3D%20io.buffered_point_poly(-3.7038%2C%2040.4168%2C%201000)%0A%0A%20%20%20%20%23%202.%20Build%20the%20network%3A%20downloads%20from%20OSM%2C%20cleans%2C%20and%20builds%20the%20dual%20graph%0A%20%20%20%20cn%20%3D%20CityNetwork.from_osm(poly_wgs)%0A%0A%20%20%20%20%23%203.%20Compute%20shortest-path%20centrality%20at%20500m%2C%201000m%2C%20and%202000m%0A%20%20%20%20cn.centrality_shortest(distances%3D%5B500%2C%201000%2C%202000%5D)%0A%0A%20%20%20%20%23%204.%20Export%20with%20street%20geometries%20and%20plot%20betweenness%20at%201000m%0A%20%20%20%20edges_gdf%20%3D%20cn.to_geopandas()%0A%20%20%20%20%23%20betweenness%20is%20heavily%20skewed%3A%20map%20the%20percentile%20rank%20so%20the%20pattern%20is%20legible%0A%20%20%20%20g%20%3D%20edges_gdf.copy()%0A%20%20%20%20g%5B%22_r%22%5D%20%3D%20g%5B%22cc_betweenness_1000%22%5D.rank(pct%3DTrue)%0A%20%20%20%20g%20%3D%20g.sort_values(%22_r%22)%20%20%23%20strongest%20drawn%20last%2C%20on%20top%0A%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(1%2C%201%2C%20figsize%3D(7%2C%207)%2C%20dpi%3D150)%0A%20%20%20%20g.plot(ax%3Dax%2C%20color%3Dplt.get_cmap(%22OrRd%22)(g%5B%22_r%22%5D)%2C%20linewidth%3D0.15%20%2B%202.25%20*%20g%5B%22_r%22%5D)%0A%20%20%20%20ax.set_title(%22Betweenness%2C%201000%20m%22%2C%20loc%3D%22left%22)%0A%20%20%20%20ax.set_axis_off()%0A%20%20%20%20fig.tight_layout()%0A%20%20%20%20fig%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%3E%20**Note%3A**%0A%20%20%20%20%3E%20Building%20the%20network%20produces%20log%20messages%20showing%20the%20cleaning%20steps.%20These%20are%20normal%20and%20can%20be%20safely%20ignored.%20To%20suppress%20them%2C%20add%20%60import%20logging%3B%20logging.getLogger(%22cityseer%22).setLevel(logging.WARNING)%60%20beforehand.%0A%0A%20%20%20%20%23%23%20Choosing%20a%20coordinate%20reference%20system%0A%0A%20%20%20%20%60cityseer%60%20requires%20a%20**projected**%20coordinate%20reference%20system%20(CRS)%20with%20metre%20units%20for%20accurate%20distance%20calculations.%20A%20geographic%20CRS%20like%20WGS%2084%20(EPSG%3A4326)%20uses%20degrees%20and%20will%20produce%20incorrect%20results.%0A%0A%20%20%20%20How%20to%20choose%20the%20right%20CRS%20for%20your%20study%20area%3A%0A%0A%20%20%20%20-%20**Let%20cityseer%20choose%20for%20you%3A**%20When%20using%20%60CityNetwork.from_osm%60%2C%20%60io.buffered_point_poly%60%2C%20or%20%60io.osm_graph_from_poly%60%20with%20default%20settings%2C%20%60cityseer%60%20automatically%20selects%20an%20appropriate%20UTM%20zone%20based%20on%20the%20input%20coordinates.%20This%20is%20usually%20sufficient.%0A%20%20%20%20-%20**Specify%20explicitly%3A**%20If%20you%20need%20a%20specific%20CRS%2C%20use%20the%20%60to_crs_code%60%20parameter.%20Common%20choices%20include%20UTM%20zones%20(search%20your%20city%20at%20%5Bepsg.io%5D(https%3A%2F%2Fepsg.io))%20or%20regional%20projections%20like%20EPSG%3A3035%20(Europe)%2C%20EPSG%3A27700%20(Great%20Britain)%2C%20or%20EPSG%3A2154%20(France).%0A%20%20%20%20-%20**From%20existing%20data%3A**%20If%20loading%20a%20network%20from%20a%20file%2C%20ensure%20it%20is%20already%20in%20a%20projected%20CRS%2C%20or%20reproject%20it%20with%20%60gdf.to_crs(epsg%3D...)%60%20before%20passing%20it%20to%20%60cityseer%60.%0A%0A%20%20%20%20%23%23%20Common%20pitfalls%0A%0A%20%20%20%20If%20something%20looks%20wrong%2C%20distances%20off%20by%20orders%20of%20magnitude%2C%20values%20fading%20at%20the%20study%20area%20edge%2C%20missing%20data%20points%2C%20and%20so%20on%2C%20see%20the%20%5BTroubleshooting%20guide%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Ftroubleshooting).%20It%20covers%20the%20common%20problems%20symptom%20by%20symptom%2C%20with%20fixes.%0A%0A%20%20%20%20%23%23%20Next%20steps%0A%0A%20%20%20%20With%20these%20concepts%20in%20hand%2C%20you%20are%20ready%20to%20explore%20the%20recipes%3A%0A%0A%20%20%20%20-%20%5BNetwork%20Preparation%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks)%20%E2%80%94%20create%20networks%20from%20various%20data%20sources.%0A%20%20%20%20-%20%5BNetwork%20Centrality%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fcentrality)%20%E2%80%94%20metric%20and%20angular%20centrality.%0A%20%20%20%20-%20%5BAccessibility%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Faccessibility)%20%E2%80%94%20landuse%20accessibility%20and%20mixed-use%20metrics.%0A%20%20%20%20-%20%5BStatistics%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fstats)%20%E2%80%94%20aggregate%20numeric%20properties%20over%20the%20network.%0A%20%20%20%20-%20%5BVisibility%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fvisibility)%20%E2%80%94%20street%20enclosure%20and%20openness.%0A%20%20%20%20-%20%5BContinuity%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fcontinuity)%20%E2%80%94%20street%20name%20and%20route%20continuity.%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
e917527905fbe36f9a6ddf561fb90a82