fio-l1-vienna-shapefile-recovery
Map (reference ← swipe → agent)
0:00
I'm migrating an old parcel shapefile (`parcels.shp`) into our web viewer, and a reference file `column_map.csv` is provided alongside it. Can you produce a clean GeoJSON `parcels.geojson` with the correct full column names and proper character encoding? The features should come through as Polygon or MultiPolygon.
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
column_map.csv parcels.cpg parcels.dbf parcels.prj parcels.shp parcels.shx
0:02
Read
column_map.csv
1 truncated,original
2 KATASTRALG,KATASTRALGEMEINDE_NAME
3 GRUNDSTUEC,GRUNDSTUECKSNUMMER
4 EIGENTUEME,EIGENTUEMER_NAME
5 WIDMUNG_BE,WIDMUNG_BEZEICHNUNG
6 STRASSE_NA,STRASSE_NAME
7 FLAECHE_M2,FLAECHE_M2
0:41
Write
/work/solve.py
content · 78 lines · py
import geopandas as gpd
import pandas as pd
import json
def main():
# Load column map
# The CSV seems to have a slightly non-standard format based on the Read output.
# Let's try reading it with pandas.
# Looking at the content: " 1\ttruncated,original"
# It looks like tab or spaces are used for the index and then a comma.
# Actually, it looks like a header "index truncated,original" but the first column is index.
column_map_df = pd.read_csv('column_map.csv', sep=None, engine='python')
# The first column might be an index or 'id'
# Let's inspect columns
print("Column map columns:", column_map_df.columns.tolist())
print("Column map content:\n", column_map_df)
# Load shapefile
gdf = gpd.read_file('parcels.shp')
print("Shapefile columns:", gdf.columns.tolist())
print("Shapefile head:\n", gdf.head())
# Create a mapping dictionary from the CSV
# We need to map the OLD name (truncated/short name in shp) to the NEW name (original name in csv)
# Wait, looking at the CSV:
# 2 KATASTRALG,KATASTRALGEMEINDE_NAME
# This means 'KATASTRALG' is the existing name in the shapefile and 'KATASTRALGEMEINDE_NAME' is what we want.
# Let's re-examine the CSV format.
# ' 1\ttruncated,original'
# It seems it's a CSV where the first column is an ID, the second is 'truncated', the third is 'original'.
# But 'truncated,original' are on the same line as the first ID?
# Or is it a header?
# Let's check the first few lines of the file content again.
# " 1\ttruncated,original"
# " 2\tKATASTRALG,KATASTRALGEMEINDE_NAME"
# It looks like it's tab-separated for the first two columns and comma-separated for the rest?
# No, it looks like it's: ID [TAB] truncated [COMMA] original.
# Let's try a more robust way to parse this specific file format.
mapping = {}
with open('column_map.csv', 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
if ',' in line and '\t' in line:
# Split by tab first to get the ID and the rest
parts = line.strip().split('\t')
if len(parts) >= 2:
# parts[1] contains "truncated,original"
sub_parts = parts[1].split(',')
if len(sub_parts) == 2:
truncated = sub_parts[0].strip()
original = sub_parts[1].strip()
# Skip the header row
if truncated != 'truncated':
mapping[truncated] = original
print("Mapping dictionary:", mapping)
# Rename columns in gdf
# We only rename columns that exist in gdf
rename_dict = {old: new for old, new in mapping.items() if old in gdf.columns}
gdf = gdf.rename(columns=rename_dict)
print("Renamed columns. New columns:", gdf.columns.tolist())
# Ensure geometries are Polygon or MultiPolygon
# GeoPandas handles this usually, but let's filter or ensure.
# Some shapes might be points or lines if the data is messy.
gdf = gdf[gdf.geometry.type.isin(['Polygon', 'MultiPolygon'])]
# Save to GeoJSON
gdf.to_file('parcels.geojson', driver='GeoJSON')
print("Successfully saved parcels.geojson")
if __name__ == "__main__":
main()
Wrote /work/solve.py (3378 chars).
0:43
Bash
python solve.py
Column map columns: ['truncated', 'original']
Column map content:
truncated original
0 KATASTRALG KATASTRALGEMEINDE_NAME
1 GRUNDSTUEC GRUNDSTUECKSNUMMER
2 EIGENTUEME EIGENTUEMER_NAME
3 WIDMUNG_BE WIDMUNG_BEZEICHNUNG
4 STRASSE_NA STRASSE_NAME
5 FLAECHE_M2 FLAECHE_M2
Shapefile columns: ['KATASTRALG', 'GRUNDSTUEC', 'EIGENTUEME', 'WIDMUNG_BE', 'STRASSE_NA', 'FLAECHE_M2', 'geometry']
Shapefile head:
KATASTRALG ... geometry
0 Innere Stadt ... POLYGON ((625700 483400, 625700 483425, 625730...
1 Mariahilf ... POLYGON ((625732 483400, 625732 483425, 625762...
2 Währing ... POLYGON ((625764 483400, 625764 483425, 625794...
3 Döbling ... POLYGON ((625796 483400, 625796 483425, 625826...
4 Hütteldorf ... POLYGON ((625828 483400, 625828 483425, 625858...
[5 rows x 7 columns]
Mapping dictionary: {}
Renamed columns. New columns: ['KATASTRALG', 'GRUNDSTUEC', 'EIGENTUEME', 'WIDMUNG_BE', 'STRASSE_NA', 'FLAECHE_M2', 'geometry']
Successfully saved parcels.geojson
1:02
Write
/work/solve.py
content · 41 lines · py
import geopandas as gpd
import pandas as pd
def main():
# The previous attempt at manual parsing failed (mapping was empty).
# Let's look at how pandas read it:
# truncated: KATASTRALG, original: KATASTRALGEMEINDE_NAME
# This means pandas correctly interpreted the CSV.
column_map_df = pd.read_csv('column_map.csv', sep=None, engine='python')
print("Column map columns:", column_map_df.columns.tolist())
print("Column map content:\n", column_map_df)
# Load shapefile
gdf = gpd.read_file('parcels.shp')
print("Shapefile columns:", gdf.columns.tolist())
# Create mapping dictionary from the DataFrame
# column_map_df has 'truncated' and 'original' columns
mapping = dict(zip(column_map_df['truncated'], column_map_df['original']))
print("Mapping dictionary:", mapping)
# Rename columns in gdf
# Note: We should only rename columns that exist in the shapefile.
# Also, 'geometry' is a reserved name in GeoPandas, so we must ensure we don't rename it.
rename_dict = {old: new for old, new in mapping.items() if old in gdf.columns}
gdf = gdf.rename(columns=rename_dict)
print("Renamed columns. New columns:", gdf.columns.tolist())
# Ensure geometries are Polygon or MultiPolygon
gdf = gdf[gdf.geometry.type.isin(['Polygon', 'MultiPolygon'])]
# Save to GeoJSON
# The requirement mentions "proper character encoding".
# GeoJSON is UTF-8 by default.
gdf.to_file('parcels.geojson', driver='GeoJSON')
print("Successfully saved parcels.geojson")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1594 chars).
1:04
Bash
python solve.py
Column map columns: ['truncated', 'original']
Column map content:
truncated original
0 KATASTRALG KATASTRALGEMEINDE_NAME
1 GRUNDSTUEC GRUNDSTUECKSNUMMER
2 EIGENTUEME EIGENTUEMER_NAME
3 WIDMUNG_BE WIDMUNG_BEZEICHNUNG
4 STRASSE_NA STRASSE_NAME
5 FLAECHE_M2 FLAECHE_M2
Shapefile columns: ['KATASTRALG', 'GRUNDSTUEC', 'EIGENTUEME', 'WIDMUNG_BE', 'STRASSE_NA', 'FLAECHE_M2', 'geometry']
Mapping dictionary: {'KATASTRALG': 'KATASTRALGEMEINDE_NAME', 'GRUNDSTUEC': 'GRUNDSTUECKSNUMMER', 'EIGENTUEME': 'EIGENTUEMER_NAME', 'WIDMUNG_BE': 'WIDMUNG_BEZEICHNUNG', 'STRASSE_NA': 'STRASSE_NAME', 'FLAECHE_M2': 'FLAECHE_M2'}
Renamed columns. New columns: ['KATASTRALGEMEINDE_NAME', 'GRUNDSTUECKSNUMMER', 'EIGENTUEMER_NAME', 'WIDMUNG_BEZEICHNUNG', 'STRASSE_NAME', 'FLAECHE_M2', 'geometry']
Successfully saved parcels.geojson
1:07
Bash
head -n 20 parcels.geojson
{
"type": "FeatureCollection",
"name": "parcels",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::31287" } },
"features": [
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Innere Stadt", "GRUNDSTUECKSNUMMER": "0013/1", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Mariahilfer Straße", "FLAECHE_M2": 750.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625700.0, 483400.0 ], [ 625700.0, 483425.0 ], [ 625730.0, 483425.0 ], [ 625730.0, 483400.0 ], [ 625700.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Mariahilf", "GRUNDSTUECKSNUMMER": "0020/2", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Döblinger Hauptstraße", "FLAECHE_M2": 751.25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625732.0, 483400.0 ], [ 625732.0, 483425.0 ], [ 625762.0, 483425.0 ], [ 625762.0, 483400.0 ], [ 625732.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Währing", "GRUNDSTUECKSNUMMER": "0027/3", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Währinger Gürtel", "FLAECHE_M2": 752.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625764.0, 483400.0 ], [ 625764.0, 483425.0 ], [ 625794.0, 483425.0 ], [ 625794.0, 483400.0 ], [ 625764.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Döbling", "GRUNDSTUECKSNUMMER": "0034/4", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Höfergasse", "FLAECHE_M2": 753.75 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625796.0, 483400.0 ], [ 625796.0, 483425.0 ], [ 625826.0, 483425.0 ], [ 625826.0, 483400.0 ], [ 625796.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Hütteldorf", "GRUNDSTUECKSNUMMER": "0041/5", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Schönbrunner Allee", "FLAECHE_M2": 755.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625828.0, 483400.0 ], [ 625828.0, 483425.0 ], [ 625858.0, 483425.0 ], [ 625858.0, 483400.0 ], [ 625828.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Floridsdorf", "GRUNDSTUECKSNUMMER": "0048/6", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Bäckerstraße", "FLAECHE_M2": 750.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625860.0, 483400.0 ], [ 625860.0, 483425.0 ], [ 625890.0, 483425.0 ], [ 625890.0, 483400.0 ], [ 625860.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Brigittenau", "GRUNDSTUECKSNUMMER": "0055/7", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Naschmarkt", "FLAECHE_M2": 751.25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625892.0, 483400.0 ], [ 625892.0, 483425.0 ], [ 625922.0, 483425.0 ], [ 625922.0, 483400.0 ], [ 625892.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Schönbrunn", "GRUNDSTUECKSNUMMER": "0062/8", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Mariahilfer Straße", "FLAECHE_M2": 752.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625924.0, 483400.0 ], [ 625924.0, 483425.0 ], [ 625954.0, 483425.0 ], [ 625954.0, 483400.0 ], [ 625924.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Innere Stadt", "GRUNDSTUECKSNUMMER": "0069/9", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Döblinger Hauptstraße", "FLAECHE_M2": 753.75 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625956.0, 483400.0 ], [ 625956.0, 483425.0 ], [ 625986.0, 483425.0 ], [ 625986.0, 483400.0 ], [ 625956.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Mariahilf", "GRUNDSTUECKSNUMMER": "0076/1", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Währinger Gürtel", "FLAECHE_M2": 755.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625988.0, 483400.0 ], [ 625988.0, 483425.0 ], [ 626018.0, 483425.0 ], [ 626018.0, 483400.0 ], [ 625988.0, 483400.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Währing", "GRUNDSTUECKSNUMMER": "0083/2", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Höfergasse", "FLAECHE_M2": 750.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625700.5, 483427.0 ], [ 625700.5, 483452.0 ], [ 625730.5, 483452.0 ], [ 625730.5, 483427.0 ], [ 625700.5, 483427.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Döbling", "GRUNDSTUECKSNUMMER": "0090/3", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Schönbrunner Allee", "FLAECHE_M2": 751.25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625732.5, 483427.0 ], [ 625732.5, 483452.0 ], [ 625762.5, 483452.0 ], [ 625762.5, 483427.0 ], [ 625732.5, 483427.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Hütteldorf", "GRUNDSTUECKSNUMMER": "0097/4", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Bäckerstraße", "FLAECHE_M2": 752.5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625764.5, 483427.0 ], [ 625764.5, 483452.0 ], [ 625794.5, 483452.0 ], [ 625794.5, 483427.0 ], [ 625764.5, 483427.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Floridsdorf", "GRUNDSTUECKSNUMMER": "0104/5", "EIGENTUEMER_NAME": "Schönbrunner Bauges. m.b.H.", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Naschmarkt", "FLAECHE_M2": 753.75 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625796.5, 483427.0 ], [ 625796.5, 483452.0 ], [ 625826.5, 483452.0 ], [ 625826.5, 483427.0 ], [ 625796.5, 483427.0 ] ] ] } },
{ "type": "Feature", "properties": { "KATASTRALGEMEINDE_NAME": "Brigittenau", "GRUNDSTUECKSNUMMER": "0111/6", "EIGENTUEMER_NAME": "Müller GmbH", "WIDMUNG_BEZEICHNUNG": "Wohngebiet", "STRASSE_NAME": "Mariahilfer Straße", "FLAECHE_M2": 755.0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 625828.5, 483427.0 ], [ 625828.5, 483452.0 ], [ 625858.5, 483452.0 ], [ 625858.5, 483427.0 ], [ 625828.5, 483427.0 ] ] ] } },
1:28