PlanLens

Coordinate systems

The same point has different numbers in different coordinate reference systems (CRS). Pick the wrong one for the job and distances and areas come out wrong, quietly.

Three systems in this project

CRSUnitsUsed forWatch out
EPSG:4326
WGS84 longitude / latitude
degreesGPS and GeoJSON. How this project stores geometry, after reprojecting the source data on import.A degree of longitude is shorter than a degree of latitude, and shrinks towards the poles.
EPSG:3857
Web Mercator
metres (on a stretched sphere)How OpenStreetMap tiles and Leaflet draw the map on screen.Distances and areas are inflated by 1/cos(latitude): about 1.6× in length and 2.7× in area in Warsaw.
EPSG:2180
PUWG 1992 (ETRF2000-PL / CS92)
metres (easting / northing)Poland's national grid. What GDOŚ and NID publish the source data in, and where this project measures area.Only meant for Poland. Its official axis order is northing first, which some services follow and others don't.

Try it: ST_Transform and distance

Enter two points. The database transforms them with ST_Transform and measures the gap four ways. Try the two presets: 0.01° east is about 680 m here but 0.01° north is about 1,110 m, so a degree is not a unit of length.

Point A
Point B

Running ST_Transform…

Why measure in 2180 or geography, not degrees

The lon/lat vs lat/lon pitfall

WhereRoyal Castle, WarsawOrder
GeoJSON position (RFC 7946)[21.0142, 52.2479][lng, lat]
PostGISST_MakePoint(21.0142, 52.2479)(x, y) = (lng, lat)
LeafletL.latLng(52.2479, 21.0142)[lat, lng]
This API?lat=52.2479&lng=21.0142named, so it cannot be swapped

Swap them and 52.2479, 21.0142 read as lng/lat is a point in the Arabian Peninsula's Empty Quarter. Both numbers are valid coordinates, so range checks cannot catch it. The app keeps points as { lat, lng } objects and only turns them into arrays in features/map/utils/coords.ts, the one place that knows both conventions.

Projected systems have the same trap. The two services this project downloads from both publish EPSG:2180, yet the GDOŚ request (WFS 1.0) takes its bounding box as easting,northing and the NID request (WFS 2.0, which follows the EPSG definition) as northing,easting. See scripts/lib/sources.ts.