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%20Centrality%20Expressions%20and%20Statistic%20Selection%0A%0A%20%20%20%20From%20v5%2C%20%60cityseer%60%20centrality%20is%20expression-based%3A%20instead%20of%20a%20fixed%20metric%20set%2C%20the%20%60centrality_shortest%60%20and%20%60centrality_simplest%60%20methods%20accept%20%60%7Bname%3A%20expression%7D%60%20dictionaries%2C%20so%20you%20define%20exactly%20which%20metrics%20to%20compute.%20The%20same%20principle%20extends%20to%20the%20land-use%20and%20statistics%20methods%20through%20the%20%60decay_fn%60%20and%20%60measures%60%20parameters.%0A%0A%20%20%20%20This%20notebook%20works%20through%20the%20high-level%20%5B%60CityNetwork%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fapi%2Fnetwork)%20class%2C%20which%20forwards%20these%20parameters%20to%20the%20underlying%20functions%20unchanged%2C%20and%20covers%3A%0A%0A%20%20%20%20-%20the%20expression%20model%20(%60c%60%20and%20%60p%60%20variables)%20and%20the%20default%20metrics%3B%0A%20%20%20%20-%20selecting%20only%20the%20metrics%20you%20need%3B%0A%20%20%20%20-%20defining%20custom%20metrics%20such%20as%20gravity-weighted%20closeness%3B%0A%20%20%20%20-%20derived%20metrics%20via%20%60postprocess%60%3B%0A%20%20%20%20-%20selecting%20statistical%20measures%20with%20%60compute_stats(measures%3D%5B...%5D)%60%20and%20applying%20distance%20decay%20to%20statistics.%0A%0A%20%20%20%20For%20the%20underlying%20concepts%20see%20the%20%5Bguide%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Fcentrality%23centrality).%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%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20cityseer.network%20import%20CityNetwork%0A%0A%20%20%20%20return%20CityNetwork%2C%20gpd%2C%20plt%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%20Network%20preparation%0A%0A%20%20%20%20We%20load%20the%20bundled%20street%20network%20from%20the%20bundled%20datasets%20and%20clip%20it%20to%20a%202km%20study%20area%20so%20that%20the%20examples%20run%20quickly.%20%60CityNetwork%60%20builds%20the%20dual%20representation%20automatically%2C%20so%20metrics%20are%20expressed%20relative%20to%20street%20segments.%20See%20the%20%5Bnetwork%20preparation%20recipes%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks)%20for%20the%20lower-level%20construction%20steps.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(CityNetwork%2C%20gpd%2C%20mo)%3A%0A%20%20%20%20data_dir%20%3D%20(mo.notebook_dir()%20%2F%20%22..%22%20%2F%20%22..%22%20%2F%20%22data%22).resolve()%0A%20%20%20%20streets_gpd%20%3D%20gpd.read_file(data_dir%20%2F%20%22madrid_streets%22%20%2F%20%22street_network.gpkg%22)%0A%20%20%20%20streets_gpd%20%3D%20streets_gpd.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%20%3D%20streets_gpd.drop_duplicates(subset%3D%22geometry%22)%0A%20%20%20%20%23%20clip%20to%20a%202km%20buffer%20around%20a%20central%20point%20(city%20centre)%20for%20fast%20examples%0A%20%20%20%20study_area%20%3D%20gpd.GeoSeries.from_xy(%5B440300%5D%2C%20%5B4474300%5D%2C%20crs%3Dstreets_gpd.crs).buffer(2000).iloc%5B0%5D%0A%20%20%20%20streets_clip%20%3D%20streets_gpd%5Bstreets_gpd.intersects(study_area)%5D%0A%20%20%20%20cn%20%3D%20CityNetwork.from_geopandas(streets_clip)%0A%20%20%20%20print(f%22%7Bcn.node_count%7D%20street%20segments%20(dual%20nodes)%22)%0A%20%20%20%20return%20cn%2C%20data_dir%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%20The%20expression%20model%0A%0A%20%20%20%20Metric%20expressions%20use%20two%20variables%3A%0A%0A%20%20%20%20-%20%60c%60%3A%20the%20raw%20network%20cost%20to%20a%20reached%20node%20-%20metres%20for%20shortest-path%20analysis%2C%20degrees%20of%20cumulative%20turning%20for%20simplest-path%20(angular)%20analysis%3B%0A%20%20%20%20-%20%60p%60%3A%20normalised%20progress%20from%20%600%60%20at%20the%20source%20to%20%601%60%20at%20the%20distance%20threshold%20(%60p%20%3D%20c%20%2F%20threshold%60).%0A%0A%20%20%20%20Expressions%20may%20use%20the%20functions%20%60exp%60%2C%20%60ln%60%2C%20%60log10%60%2C%20%60sqrt%60%2C%20%60abs%60%2C%20%60floor%60%2C%20%60ceil%60%2C%20%60round%60%2C%20%60sin%60%2C%20%60cos%60%2C%20%60tan%60%2C%20and%20the%20constants%20%60pi%60%20and%20%60e%60.%0A%0A%20%20%20%20The%20two%20metric%20categories%20aggregate%20differently%3A%0A%0A%20%20%20%20-%20**closeness**%20expressions%20are%20evaluated%20once%20per%20reached%20node%20and%20summed%3A%20%60%7B%22harmonic%22%3A%20%221%2Fc%22%7D%60%20accumulates%20%24%5Csum_j%201%2Fc_j%24%20over%20all%20nodes%20%24j%24%20within%20the%20threshold%3B%0A%20%20%20%20-%20**betweenness**%20expressions%20weight%20each%20origin-destination%20pair's%20contribution%20to%20the%20nodes%20on%20the%20shortest%20path%20between%20them%3A%20%60%7B%22betweenness%22%3A%20%221%22%7D%60%20counts%20paths%20equally.%0A%0A%20%20%20%20Each%20entry%20produces%20a%20column%20%60cc_%7Bname%7D_%7Bdistance%7D%60.%20The%20%60CityNetwork%60%20methods%20default%20to%20a%20lean%20set%2C%20a%20single%20harmonic%20closeness%20and%20a%20single%20betweenness%2C%20while%20passing%20%60%7B%7D%60%20skips%20a%20category%20entirely.%20Explicitly%20passing%20%60None%60%20opts%20into%20the%20fuller%20default%20set%20of%20the%20underlying%20functional%20%60networks.centrality_shortest%60%3A%0A%0A%20%20%20%20%7C%20Category%20%7C%20Default%20%7C%20Expression%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20closeness%20%7C%20%60density%60%20%7C%20%60%221%22%60%20%7C%0A%20%20%20%20%7C%20closeness%20%7C%20%60farness%60%20%7C%20%60%22c%22%60%20%7C%0A%20%20%20%20%7C%20closeness%20%7C%20%60harmonic%60%20%7C%20%60%221%2Fc%22%60%20%7C%0A%20%20%20%20%7C%20closeness%20%7C%20%60decay%60%20%7C%20%60%22exp(-4%20*%20p)%22%60%20%7C%0A%20%20%20%20%7C%20betweenness%20%7C%20%60betweenness%60%20%7C%20%60%221%22%60%20%7C%0A%20%20%20%20%7C%20betweenness%20%7C%20%60betweenness_decay%60%20%7C%20%60%22exp(-4%20*%20p)%22%60%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cn)%3A%0A%20%20%20%20_before%20%3D%20set(cn.nodes_gdf.columns)%0A%20%20%20%20cn.centrality_shortest(distances%3D%5B800%5D)%0A%20%20%20%20lean_cols%20%3D%20sorted(c%20for%20c%20in%20set(cn.nodes_gdf.columns)%20-%20_before)%0A%20%20%20%20print(lean_cols)%0A%20%20%20%20return%20(lean_cols%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%20Selecting%20only%20what%20you%20need%0A%0A%20%20%20%20Every%20expression%20is%20evaluated%20during%20the%20network%20traversal%2C%20so%20a%20smaller%20metric%20set%20runs%20faster%20and%20emits%20fewer%20columns.%20Here%20we%20compute%20a%20single%20harmonic%20closeness%20across%20two%20distances%20and%20skip%20betweenness%20entirely%20with%20%60%7B%7D%60%20(cycles%20are%20already%20off%20by%20default%20on%20%60CityNetwork%60).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cn%2C%20lean_cols)%3A%0A%20%20%20%20_before%20%3D%20set(cn.nodes_gdf.columns)%0A%20%20%20%20cn.centrality_shortest(%0A%20%20%20%20%20%20%20%20distances%3D%5B400%2C%20800%5D%2C%0A%20%20%20%20%20%20%20%20closeness%3D%7B%22harmonic%22%3A%20%221%2Fc%22%7D%2C%0A%20%20%20%20%20%20%20%20betweenness%3D%7B%7D%2C%0A%20%20%20%20)%0A%20%20%20%20print(sorted(set(cn.nodes_gdf.columns)%20-%20_before)%2C%20f%22(in%20addition%20to%20the%20existing%20%7Blean_cols%7D)%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%20Custom%20metrics%0A%0A%20%20%20%20Any%20expression%20over%20%60c%60%20and%20%60p%60%20defines%20a%20new%20metric.%20Three%20common%20patterns%3A%0A%0A%20%20%20%20-%20**Gravity%20%2F%20spatial%20interaction**%3A%20%60exp(-beta%20*%20c)%60%20with%20an%20explicit%20beta%20in%20metres.%20%60%22exp(-0.005%20*%20c)%22%60%20corresponds%20to%20a%20beta%20of%200.005%2C%20i.e.%20roughly%20an%20800m%20walking%20tolerance.%20This%20replaces%20the%20removed%20%60betas%3D%60%20parameter%20from%20earlier%20versions.%0A%20%20%20%20-%20**Threshold-relative%20decay**%3A%20%60exp(-4%20*%20p)%60%20expresses%20decay%20in%20terms%20of%20the%20threshold%20rather%20than%20absolute%20metres%2C%20so%20the%20same%20expression%20adapts%20across%20distances.%0A%20%20%20%20-%20**Cumulative%20reach**%3A%20%60%221%22%60%20simply%20counts%20reachable%20nodes%20(density).%0A%0A%20%20%20%20The%20same%20dictionaries%20apply%20to%20%60centrality_simplest%60%2C%20where%20%60c%60%20is%20angular%20cost%2C%20and%20to%20the%20betweenness%20side%2C%20where%20the%20expression%20weights%20each%20origin-destination%20pair.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cn)%3A%0A%20%20%20%20_before%20%3D%20set(cn.nodes_gdf.columns)%0A%20%20%20%20cn.centrality_shortest(%0A%20%20%20%20%20%20%20%20distances%3D%5B800%5D%2C%0A%20%20%20%20%20%20%20%20closeness%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22harmonic%22%3A%20%221%2Fc%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22gravity%22%3A%20%22exp(-0.005%20*%20c)%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20betweenness%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22betweenness%22%3A%20%221%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22betweenness_near%22%3A%20%22exp(-8%20*%20p)%22%2C%20%20%23%20emphasise%20short-range%20through-movement%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20)%0A%20%20%20%20nodes_custom%20%3D%20cn.to_geopandas()%0A%20%20%20%20print(sorted(set(nodes_custom.columns)%20-%20_before))%0A%20%20%20%20return%20(nodes_custom%2C)%0A%0A%0A%40app.cell%0Adef%20_(nodes_custom%2C%20plt)%3A%0A%20%20%20%20fig%2C%20axes%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(13%2C%206.5)%2C%20dpi%3D150)%0A%20%20%20%20for%20ax%2C%20col%2C%20label%20in%20zip(%0A%20%20%20%20%20%20%20%20axes%2C%0A%20%20%20%20%20%20%20%20%5B%22cc_harmonic_800%22%2C%20%22cc_gravity_800%22%5D%2C%0A%20%20%20%20%20%20%20%20%5B%22Harmonic%20closeness%2C%20800%20m%22%2C%20%22Gravity-weighted%20closeness%2C%20800%20m%22%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%20g%20%3D%20nodes_custom%5Bnodes_custom.live%5D.copy()%0A%20%20%20%20%20%20%20%20g%5B%22_r%22%5D%20%3D%20g%5Bcol%5D.rank(pct%3DTrue)%0A%20%20%20%20%20%20%20%20g%20%3D%20g.sort_values(%22_r%22)%20%20%23%20strongest%20drawn%20last%0A%20%20%20%20%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%20%20%20%20%20ax.set_title(label%2C%20loc%3D%22left%22)%0A%20%20%20%20%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%23%23%20Derived%20metrics%20with%20%60postprocess%60%0A%0A%20%20%20%20The%20%60postprocess%60%20parameter%20derives%20further%20columns%20from%20computed%20results%20using%20simple%20arithmetic%20over%20the%20metric%20names.%20The%20default%20computes%20Hillier-style%20normalised%20integration%2C%20%60density**2%20%2F%20farness%60%2C%20which%20requires%20that%20%60density%60%20and%20%60farness%60%20are%20present%20in%20the%20closeness%20set.%20Derived%20metrics%20are%20computed%20per%20distance%20threshold%20after%20the%20traversal%2C%20so%20they%20add%20no%20traversal%20cost.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cn)%3A%0A%20%20%20%20_before%20%3D%20set(cn.nodes_gdf.columns)%0A%20%20%20%20cn.centrality_shortest(%0A%20%20%20%20%20%20%20%20distances%3D%5B800%5D%2C%0A%20%20%20%20%20%20%20%20closeness%3D%7B%22density%22%3A%20%221%22%2C%20%22farness%22%3A%20%22c%22%7D%2C%0A%20%20%20%20%20%20%20%20betweenness%3D%7B%7D%2C%0A%20%20%20%20%20%20%20%20postprocess%3D%7B%22hillier%22%3A%20%22density**2%20%2F%20farness%22%7D%2C%0A%20%20%20%20)%0A%20%20%20%20print(sorted(set(cn.nodes_gdf.columns)%20-%20_before))%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%20Selecting%20statistics%3A%20%60compute_stats%60%20with%20%60measures%60%0A%0A%20%20%20%20The%20statistics%20function%20follows%20the%20same%20select-what-you-need%20principle.%20By%20default%2C%20%60compute_stats%60%20emits%20%60sum%60%2C%20%60mean%60%2C%20%60count%60%2C%20%60var%60%2C%20%60median%60%2C%20%60mad%60%2C%20%60max%60%2C%20and%20%60min%60%20for%20each%20column%20and%20distance.%20The%20%60measures%60%20parameter%20restricts%20this%20to%20a%20subset%2C%20which%20keeps%20the%20output%20frame%20small%20and%20skips%20the%20weighted%20median%2FMAD%20sort%20when%20neither%20is%20requested.%0A%0A%20%20%20%20Distance%20weighting%20is%20controlled%20by%20%60decay_fn%60%2C%20an%20expression%20over%20%60p%60%20(clamped%20to%20%60%5B0%2C%201%5D%60).%20Passing%20a%20%60%7Blabel%3A%20expression%7D%60%20dictionary%20computes%20several%20decay%20variants%20in%20a%20single%20traversal%2C%20with%20each%20label%20suffixed%20into%20its%20column%20names.%20The%20%5B%60cityseer.decay%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fapi%2Fdecay)%20module%20provides%20helpers%20that%20return%20these%20expression%20strings%3A%20%60decay.flat()%60%20returns%20%60%221%22%60%2C%20%60decay.exponential()%60%20returns%20%60%22exp(-4.0%20*%20p)%22%60%2C%20and%20%60decay.gaussian(peak%3D400%2C%20cutoff%3D1600)%60%20returns%20a%20Gaussian%20centred%20at%20400m.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cn%2C%20data_dir%2C%20gpd)%3A%0A%20%20%20%20from%20cityseer%20import%20decay%0A%0A%20%20%20%20bldgs_gpd%20%3D%20gpd.read_file(data_dir%20%2F%20%22madrid_buildings%22%20%2F%20%22madrid_bldgs.gpkg%22)%0A%20%20%20%20_before%20%3D%20set(cn.nodes_gdf.columns)%0A%20%20%20%20_cn%2C%20bldgs_assigned%20%3D%20cn.compute_stats(%0A%20%20%20%20%20%20%20%20bldgs_gpd%2C%0A%20%20%20%20%20%20%20%20stats_column_labels%3D%5B%22mean_height%22%5D%2C%0A%20%20%20%20%20%20%20%20distances%3D%5B400%2C%20800%5D%2C%0A%20%20%20%20%20%20%20%20measures%3D%5B%22mean%22%2C%20%22count%22%5D%2C%0A%20%20%20%20%20%20%20%20decay_fn%3D%7B%22plain%22%3A%20decay.flat()%2C%20%22wt%22%3A%20decay.exponential()%7D%2C%0A%20%20%20%20)%0A%20%20%20%20nodes_stats%20%3D%20cn.to_geopandas()%0A%20%20%20%20print(sorted(set(nodes_stats.columns)%20-%20_before))%0A%20%20%20%20return%20(nodes_stats%2C)%0A%0A%0A%40app.cell%0Adef%20_(nodes_stats%2C%20plt)%3A%0A%20%20%20%20stat_cols%20%3D%20sorted(c%20for%20c%20in%20nodes_stats.columns%20if%20%22mean_height%22%20in%20c%20and%20%22_mean_%22%20in%20c)%0A%20%20%20%20fig_s%2C%20axes_s%20%3D%20plt.subplots(1%2C%20len(stat_cols)%2C%20figsize%3D(6.5%20*%20len(stat_cols)%2C%206.5)%2C%20dpi%3D150)%0A%20%20%20%20for%20ax_s%2C%20col_s%20in%20zip(axes_s%2C%20stat_cols%2C%20strict%3DFalse)%3A%0A%20%20%20%20%20%20%20%20%23%20column%20names%20follow%20cc_mean_height_mean_%7Bdecay%20label%7D_%7Bdistance%7D%0A%20%20%20%20%20%20%20%20_decay_label%2C%20_dist%20%3D%20col_s.split(%22_%22)%5B-2%3A%5D%0A%20%20%20%20%20%20%20%20_title%20%3D%20f%22Mean%20building%20height%2C%20%7B_dist%7D%20m%20(%7B'distance-weighted'%20if%20_decay_label%20%3D%3D%20'wt'%20else%20'unweighted'%7D)%22%0A%20%20%20%20%20%20%20%20_g%20%3D%20nodes_stats%5Bnodes_stats.live%5D.copy()%0A%20%20%20%20%20%20%20%20_g%5B%22_r%22%5D%20%3D%20_g%5Bcol_s%5D.rank(pct%3DTrue)%0A%20%20%20%20%20%20%20%20_g%20%3D%20_g.sort_values(%22_r%22)%20%20%23%20strongest%20drawn%20last%0A%20%20%20%20%20%20%20%20_g.plot(ax%3Dax_s%2C%20color%3Dplt.get_cmap(%22OrRd%22)(_g%5B%22_r%22%5D)%2C%20linewidth%3D0.15%20%2B%202.25%20*%20_g%5B%22_r%22%5D)%0A%20%20%20%20%20%20%20%20ax_s.set_title(_title%2C%20loc%3D%22left%22)%0A%20%20%20%20%20%20%20%20ax_s.set_axis_off()%0A%20%20%20%20fig_s.tight_layout()%0A%20%20%20%20fig_s%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%20Where%20else%20expressions%20apply%0A%0A%20%20%20%20-%20%60compute_accessibilities%60%20and%20%60compute_mixed_uses%60%20accept%20the%20same%20%60decay_fn%60%20parameter%2C%20including%20the%20%60%7Blabel%3A%20expression%7D%60%20dict%20form%2C%20for%20distance-weighted%20variants.%0A%20%20%20%20-%20%60betweenness_demand%60%20uses%20a%20%60decay_fn%60%20expression%20as%20the%20deterrence%20function%20of%20a%20spatial-interaction%20model%20for%20origin-destination%20weighted%20flows.%0A%20%20%20%20-%20The%20lower-level%20functional%20%60networks%60%20and%20%60layers%60%20modules%20accept%20the%20same%20dictionaries%20directly%3B%20the%20%5B%60CityNetwork%60%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fapi%2Fnetwork)%20methods%20used%20here%20forward%20them%20unchanged%2C%20differing%20only%20in%20their%20leaner%20defaults.%0A%0A%20%20%20%20See%20the%20%5Bguide%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fguide%2Fland-use%23decay-functions)%20for%20the%20full%20expression%20syntax%20and%20decay%20reference.%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
81e9d2351d6e8ff58b322be03e7749fa