fio-l2-capetown-landuse-dissolve
Map (reference ← swipe → agent)
0:00
I'm prepping a transit-corridor study for the Cape Town metro, and I need a class-level summary of `landuse` so the team's spatial-SQL notebooks can join it against the bus-route table. Can you give me one row per landuse class with the geometry unified into a single MultiPolygon, the total area in m², and the count of source parcels that fed in? Please write the result to `landuse_dissolved.geoparquet` with `class`, `area_m2`, and `parcel_count` columns.
0:00
System info
{
"adapter": "openrouter",
"model": "google/gemma-4-26b-a4b-it",
"base_url": "https://openrouter.ai/api/v1"
}
0:01
Bash
ls -F
capetown_landuse.fgb
0:02
Bash
python -c "import geopandas as gpd; print(gpd.read_file('capetown_landuse.fgb')....
id ... geometry 0 f328c054-b040-3a7d-a015-53747d608fef ... MULTIPOLYGON (((872000.605 6252622.417, 871205... 1 f1943847-f785-390c-abb0-edc923f97997 ... MULTIPOLYGON (((253543.223 6283900.241, 254921... 2 c37e40aa-f202-3b15-b68d-89dafeeaa478 ... MULTIPOLYGON (((255047.308 6280773.284, 255024... 3 b9d39db7-5dcc-379e-bfeb-c994628df5a7 ... MULTIPOLYGON (((254978.723 6280842.179, 254992... 4 0033302c-c1d6-3624-b71e-0e300db64963 ... MULTIPOLYGON (((264759.63 6280552.85, 264825.5... [5 rows x 4 columns]
0:05
Bash
python -c "import geopandas as gpd; print(gpd.read_file('capetown_landuse.fgb')....
['id', 'class', 'subtype', 'geometry']
0:21
Write
/work/solve.py
content · 57 lines · py
import geopandas as gpd
def main():
# Load the data
gdf = gpd.read_file('capetown_landuse.fgb')
# Ensure we are in a projected CRS to calculate area in m2 correctly
# If the data is already projected (UTM/Lo), we'll use it.
# If it's EPSG:4326, we must reproject.
if gdf.crs.is_geographic:
print("Reprojecting to UTM Zone 34S (EPSG:32734) for accurate area calculation...")
gdf = gdf.to_crs(epsg=32734)
else:
print(f"Using existing CRS: {gdf.crs}")
# Group by 'class'
# We need:
# 1. Dissolved geometry (MultiPolygon)
# 2. Total area (sum of areas)
# 3. Count of original parcels
# First, calculate area of each individual parcel in the projected CRS
gdf['area_m2_parcel'] = gdf.geometry.area
# Grouping and aggregating
# dissolved: we'll use unary_union via groupby.apply or dissolve()
# total area: sum of parcel areas
# parcel count: count of rows per group
print("Dissolving landuse classes...")
# The dissolve() method is highly efficient for this
dissolved = gdf.dissolve(by='class', aggfunc={
'area_m2_parcel': 'sum',
'id': 'count'
})
# Rename columns to match requirements
dissolved = dissolved.rename(columns={
'area_m2_parcel': 'area_m2',
'id': 'parcel_count'
})
# Reset index so 'class' becomes a column
dissolved = dissolved.reset_index()
# Select/Order columns as requested
# requested: 'class', 'area_m2', 'parcel_count'
result = dissolved[['class', 'area_m2', 'parcel_count', 'geometry']]
# Write to GeoParquet
print(f"Writing result to landuse_dissolved.geoparquet...")
result.to_parquet('landuse_dissolved.geoparquet')
print("Done.")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1793 chars).
0:22
Bash
python /work/solve.py
Using existing CRS: EPSG:32734 Dissolving landuse classes... Writing result to landuse_dissolved.geoparquet... Done.
0:28
Bash
python -c "import geopandas as gpd; df = gpd.read_parquet('landuse_dissolved.geo...
class ... geometry 0 airfield ... POLYGON ((267829.758 6244743.665, 267820.919 6... 1 allotments ... MULTIPOLYGON (((263870.512 6232477.907, 263865... 2 animal_keeping ... MULTIPOLYGON (((264114.249 6261265.896, 264220... 3 barracks ... MULTIPOLYGON (((262288.681 6215543.331, 262280... 4 base ... POLYGON ((272069.73 6245748.538, 272064.541 62... [5 rows x 4 columns] ['class', 'area_m2', 'parcel_count', 'geometry']
0:31
Bash
python -c "import geopandas as gpd; df = gpd.read_parquet('landuse_dissolved.geo...
class ... geometry 0 airfield ... POLYGON ((267829.758 6244743.665, 267820.919 6... 1 allotments ... MULTIPOLYGON (((263870.512 6232477.907, 263865... 2 animal_keeping ... MULTIPOLYGON (((264114.249 6261265.896, 264220... 3 barracks ... MULTIPOLYGON (((262288.681 6215543.331, 262280... 4 base ... POLYGON ((272069.73 6245748.538, 272064.541 62... [5 rows x 4 columns]
0:39