dd-l1-vienna-gpkg-manifest
Map (reference ← swipe → agent)
0:00
Inherited a GPKG (vienna_planning) from a colleague who retired last week. Before I commit to scripting against it I need a one-page manifest so I can see what's in there and decide which layers actually feed next month's councillor briefing. Catalog the contents and give me one record per layer. Output manifest.json — a JSON list of these records.
Each record in the list must be a JSON object with exactly five keys: `layer_name` as a string, `crs` as a string in `EPSG:NNNN` form, `geometry_type` as a string matching the layer's native type (e.g. `Point`, `LineString`, `Polygon`, `MultiPolygon`), `feature_count` as an integer, and `bbox` as a list of four numbers `[xmin, ymin, xmax, ymax]` in the layer's native CRS.
0:00
System info
{
"adapter": "openrouter",
"model": "google/gemma-4-26b-a4b-it",
"base_url": "https://openrouter.ai/api/v1"
}
0:04
Bash
ls -F
vienna_planning.gpkg
0:28
Write
/work/solve.py
content · 51 lines · py
import geopandas as gpd
import json
def main():
gpkg_path = 'vienna_planning.gpkg'
# Get layer names
import fiona
layers = fiona.listlayers(gpkg_path)
manifest = []
for layer_name in layers:
gdf = gpd.read_file(gpkg_path, layer=layer_name)
# CRS: EPSG:NNNN form
# gdf.crs might be an object, we want the EPSG code
epsg_code = gdf.crs.to_epsg()
crs_str = f"EPSG:{epsg_code}" if epsg_code else str(gdf.crs)
# Geometry type
# gdf.geom_type returns the type of the geometry column (e.g., 'Polygon', 'MultiPolygon')
# We want the native type. Geopandas provides this.
# Note: if it's a mix, it might be 'GeometryCollection', but usually it's one of the standard ones.
# Let's check the first non-null geometry type or just the column type.
geom_type = gdf.geom_type.iloc[0] if not gdf.empty else "None"
# Feature count
feature_count = len(gdf)
# BBox [xmin, ymin, xmax, ymax]
if not gdf.empty:
bounds = gdf.total_bounds
bbox = [float(bounds[0]), float(bounds[1]), float(bounds[2]), float(bounds[3])]
else:
bbox = [0.0, 0.0, 0.0, 0.0]
manifest.append({
"layer_name": layer_name,
"crs": crs_str,
"geometry_type": geom_type,
"feature_count": feature_count,
"bbox": bbox
})
with open('manifest.json', 'w') as f:
json.dump(manifest, f, indent=4)
if __name__ == "__main__":
main()
Wrote /work/solve.py (1625 chars).
0:30
Bash
python solve.py
(no output)
0:36
Bash
cat manifest.json
[
{
"layer_name": "districts",
"crs": "EPSG:31287",
"geometry_type": "Polygon",
"feature_count": 22,
"bbox": [
623867.3888224852,
481236.5836125494,
626371.3079994549,
484403.7315526943
]
},
{
"layer_name": "parks",
"crs": "EPSG:31287",
"geometry_type": "MultiPolygon",
"feature_count": 119,
"bbox": [
623851.990195953,
481200.6674012489,
626620.9438865517,
485539.3479671855
]
},
{
"layer_name": "waterbodies",
"crs": "EPSG:31287",
"geometry_type": "Polygon",
"feature_count": 33,
"bbox": [
624288.8521056126,
481236.66320640914,
626747.8611584986,
484132.0212685799
]
},
{
"layer_name": "schools",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 40,
"bbox": [
624000.002417057,
481214.73871311604,
626259.5421406503,
484178.87865010765
]
},
{
"layer_name": "cafes",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 392,
"bbox": [
623796.529863561,
481107.2540129812,
626399.5618121764,
484498.9209005649
]
},
{
"layer_name": "supermarkets",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 87,
"bbox": [
623794.0549950565,
481148.38703723426,
626392.6164786755,
484489.91954147833
]
},
{
"layer_name": "cycleway_segments",
"crs": "EPSG:31287",
"geometry_type": "LineString",
"feature_count": 271,
"bbox": [
623787.4932131292,
481134.9325878215,
626619.1631922598,
485245.6624853243
]
}
]
0:54
Write
/work/solve.py
content · 62 lines · py
import geopandas as gpd
import json
import fiona
def main():
gpkg_path = 'vienna_planning.gpkg'
# Get layer names
layers = fiona.listlayers(gpkg_path)
manifest = []
for layer_name in layers:
gdf = gpd.read_file(gpkg_path, layer=layer_name)
# CRS: EPSG:NNNN form
# Try to get the EPSG code directly. If it fails, fallback to string representation.
try:
epsg_code = gdf.crs.to_epsg()
if epsg_code:
crs_str = f"EPSG:{epsg_code}"
else:
crs_str = str(gdf.crs)
except Exception:
crs_str = str(gdf.crs)
# Geometry type
# Geopandas 'geom_type' can return 'MultiPolygon' etc.
# We check the actual geometry type of the first feature.
if not gdf.empty:
# Get the most common geometry type or just the first one's type.
# The instruction says "matching the layer's native type".
# gdf.geom_type is a Series of types for each geometry.
# We'll take the most frequent one to be safe, or just the first.
geom_type = gdf.geom_type.mode()[0]
else:
geom_type = "None"
# Feature count
feature_count = len(gdf)
# BBox [xmin, ymin, xmax, ymax]
if not gdf.empty:
bounds = gdf.total_bounds
bbox = [float(bounds[0]), float(bounds[1]), float(bounds[2]), float(bounds[3])]
else:
bbox = [0.0, 0.0, 0.0, 0.0]
manifest.append({
"layer_name": layer_name,
"crs": crs_str,
"geometry_type": geom_type,
"feature_count": feature_count,
"bbox": bbox
})
with open('manifest.json', 'w') as f:
json.dump(manifest, f, indent=4)
if __name__ == "__main__":
main()
Wrote /work/solve.py (1918 chars).
0:58
Bash
python solve.py
(no output)
1:02
Bash
cat manifest.json
[
{
"layer_name": "districts",
"crs": "EPSG:31287",
"geometry_type": "Polygon",
"feature_count": 22,
"bbox": [
623867.3888224852,
481236.5836125494,
626371.3079994549,
484403.7315526943
]
},
{
"layer_name": "parks",
"crs": "EPSG:31287",
"geometry_type": "MultiPolygon",
"feature_count": 119,
"bbox": [
623851.990195953,
481200.6674012489,
626620.9438865517,
485539.3479671855
]
},
{
"layer_name": "waterbodies",
"crs": "EPSG:31287",
"geometry_type": "Polygon",
"feature_count": 33,
"bbox": [
624288.8521056126,
481236.66320640914,
626747.8611584986,
484132.0212685799
]
},
{
"layer_name": "schools",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 40,
"bbox": [
624000.002417057,
481214.73871311604,
626259.5421406503,
484178.87865010765
]
},
{
"layer_name": "cafes",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 392,
"bbox": [
623796.529863561,
481107.2540129812,
626399.5618121764,
484498.9209005649
]
},
{
"layer_name": "supermarkets",
"crs": "EPSG:31287",
"geometry_type": "Point",
"feature_count": 87,
"bbox": [
623794.0549950565,
481148.38703723426,
626392.6164786755,
484489.91954147833
]
},
{
"layer_name": "cycleway_segments",
"crs": "EPSG:31287",
"geometry_type": "LineString",
"feature_count": 271,
"bbox": [
623787.4932131292,
481134.9325878215,
626619.1631922598,
485245.6624853243
]
}
]
2:12