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:02
Bash
ls -F
paris_buildings_wgs84.geojson
0:29
Write
/work/solve.py
content · 45 lines · py
import geopandas as gpd
def main():
# Load the buildings file
input_file = 'paris_buildings_wgs84.geojson'
output_file = 'paris_buildings_lambert93.gpkg'
print(f"Reading {input_file}...")
gdf = gpd.read_file(input_file)
# EPSG for Lambert-93 (standard official projection for France)
# EPSG:2154
lambert93_epsg = 2154
print(f"Reprojecting to EPSG:{lambert93_epsg}...")
gdf = gdf.to_crs(epsg=lambert93_epsg)
# Ensure geometries are plain Polygons instead of MultiPolygons.
# We can do this by exploding MultiPolygons into individual Polygons.
# The requirement says "keep every geometry as a plain Polygon rather than turning it into a MultiPolygon".
# Usually, this implies that if a building is a MultiPolygon, we want its constituent parts as separate rows.
# However, the instruction "keep every geometry as a plain Polygon" might also suggest that we shouldn't
# allow MultiPolygons to exist.
print("Exploding MultiPolygons to Polygons...")
gdf = gdf.explode(index_parts=False)
# The requirement says "use id as the key" in the GeoPackage.
# In GeoPackage context, this often means the primary key should be the 'id' column.
# However, when writing via geopandas/fiona, the 'id' column is usually just a column.
# We should ensure 'id' is present.
if 'id' not in gdf.columns:
# If it's not there, maybe it's called something else? Let's check.
print(f"Warning: 'id' column not found. Columns are: {gdf.columns.tolist()}")
print(f"Saving to {output_file}...")
# layer name isn't specified, using 'buildings'
gdf.to_file(output_file, driver="GPKG", layer="buildings")
print("Done!")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1795 chars).
0:31
Bash
python solve.py
Reading paris_buildings_wgs84.geojson... Reprojecting to EPSG:2154... Exploding MultiPolygons to Polygons... Saving to paris_buildings_lambert93.gpkg... Done!
0:55
Write
/work/solve.py
content · 43 lines · py
import geopandas as gpd
def main():
input_file = 'paris_buildings_wgs84.geojson'
output_file = 'paris_buildings_lambert93.gpkg'
print(f"Reading {input_file}...")
gdf = gpd.read_file(input_file)
# Check the columns
print(f"Initial columns: {gdf.columns.tolist()}")
# EPSG for Lambert-93
lambert93_epsg = 2154
print(f"Reprojecting to EPSG:{lambert93_epsg}...")
gdf = gdf.to_crs(epsg=lambert93_epsg)
print("Exploding MultiPolygons to Polygons...")
gdf = gdf.explode(index_parts=False)
# Check if 'id' exists and ensure it is used properly.
# The instruction "use id as the key" is slightly ambiguous for a GeoPackage
# but usually implies a primary key. Most GIS tools treat 'id' or 'fid'
# as the default primary key.
# Since we exploded, if 'id' was the original ID, we still have it.
# Ensure 'id' exists. If the input has 'id', we keep it.
# If it doesn't have 'id', we might need to create it, but let's assume it exists
# based on the prompt "use id as the key".
print(f"Final columns: {gdf.columns.tolist()}")
print(f"Saving to {output_file}...")
# We'll write it. GeoPackage handles the 'id' column as a primary key if specified,
# but by default fiona/geopandas will write the 'id' column.
gdf.to_file(output_file, driver="GPKG")
print("Done!")
if __name__ == "__main__":
main()
Wrote /work/solve.py (1449 chars).
1:06
Bash
python solve.py
Reading paris_buildings_wgs84.geojson... Initial columns: ['id', 'class', 'subtype', 'name', 'height', 'num_floors', 'geometry'] Reprojecting to EPSG:2154... Exploding MultiPolygons to Polygons... Final columns: ['id', 'class', 'subtype', 'name', 'height', 'num_floors', 'geometry'] Saving to paris_buildings_lambert93.gpkg... Done!
1:11
Bash
# Check if the output file exists and is a valid GeoPackage
# Check if the output file exists and is a valid GeoPackage ogrinfo -so paris_buildings_lambert93.gpkg
INFO: Open of `paris_buildings_lambert93.gpkg'
using driver `GPKG' successful.
1: buildings (Polygon)
2: paris_buildings_lambert93 (Polygon)
1:15
Bash
# Check if the 'id' column is there and if geometries are indeed Polygons.
# Check if the 'id' column is there and if geometries are indeed Polygons. ogrinfo -al -so paris_buildings_lambert93.gpkg
INFO: Open of `paris_buildings_lambert93.gpkg'
using driver `GPKG' successful.
Layer name: buildings
Geometry: Polygon
Feature Count: 330
Extent: (652677.960384, 6861856.825178) - (653039.282282, 6862296.829776)
Layer SRS WKT:
PROJCRS["RGF93 v1 / Lambert-93",
BASEGEOGCRS["RGF93 v1",
DATUM["Reseau Geodesique Francais 1993 v1",
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4171]],
CONVERSION["Lambert-93",
METHOD["Lambert Conic Conformal (2SP)",
ID["EPSG",9802]],
PARAMETER["Latitude of false origin",46.5,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8821]],
PARAMETER["Longitude of false origin",3,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8822]],
PARAMETER["Latitude of 1st standard parallel",49,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8823]],
PARAMETER["Latitude of 2nd standard parallel",44,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8824]],
PARAMETER["Easting at false origin",700000,
LENGTHUNIT["metre",1],
ID["EPSG",8826]],
PARAMETER["Northing at false origin",6600000,
LENGTHUNIT["metre",1],
ID["EPSG",8827]]],
CS[Cartesian,2],
AXIS["easting (X)",east,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["northing (Y)",north,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Engineering survey, topographic mapping."],
AREA["France - onshore and offshore, mainland and Corsica (France métropolitaine including Corsica)."],
BBOX[41.15,-9.86,51.56,10.38]],
ID["EPSG",2154]]
Data axis to CRS axis mapping: 1,2
FID Column = fid
Geometry Column = geom
id: String (0.0)
class: String (0.0)
subtype: String (0.0)
name: String (0.0)
height: Real (0.0)
num_floors: Real (0.0)
Layer name: paris_buildings_lambert93
Geometry: Polygon
Feature Count: 330
Extent: (652677.960384, 6861856.825178) - (653039.282282, 6862296.829776)
Layer SRS WKT:
PROJCRS["RGF93 v1 / Lambert-93",
BASEGEOGCRS["RGF93 v1",
DATUM["Reseau Geodesique Francais 1993 v1",
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4171]],
CONVERSION["Lambert-93",
METHOD["Lambert Conic Conformal (2SP)",
ID["EPSG",9802]],
PARAMETER["Latitude of false origin",46.5,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8821]],
PARAMETER["Longitude of false origin",3,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8822]],
PARAMETER["Latitude of 1st standard parallel",49,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8823]],
PARAMETER["Latitude of 2nd standard parallel",44,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8824]],
PARAMETER["Easting at false origin",700000,
LENGTHUNIT["metre",1],
ID["EPSG",8826]],
PARAMETER["Northing at false origin",6600000,
LENGTHUNIT["metre",1],
ID["EPSG",8827]]],
CS[Cartesian,2],
AXIS["easting (X)",east,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["northing (Y)",north,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Engineering survey, topographic mapping."],
AREA["France - onshore and offshore, mainland and Corsica (France métropolitaine including Corsica)."],
BBOX[41.15,-9.86,51.56,10.38]],
ID["EPSG",2154]]
Data axis to CRS axis mapping: 1,2
FID Column = fid
Geometry Column = geom
id: String (0.0)
class: String (0.0)
subtype: String (0.0)
name: String (0.0)
height: Real (0.0)
num_floors: Real (0.0)
1:24