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:03
Bash
head -n 20 paris_buildings_wgs84.geojson
{
"type": "FeatureCollection",
"name": "paris_buildings_wgs84",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": "007591b9-c632-4d57-8bd2-144f82cfdd73", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3597498, 48.8570399 ], [ 2.3597608, 48.8570499 ], [ 2.3598145, 48.8571068 ], [ 2.3598435, 48.8571291 ], [ 2.359806, 48.8571492 ], [ 2.3597163, 48.8570555 ], [ 2.3597328, 48.8570478 ], [ 2.3597498, 48.8570399 ] ] ] } },
{ "type": "Feature", "properties": { "id": "00fac4fe-168a-4116-b287-6a28f34c87df", "class": "hotel", "subtype": "commercial", "name": "Hôtel de Nice", "height": null, "num_floors": 7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3558066, 48.8565792 ], [ 2.3558201, 48.8565761 ], [ 2.355847, 48.8566201 ], [ 2.3558588, 48.8566176 ], [ 2.3559027, 48.8566953 ], [ 2.3558801, 48.8567021 ], [ 2.3557818, 48.856724 ], [ 2.3557422, 48.8566535 ], [ 2.3557293, 48.8566307 ], [ 2.355756, 48.856591 ], [ 2.3558066, 48.8565792 ] ] ] } },
{ "type": "Feature", "properties": { "id": "020eefa5-5685-4f26-bd27-5b2bbd276bec", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3572011, 48.8572525 ], [ 2.3572582, 48.8572755 ], [ 2.3572304, 48.8572879 ], [ 2.3571022, 48.8573444 ], [ 2.3570724, 48.8573171 ], [ 2.3570455, 48.8572899 ], [ 2.3570759, 48.8572763 ], [ 2.3570906, 48.857296 ], [ 2.3571193, 48.8572856 ], [ 2.3571116, 48.8572727 ], [ 2.3570988, 48.857277 ], [ 2.3570899, 48.8572701 ], [ 2.3571344, 48.8572517 ], [ 2.3570889, 48.8571907 ], [ 2.3571324, 48.8571707 ], [ 2.3571965, 48.8572473 ], [ 2.3572011, 48.8572525 ] ] ] } },
{ "type": "Feature", "properties": { "id": "030e5772-d9af-4df1-9d7c-75d629eeca2d", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3576144, 48.8554387 ], [ 2.3575176, 48.8554725 ], [ 2.3574425, 48.8553782 ], [ 2.3575422, 48.8553435 ], [ 2.3576734, 48.8554183 ], [ 2.3576144, 48.8554387 ] ] ] } },
{ "type": "Feature", "properties": { "id": "0468c0c0-8ee9-4000-a0c1-514c803c86ee", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3563341, 48.858202 ], [ 2.3563562, 48.8581947 ], [ 2.3565055, 48.8583418 ], [ 2.3562074, 48.8584452 ], [ 2.3561355, 48.8583597 ], [ 2.3560759, 48.8582882 ], [ 2.3561163, 48.8582744 ], [ 2.3563341, 48.858202 ] ] ] } },
{ "type": "Feature", "properties": { "id": "04eec0bf-2cf3-436b-be28-5a17310179a4", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3593621, 48.8570356 ], [ 2.3593057, 48.8570501 ], [ 2.3593865, 48.8571298 ], [ 2.3592946, 48.8571673 ], [ 2.3592538, 48.8571923 ], [ 2.3591646, 48.8571264 ], [ 2.3591789, 48.8571161 ], [ 2.3591532, 48.8571066 ], [ 2.3591395, 48.8571171 ], [ 2.3591133, 48.8571072 ], [ 2.3591417, 48.8570895 ], [ 2.3591806, 48.8570624 ], [ 2.3591223, 48.8569857 ], [ 2.3591185, 48.8569791 ], [ 2.3592878, 48.8569268 ], [ 2.3593217, 48.8569787 ], [ 2.3593126, 48.8569826 ], [ 2.3593621, 48.8570356 ] ], [ [ 2.3592979, 48.8570841 ], [ 2.359273, 48.8570541 ], [ 2.3592526, 48.8570618 ], [ 2.3592822, 48.8570911 ], [ 2.3592979, 48.8570841 ] ] ] } },
{ "type": "Feature", "properties": { "id": "051dfb19-9a71-4127-8522-63bf20232528", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3581223, 48.8581081 ], [ 2.3580964, 48.8580772 ], [ 2.3584975, 48.857856 ], [ 2.3585364, 48.8578936 ], [ 2.3584542, 48.8579474 ], [ 2.3583045, 48.8580455 ], [ 2.3581774, 48.8581295 ], [ 2.3581578, 48.8581275 ], [ 2.3581367, 48.8581253 ], [ 2.3581223, 48.8581081 ] ] ] } },
{ "type": "Feature", "properties": { "id": "0707091a-10c6-4669-b6ed-55166847839e", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3573039, 48.8571135 ], [ 2.3572826, 48.8571208 ], [ 2.3572282, 48.8570585 ], [ 2.357222, 48.8570514 ], [ 2.3571732, 48.8569955 ], [ 2.3573448, 48.8569306 ], [ 2.3573136, 48.856893 ], [ 2.3574243, 48.8568539 ], [ 2.3575378, 48.8568138 ], [ 2.3575632, 48.8568051 ], [ 2.3576794, 48.8567629 ], [ 2.3578134, 48.8567165 ], [ 2.3578419, 48.8567066 ], [ 2.3579102, 48.8566833 ], [ 2.3580018, 48.8567988 ], [ 2.3579785, 48.8568061 ], [ 2.3578495, 48.8568467 ], [ 2.3578249, 48.8568547 ], [ 2.3577854, 48.8568662 ], [ 2.3576943, 48.8569005 ], [ 2.357741, 48.8569661 ], [ 2.3577062, 48.8569778 ], [ 2.3576648, 48.8569913 ], [ 2.3575549, 48.8570275 ], [ 2.3573039, 48.8571135 ] ], [ [ 2.3575937, 48.8568607 ], [ 2.3575442, 48.8568789 ], [ 2.3573572, 48.8569455 ], [ 2.3573748, 48.8569681 ], [ 2.3573225, 48.8569871 ], [ 2.3573677, 48.8570433 ], [ 2.3574221, 48.8570234 ], [ 2.3574185, 48.8570203 ], [ 2.3575226, 48.8569831 ], [ 2.3575195, 48.8569766 ], [ 2.3575983, 48.8569478 ], [ 2.3576068, 48.8569586 ], [ 2.3576598, 48.8569415 ], [ 2.3575937, 48.8568607 ] ] ] } },
{ "type": "Feature", "properties": { "id": "07142702-50fc-4469-9fec-687e5719d2e5", "class": "", "subtype": "", "name": "", "height": null, "num_floors": 5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3573095, 48.8587292 ], [ 2.3572626, 48.8586874 ], [ 2.3573894, 48.8586176 ], [ 2.3574152, 48.85864 ], [ 2.3574534, 48.858621 ], [ 2.3574255, 48.8585971 ], [ 2.3574634, 48.8585761 ], [ 2.3575101, 48.8586154 ], [ 2.3574314, 48.8586636 ], [ 2.3574052, 48.8586809 ], [ 2.3573095, 48.8587292 ] ] ] } },
{ "type": "Feature", "properties": { "id": "071f77d5-75e3-4a98-89de-44f9a945aa44", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3565534, 48.8564198 ], [ 2.3565814, 48.8564286 ], [ 2.3566114, 48.8564826 ], [ 2.3564514, 48.8565169 ], [ 2.3564064, 48.8564365 ], [ 2.3564507, 48.8564258 ], [ 2.3565194, 48.8564091 ], [ 2.3565534, 48.8564198 ] ] ] } },
{ "type": "Feature", "properties": { "id": "07949552-5a76-4fe6-ba80-efa54e8b0688", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3563841, 48.8579286 ], [ 2.3564188, 48.8579083 ], [ 2.3564408, 48.8578943 ], [ 2.3564942, 48.8579492 ], [ 2.3564604, 48.857966 ], [ 2.3564275, 48.8579796 ], [ 2.3563841, 48.8579286 ] ] ] } },
{ "type": "Feature", "properties": { "id": "07ae479c-aa1a-4096-8c0d-4aa3d77d6c68", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3558582, 48.8583412 ], [ 2.3558805, 48.8583346 ], [ 2.3559207, 48.8583788 ], [ 2.3559434, 48.8584057 ], [ 2.3559652, 48.8583978 ], [ 2.3559826, 48.858419 ], [ 2.3559799, 48.8584201 ], [ 2.3559791, 48.8584223 ], [ 2.3559256, 48.8584407 ], [ 2.3559394, 48.8584582 ], [ 2.355925, 48.8584647 ], [ 2.3559556, 48.8585025 ], [ 2.3559606, 48.8585011 ], [ 2.3559961, 48.8585458 ], [ 2.3560893, 48.8585128 ], [ 2.3562946, 48.8587651 ], [ 2.3562546, 48.8587793 ], [ 2.3562817, 48.8588068 ], [ 2.3561865, 48.8588431 ], [ 2.3561537, 48.8588004 ], [ 2.3561489, 48.8588015 ], [ 2.3560707, 48.8587033 ], [ 2.3559915, 48.8586048 ], [ 2.3557874, 48.8583621 ], [ 2.3558582, 48.8583412 ] ] ] } },
{ "type": "Feature", "properties": { "id": "085195c0-034d-4763-994a-37cf71a53f1b", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3570164, 48.8568157 ], [ 2.3570464, 48.8568041 ], [ 2.3571038, 48.8567839 ], [ 2.3571104, 48.8567891 ], [ 2.3571663, 48.8567698 ], [ 2.3572235, 48.8567482 ], [ 2.357284, 48.8567257 ], [ 2.3573256, 48.8567861 ], [ 2.357207, 48.8568283 ], [ 2.3570701, 48.8568769 ], [ 2.3570214, 48.8568214 ], [ 2.3570164, 48.8568157 ] ] ] } },
{ "type": "Feature", "properties": { "id": "08e6b740-11e7-434c-8387-97797166f85a", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": 5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3573754, 48.8587838 ], [ 2.3573095, 48.8587292 ], [ 2.3574052, 48.8586809 ], [ 2.3574314, 48.8586636 ], [ 2.3574943, 48.8587156 ], [ 2.35745, 48.858741 ], [ 2.3574313, 48.8587518 ], [ 2.3573786, 48.858782 ], [ 2.3573754, 48.8587838 ] ] ] } },
{ "type": "Feature", "properties": { "id": "0955376b-191f-4230-85e0-7c79b20a94ba", "class": "apartments", "subtype": "residential", "name": "", "height": null, "num_floors": null }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 2.3576954, 48.8575906 ], [ 2.3576496, 48.857536 ], [ 2.3578871, 48.8574519 ], [ 2.3579379, 48.8574355 ], [ 2.3579755, 48.8574873 ], [ 2.3579546, 48.8574944 ], [ 2.3579672, 48.8575123 ], [ 2.3578471, 48.8575511 ], [ 2.3577027, 48.8575994 ], [ 2.3576954, 48.8575906 ] ] ] } },
0:12
Write
solve.py
content · 58 lines · py
import geopandas as gpd
from shapely.geometry import Polygon, MultiPolygon
def ensure_polygon(geom):
"""
Ensures that the geometry is a Polygon.
If it's a MultiPolygon, it takes the largest constituent polygon.
"""
if isinstance(geom, Polygon):
return geom
elif isinstance(geom, MultiPolygon):
if len(geom.geoms) > 0:
# Return the largest polygon by area to avoid losing too much information
return max(geom.geoms, key=lambda p: p.area)
else:
return None
return None
def solve():
# Input file
input_file = 'paris_buildings_wgs84.geojson'
output_file = 'paris_buildings_lambert93.gpkg'
# Load the data
print(f"Loading {input_file}...")
gdf = gpd.read_file(input_file)
# Check CRS. GeoJSON is usually EPSG:4326.
print(f"Current CRS: {gdf.crs}")
# Target CRS: Lambert 93 (EPSG:2154) is the standard official projection for France
target_crs = 'EPSG:2154'
# Convert to Lambert 93
print(f"Converting to {target_crs}...")
gdf = gdf.to_crs(target_crs)
# Ensure all geometries are plain Polygons
print("Ensuring geometries are Polygons...")
gdf['geometry'] = gdf['geometry'].apply(ensure_polygon)
# Remove any features that became None (though unlikely with buildings)
gdf = gdf[gdf['geometry'].notnull()]
# Write to GeoPackage
# The requirement says to use 'id' as the key.
# In GeoPackage/OGR, the primary key is usually an internal integer,
# but we can ensure 'id' is preserved in the attributes.
# We'll use the 'id' column for the output.
print(f"Writing to {output_file}...")
gdf.to_file(output_file, driver='GPKG')
print("Done!")
if __name__ == "__main__":
solve()
Wrote solve.py (1812 chars).
0:13
Bash
python solve.py
Loading paris_buildings_wgs84.geojson... Current CRS: EPSG:4326 Converting to EPSG:2154... Ensuring geometries are Polygons... Writing to paris_buildings_lambert93.gpkg... Done!
0:21
Bash
python -c "import geopandas as gpd; gdf = gpd.read_file('paris_buildings_lambert...
CRS: EPSG:2154 Geometry types: <ArrowStringArray> ['Polygon'] Length: 1, dtype: str First 5 IDs: ['007591b9-c632-4d57-8bd2-144f82cfdd73', '00fac4fe-168a-4116-b287-6a28f34c87df', '020eefa5-5685-4f26-bd27-5b2bbd276bec', '030e5772-d9af-4df1-9d7c-75d629eeca2d', '0468c0c0-8ee9-4000-a0c1-514c803c86ee'] First 5 Geometries: 0 POLYGON ((653023.358 6862079.654, 653024.174 6... 1 POLYGON ((652733.625 6862030.782, 652734.612 6... 2 POLYGON ((652836.551 6862104.813, 652840.761 6... 3 POLYGON ((652865.234 6861902.887, 652858.162 6... 4 POLYGON ((652773.799 6862210.907, 652775.414 6... Name: geometry, dtype: geometry
0:25
Bash
ls -F
paris_buildings_lambert93.gpkg paris_buildings_wgs84.geojson solve.py
0:36