crs-l1-paris-lambert93
Map (reference ← swipe → agent)
0:00
Our heat-loss model won't accept the `paris_buildings` file in lat/lon. It needs the coordinates in metres using the standard official projection for the Paris region. Can you convert the buildings over so the model can ingest them? Please leave the attributes alone, and keep every geometry as a plain Polygon rather than turning it into a MultiPolygon. Write the result as a GeoPackage to `paris_buildings_lambert93.gpkg`, and use `id` as the key.
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
paris_buildings_wgs84.geojson
0:14
Write
/work/solve.py
content · 49 lines · py
# /// script
# requires-python = ">=3.12"
# dependencies = ["geopandas", "shapely", "pyproj", "pyogrio"]
# ///
import geopandas as gpd
def main():
input_file = "paris_buildings_wgs84.geojson"
output_file = "paris_buildings_lambert93.gpkg"
# Load the data
print(f"Reading {input_file}...")
gdf = gpd.read_file(input_file)
# Check current CRS
print(f"Current CRS: {gdf.crs}")
# Convert to Lambert-93 (EPSG:2154)
# Lambert-93 is the standard official projection for France (RGF93 / Lambert-93)
print("Converting to EPSG:2154 (Lambert-93)...")
gdf = gdf.to_crs(epsg=2154)
# Ensure every geometry is a plain Polygon instead of a MultiPolygon
# The instruction says: "keep every geometry as a plain Polygon rather than turning it into a MultiPolygon"
# This usually means if we have a MultiPolygon, we should explode it into individual Polygons.
print("Exploding MultiPolygons into Polygons...")
gdf = gdf.explode(index_parts=False)
# The instruction says: "use `id` as the key" for the GeoPackage.
# In GeoPackage, this usually refers to the primary key.
# geopandas/pyogrio will write the index or a specific column as a key if configured,
# but typically we just ensure 'id' is a column and it's preserved.
# Let's check if 'id' exists or if we need to create it.
if 'id' not in gdf.columns:
print("Column 'id' not found, creating it from index...")
gdf['id'] = gdf.index
# Write to GeoPackage
print(f"Writing to {output_file}...")
# We use layer name 'buildings' or similar, but the instruction doesn't specify layer name.
# We will just write the file.
gdf.to_file(output_file, driver="GPKG")
print("Done.")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1808 chars).
0:21
Bash
uv run solve.py
Reading paris_buildings_wgs84.geojson... Current CRS: EPSG:4326 Converting to EPSG:2154 (Lambert-93)... Exploding MultiPolygons into Polygons... Writing to paris_buildings_lambert93.gpkg... Done.
Installed 10 packages in 269ms
0:39
Write
/work/solve.py
content · 56 lines · py
# /// script
# requires-python = ">=3.12"
# dependencies = ["geopandas", "shapely", "pyproj", "pyogrio"]
# ///
import geopandas as gpd
def main():
input_file = "paris_buildings_wgs84.geojson"
output_file = "paris_buildings_lambert93.gpkg"
# Load the data
print(f"Reading {input_file}...")
gdf = gpd.read_file(input_file)
# Check current CRS
print(f"Current CRS: {gdf.crs}")
# Convert to Lambert-93 (EPSG:2154)
print("Converting to EPSG:2154 (Lambert-93)...")
gdf = gdf.to_crs(epsg=2154)
# Explode MultiPolygons into Polygons
print("Exploding MultiPolygons into Polygons...")
gdf = gdf.explode(index_parts=False)
# Ensure 'id' is the first column and used as the index/key
# Many GIS models expect a unique integer 'id' column.
# If 'id' exists, we keep it. If not, we might need to create it.
# The instruction says "use `id` as the key".
if 'id' not in gdf.columns:
print("Column 'id' not found, creating it...")
gdf['id'] = range(len(gdf))
# Reorder columns to put 'id' first for good measure
cols = ['id'] + [c for c in gdf.columns if c != 'id']
gdf = gdf[cols]
# Write to GeoPackage
print(f"Writing to {output_file}...")
gdf.to_file(output_file, driver="GPKG")
# Verification
print("Verifying output...")
check_gdf = gpd.read_file(output_file)
print(f"Output CRS: {check_gdf.crs}")
print(f"Geometry type: {check_gdf.geom_type.unique()}")
print(f"Columns: {check_gdf.columns.tolist()}")
print(f"Number of rows: {len(check_gdf)}")
print("Done.")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1675 chars).
0:44
Bash
uv run solve.py
Reading paris_buildings_wgs84.geojson... Current CRS: EPSG:4326 Converting to EPSG:2154 (Lambert-93)... Exploding MultiPolygons into Polygons... Writing to paris_buildings_lambert93.gpkg... Verifying output... Output CRS: EPSG:2154 Geometry type: <StringArray> ['Polygon'] Length: 1, dtype: str Columns: ['id', 'class', 'subtype', 'name', 'height', 'num_floors', 'geometry'] Number of rows: 330 Done.
0:47
Bash
ls -F
paris_buildings_lambert93.gpkg paris_buildings_wgs84.geojson solve.py
1:01