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%20GeoPandas%0A%0A%20%20%20%20%5BGeoPandas%5D(https%3A%2F%2Fgeopandas.org%2F)%20extends%20the%20pandas%20data%20analysis%20library%20to%20work%20with%20spatial%20data.%20Its%20core%20data%20structure%2C%20the%20%60GeoDataFrame%60%2C%20is%20a%20table%20in%20which%20each%20row%20is%20a%20feature%3A%20one%20column%20holds%20a%20Shapely%20geometry%2C%20and%20the%20remaining%20columns%20hold%20attributes.%20A%20GeoDataFrame%20also%20records%20its%20coordinate%20reference%20system%20(CRS).%0A%0A%20%20%20%20To%20see%20how%20the%20pieces%20fit%20together%2C%20we%20will%20build%20a%20small%20GeoDataFrame%20from%20scratch.%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%20shapely.geometry%20import%20Point%0A%0A%20%20%20%20return%20Point%2C%20gpd%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%20First%2C%20we'll%20define%20some%20data%20as%20a%20list%20of%20dictionaries.%20Each%20dictionary%20will%20represent%20a%20city%2C%20storing%20its%20name%20and%20approximate%20coordinates%20(longitude%2C%20latitude).%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%20data%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%7B%22city%22%3A%20%22Seville%22%2C%20%22x%22%3A%20-5.9845%2C%20%22y%22%3A%2037.3891%7D%2C%0A%20%20%20%20%20%20%20%20%7B%22city%22%3A%20%22Barcelona%22%2C%20%22x%22%3A%202.1734%2C%20%22y%22%3A%2041.3851%7D%2C%0A%20%20%20%20%20%20%20%20%7B%22city%22%3A%20%22Valencia%22%2C%20%22x%22%3A%20-0.3774%2C%20%22y%22%3A%2039.4699%7D%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20data%0A%20%20%20%20return%20(data%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%20Next%2C%20we%20need%20to%20create%20the%20corresponding%20geometry%20objects.%20As%20these%20are%20coordinates%2C%20%60Point%60%20objects%20are%20suitable.%20We%20can%20generate%20a%20list%20of%20%60Point%60%20objects%20directly%20from%20our%20data.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Point%2C%20data)%3A%0A%20%20%20%20%23%20Create%20Point%20geometries%20from%20the%20x%20and%20y%20columns%0A%20%20%20%20locations%20%3D%20%5B%5D%0A%0A%20%20%20%20for%20city%20in%20data%3A%0A%20%20%20%20%20%20%20%20x%20%3D%20city%5B%22x%22%5D%0A%20%20%20%20%20%20%20%20y%20%3D%20city%5B%22y%22%5D%0A%20%20%20%20%20%20%20%20geom%20%3D%20Point(x%2C%20y)%0A%20%20%20%20%20%20%20%20locations.append(geom)%0A%0A%20%20%20%20locations%0A%20%20%20%20return%20(locations%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%20With%20the%20structured%20data%20and%20geometry%20prepared%2C%20the%20final%20component%20is%20the%20CRS.%20Given%20that%20the%20coordinates%20are%20longitude%20and%20latitude%2C%20the%20appropriate%20CRS%20is%20WGS%2084%2C%20identified%20by%20the%20EPSG%20code%204326.%0A%0A%20%20%20%20We%20can%20now%20construct%20the%20%60GeoDataFrame%60%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(data%2C%20gpd%2C%20locations)%3A%0A%20%20%20%20gdf_cities%20%3D%20gpd.GeoDataFrame(%0A%20%20%20%20%20%20%20%20data%2C%20%20%23%20The%20list%20of%20dictionaries%0A%20%20%20%20%20%20%20%20geometry%3Dlocations%2C%20%20%23%20The%20Shapely%20Points%0A%20%20%20%20%20%20%20%20crs%3D4326%2C%20%20%23%20Coordinate%20Reference%20System%20(WGS%2084)%0A%20%20%20%20)%0A%0A%20%20%20%20gdf_cities%0A%20%20%20%20return%20(gdf_cities%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%20Indexing%0A%0A%20%20%20%20Similar%20to%20pandas%20DataFrames%2C%20GeoDataFrames%20possess%20an%20index.%20By%20default%2C%20this%20is%20a%20range%20of%20integers.%20You%20can%20assign%20a%20more%20meaningful%20index%20using%20one%20of%20the%20columns%20(e.g.%2C%20the%20city%20name)%20with%20the%20%60set_index()%60%20method.%20This%20often%20simplifies%20data%20selection.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities)%3A%0A%20%20%20%20gdf_cities_idx%20%3D%20gdf_cities.set_index(%22city%22)%0A%20%20%20%20gdf_cities_idx%0A%20%20%20%20return%20(gdf_cities_idx%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%20You%20can%20access%20a%20row%20using%20its%20index.%20Pandas%20provides%20a%20special%20indexing%20method%2C%20%60.loc%5B%5D%60%2C%20which%20allows%20you%20to%20access%20rows%20by%20their%20index%20label.%20This%20is%20particularly%20useful%20when%20you've%20set%20a%20meaningful%20index%2C%20such%20as%20city%20names.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.loc%5B%22Seville%22%5D%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%20You%20can%20also%20specify%20a%20column%20name.%20For%20instance%2C%20to%20retrieve%20the%20latitude%20of%20Barcelona%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.loc%5B%22Barcelona%22%2C%20%22y%22%5D%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%20To%20retrieve%20all%20rows%20for%20a%20specific%20column%2C%20use%20the%20%60%3A%60%20operator.%20For%20example%2C%20to%20get%20all%20rows%20for%20the%20%60y%60%20column%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.loc%5B%3A%2C%20%22y%22%5D%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%20An%20alternative%20way%20to%20access%20columns%20is%20by%20using%20the%20column%20name%20directly%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx%5B%22y%22%5D%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%20A%20particularly%20powerful%20feature%20of%20GeoDataFrames%20is%20the%20ability%20to%20filter%20rows%20based%20on%20their%20properties.%20To%20do%20this%2C%20you%20create%20a%20boolean%20mask%2C%20which%20can%20then%20be%20used%20to%20exclude%20rows%20you%20are%20not%20interested%20in.%20For%20instance%2C%20if%20you%20want%20to%20filter%20the%20cities%20to%20include%20only%20those%20with%20a%20latitude%20greater%20than%2040%2C%20you%20can%20proceed%20as%20follows%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20%23%20Create%20a%20boolean%20mask%0A%20%20%20%20mask%20%3D%20gdf_cities_idx%5B%22y%22%5D%20%3E%2040%0A%20%20%20%20mask%0A%20%20%20%20return%20(mask%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%20This%20mask%20is%20a%20pandas%20Series%20of%20boolean%20values%2C%20where%20%60True%60%20indicates%20that%20the%20condition%20(y%20%3E%2040)%20is%20met%2C%20and%20%60False%60%20indicates%20it%20is%20not.%20You%20can%20now%20apply%20this%20mask%20to%20filter%20the%20rows%20in%20the%20original%20GeoDataFrame.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx%2C%20mask)%3A%0A%20%20%20%20%23%20Use%20the%20mask%20to%20filter%20the%20rows%0A%20%20%20%20gdf_cities_idx.loc%5Bmask%5D%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%20As%20shown%2C%20only%20two%20rows%20are%20returned%20because%20Valencia%2C%20the%20third%20city%2C%20has%20a%20latitude%20below%2040.%0A%0A%20%20%20%20%23%23%20Geospatial%0A%0A%20%20%20%20GeoDataFrames%20possess%20special%20properties%20stemming%20from%20their%20spatial%20nature.%0A%0A%20%20%20%20GeoPandas%20formally%20designates%20a%20particular%20column%20as%20the%20geometry%3B%20this%20is%20typically%20done%20during%20the%20creation%20of%20the%20GeoDataFrame.%20The%20geometry%20column%20contains%20Shapely%20geometry%20objects%2C%20which%20can%20be%20points%2C%20lines%2C%20or%20polygons.%20This%20column%20is%20often%20called%20%60geometry%60%2C%20but%20this%20is%20not%20always%20the%20case.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.geometry%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%20Similarly%2C%20GeoPandas%20formally%20associates%20the%20geometry%20with%20a%20given%20CRS%2C%20accessible%20via%20the%20%60.crs%60%20attribute.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.crs%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%20GeoPandas%20conveniently%20integrates%20with%20%60matplotlib%60%20for%20straightforward%20plotting.%20Calling%20%60.plot()%60%20on%20a%20GeoDataFrame%20will%20render%20its%20geometries.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_idx.plot()%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%23%20Coordinate%20Transformations%0A%0A%20%20%20%20%3E%20**Note%3A**%0A%20%20%20%20%3E%20%23%23%23%23%20Geographic%20vs.%20projected%20CRS%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20A%20**geographic%20CRS**%20(e.g.%2C%20WGS%2084%20%2F%20EPSG%3A4326)%20stores%20coordinates%20as%20longitude%20and%20latitude%20in%20**degrees**%20on%20the%20Earth's%20curved%20surface.%20A%20**projected%20CRS**%20(e.g.%2C%20EPSG%3A3035%2C%20UTM%20zones)%20projects%20coordinates%20onto%20a%20flat%20surface%20in%20**metres**.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20You%20generally%20want%20to%20use%20a%20projected%20CRS%20for%20the%20type%20of%20work%20we're%20doing%20in%20this%20notebook.%20To%20find%20an%20appropriate%20projected%20CRS%20for%20your%20study%20area%2C%20search%20for%20your%20city%20or%20country%20at%20%5Bepsg.io%5D(https%3A%2F%2Fepsg.io).%20Common%20choices%20include%20UTM%20zones%20(accurate%20for%20local%20areas)%2C%20EPSG%3A3035%20(Europe-wide)%2C%20and%20national%20projections%20like%20EPSG%3A27700%20(Great%20Britain).%0A%0A%20%20%20%20GeoPandas%20makes%20CRS%20transformation%20very%20easy%20with%20the%20%60to_crs()%60%20method.%20Let's%20convert%20our%20cities%20GeoDataFrame%20to%20EPSG%3A3035%2C%20a%20projected%20equal-area%20CRS%20suitable%20for%20Europe%20(ETRS89-LAEA).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_idx)%3A%0A%20%20%20%20gdf_cities_proj%20%3D%20gdf_cities_idx.to_crs(3035)%0A%20%20%20%20gdf_cities_proj%0A%20%20%20%20return%20(gdf_cities_proj%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%20Notice%20how%20the%20%60x%60%20and%20%60y%60%20columns%20no%20longer%20match%20the%20geometry%2C%20as%20the%20geometry%20is%20now%20in%20metres%20according%20to%20EPSG%3A3035.%20The%20%60.crs%60%20attribute%20reflects%20this%20change%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20gdf_cities_proj.crs%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%20Plotting%20the%20transformed%20data%20shows%20the%20locations%20relative%20to%20the%20new%20projected%20coordinate%20system.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20gdf_cities_proj.plot()%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%23%20Spatial%20Operations%0A%0A%20%20%20%20GeoPandas%20enables%20you%20to%20apply%20spatial%20operations%20directly%20to%20%60GeoDataFrames%60%20or%20%60GeoSeries%60.%20These%20operations%20are%20applied%20element-wise.%0A%0A%20%20%20%20For%20instance%2C%20to%20create%20a%20100km%20buffer%20around%20each%20city%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20%23%20The%20buffer%20distance%20is%20in%20the%20units%20of%20the%20CRS%20(metres%20for%20EPSG%3A3035)%0A%20%20%20%20gdf_cities_proj%5B%22geometry%22%5D%20%3D%20gdf_cities_proj.geometry.buffer(100000)%20%20%23%20100km%20buffer%0A%0A%20%20%20%20gdf_cities_proj.plot()%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%20Alternatively%2C%20you%20can%20calculate%20the%20distance%20from%20each%20feature%20in%20a%20GeoDataFrame%20to%20a%20single%20Shapely%20geometry%20object.%20Let's%20determine%20the%20distance%20from%20each%20city%20buffer%20to%20a%20specific%20point%20(also%20defined%20in%20EPSG%3A3035%20coordinates)%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Point%2C%20gdf_cities_proj)%3A%0A%20%20%20%20%23%20Define%20a%20point%20in%20the%20same%20CRS%20(EPSG%3A3035)%0A%20%20%20%20pt%20%3D%20Point(3300000%2C%202000000)%0A%0A%20%20%20%20%23%20Calculate%20distance%20from%20each%20geometry%20in%20the%20GeoSeries%20to%20the%20point%0A%20%20%20%20gdf_cities_proj.geometry.distance(pt)%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%23%20Creating%20and%20Updating%20Columns%0A%0A%20%20%20%20If%20we%20wished%20to%20create%20a%20new%20column%20named%20'easting'%20and%20assign%20it%20the%20x-coordinate%20of%20the%20geometry%2C%20we%20could%20proceed%20as%20follows%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20gdf_cities_proj%5B%22easting%22%5D%20%3D%20gdf_cities_proj.geometry.centroid.x%0A%0A%20%20%20%20gdf_cities_proj%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%20Each%20geometry%20row%20in%20the%20DataFrame%20is%20a%20Shapely%20geometry%2C%20so%20you%20can%20use%20standard%20Shapely%20syntax%20to%20access%20properties%20such%20as%20the%20centroid%20or%20its%20x-coordinate.%0A%0A%20%20%20%20If%20you%20decide%20instead%20to%20update%20the%20existing%20%60x%60%20and%20%60y%60%20columns%2C%20you%20can%20reference%20them%20directly%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20gdf_cities_proj%5B%22x%22%5D%20%3D%20gdf_cities_proj.geometry.centroid.x%0A%20%20%20%20gdf_cities_proj%5B%22y%22%5D%20%3D%20gdf_cities_proj.geometry.centroid.y%0A%0A%20%20%20%20gdf_cities_proj%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%20DataFrames%20offer%20an%20extensive%20variety%20of%20useful%20methods%3B%20here%2C%20we%20will%20use%20the%20%60drop%60%20method%20to%20remove%20the%20column%20we%20no%20longer%20wish%20to%20retain%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(gdf_cities_proj)%3A%0A%20%20%20%20gdf_cities_proj.drop(columns%3D%5B%22easting%22%5D)%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%20Working%20with%20Data%0A%0A%20%20%20%20%23%23%23%20Reading%20Data%0A%0A%20%20%20%20GeoPandas%20can%20read%20various%20spatial%20data%20formats%2C%20such%20as%20Shapefiles%2C%20GeoPackages%2C%20and%20GeoJSON%20files.%20The%20%60read_file()%60%20function%20is%20the%20primary%20method%20for%20this.%20The%20path%20below%20is%20relative%20to%20this%20notebook's%20location%20(%60examples%2Fclass%2F%60)%3B%20the%20bundled%20datasets%20live%20in%20%60examples%2Fdata%2F%60.%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%20mad_bldgs%20%3D%20gpd.read_file(%22..%2Fdata%2Fmadrid_buildings%2Fmadrid_bldgs.gpkg%22)%0A%0A%20%20%20%20mad_bldgs.head()%0A%20%20%20%20return%20(mad_bldgs%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%20The%20%60head()%60%20method%20shows%20the%20first%20few%20rows%20of%20the%20GeoDataFrame%2C%20including%20the%20geometry%20column.%20The%20CRS%20is%20automatically%20detected%20and%20set.%0A%0A%20%20%20%20%23%23%23%20Plotting%0A%0A%20%20%20%20Let's%20plot%20the%20data.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mad_bldgs)%3A%0A%20%20%20%20mad_bldgs.plot()%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%20To%20zoom%20in%20when%20plotting%2C%20you%20can%20set%20your%20x%20and%20y-axis%20limits.%20For%20a%20cleaner%20plot%2C%20it%20is%20also%20generally%20preferable%20to%20turn%20off%20the%20axes%20so%20that%20the%20coordinates%20do%20not%20render.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mad_bldgs)%3A%0A%20%20%20%20_ax%20%3D%20mad_bldgs.plot()%0A%20%20%20%20_ax.set_xlim(439000%2C%20442000)%0A%20%20%20%20_ax.set_ylim(4473000%2C%204476000)%0A%20%20%20%20_ax.axis(%22off%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%20Let's%20create%20a%20new%20column%20named%20%60area%60%2C%20which%20we%20will%20set%20to%20the%20value%20of%20each%20geometry's%20area.%20Then%2C%20we%20will%20plot%20the%20data%20again%2C%20this%20time%20rendering%20the%20colour%20according%20to%20the%20building's%20area.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mad_bldgs)%3A%0A%20%20%20%20mad_bldgs%5B%22area%22%5D%20%3D%20mad_bldgs.geometry.area%0A%20%20%20%20_ax%20%3D%20mad_bldgs.plot(%0A%20%20%20%20%20%20%20%20column%3D%22area%22%2C%0A%20%20%20%20%20%20%20%20cmap%3D%22viridis%22%2C%0A%20%20%20%20%20%20%20%20vmax%3D10000%2C%0A%20%20%20%20%20%20%20%20legend%3DTrue%2C%0A%20%20%20%20%20%20%20%20legend_kwds%3D%7B%22label%22%3A%20%22Building%20footprint%20area%20(m%C2%B2)%22%2C%20%22shrink%22%3A%200.6%7D%2C%0A%20%20%20%20)%0A%20%20%20%20_ax.set_title(%22Buildings%20coloured%20by%20footprint%20area%22)%0A%20%20%20%20_ax.set_xlim(439000%2C%20442000)%0A%20%20%20%20_ax.set_ylim(4473000%2C%204476000)%0A%20%20%20%20_ax.axis(%22off%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%23%20Saving%20Data%0A%0A%20%20%20%20GeoPandas%20can%20save%20GeoDataFrames%20to%20various%20formats%2C%20including%20Shapefiles%2C%20GeoPackages%2C%20and%20GeoJSON%20files.%20The%20%60to_file()%60%20method%20is%20used%20for%20this%20purpose.%20You%20can%20specify%20the%20format%20using%20the%20%60driver%60%20parameter.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mad_bldgs)%3A%0A%20%20%20%20mad_bldgs.to_file(%22bldgs_w_area.gpkg%22%2C%20driver%3D%22GPKG%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%23%20Exercises%0A%0A%20%20%20%20-%20Load%20the%20bundled%20buildings%20GeoPackage%20and%20filter%20to%20only%20buildings%20with%20an%20area%20greater%20than%20500%20square%20metres.%20How%20many%20remain%3F%0A%20%20%20%20-%20Reproject%20the%20buildings%20GeoDataFrame%20to%20EPSG%3A4326%20(WGS%2084)%20and%20plot%20the%20result.%20What%20changes%3F%0A%20%20%20%20-%20Create%20a%20new%20column%20called%20%60perimeter%60%20containing%20each%20building's%20perimeter%20length.%20Plot%20the%20buildings%20coloured%20by%20perimeter.%0A%20%20%20%20-%20Create%20a%20%60Point%60%20geometry%20for%20a%20location%20of%20your%20choice%20and%20calculate%20the%20distance%20from%20each%20building's%20centroid%20to%20that%20point.%20Which%20building%20is%20closest%3F%0A%0A%20%20%20%20%23%23%20Summary%0A%0A%20%20%20%20-%20GeoPandas%20extends%20pandas%20with%20a%20geometry%20column%20and%20CRS%20support%2C%20bridging%20tabular%20data%20analysis%20with%20spatial%20operations.%0A%20%20%20%20-%20Use%20%60.loc%5B%5D%60%20and%20boolean%20masks%20to%20index%20and%20filter%20rows%20by%20attribute%20or%20spatial%20properties.%0A%20%20%20%20-%20%60to_crs()%60%20transforms%20between%20coordinate%20reference%20systems%3B%20always%20use%20a%20projected%20CRS%20for%20distance%20and%20area%20calculations.%0A%20%20%20%20-%20Spatial%20operations%20like%20%60buffer%60%20and%20%60distance%60%20work%20element-wise%20across%20the%20GeoDataFrame.%0A%20%20%20%20-%20%60read_file()%60%20and%20%60to_file()%60%20handle%20common%20spatial%20formats%20(GeoPackage%2C%20Shapefile%2C%20GeoJSON).%0A%0A%20%20%20%20Next%3A%20%5BUrban%20Analytics%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fstart%2F5-urban)%20introduces%20%60osmnx%60%20for%20downloading%20OSM%20data%20and%20%60momepy%60%20for%20morphological%20analysis.%20The%20skills%20from%20this%20chapter%20are%20used%20extensively%20in%20the%20%5BNetwork%20Preparation%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fnetworks)%20and%20%5BStatistics%5D(https%3A%2F%2Fcityseer.benchmarkurbanism.com%2Fexamples%2Fstats)%20recipes.%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
120f1a00bb267001a57c233096ecb691