Coordinate Reference Systems (CRS)

Understand coordinate reference systems and how they relate to GeoJSON and web mapping.

What is a Coordinate Reference System?

A Coordinate Reference System (CRS) defines how geographic coordinates map to real locations on Earth. It specifies:

  • A datum — a mathematical model of the Earth's shape (e.g., WGS 84 uses an ellipsoid)
  • A coordinate system — how positions are expressed (e.g., degrees of latitude/longitude, or meters on a grid)
  • A projection (for projected CRS) — how the 3D Earth is flattened onto a 2D surface

Without knowing the CRS, coordinates are just numbers. The same pair [500000, 4649776] could be in UTM Zone 33N (a point in Italy) or something entirely different in another system.

GeoJSON and CRS: The Rules

RFC 7946 is explicit: all GeoJSON coordinates must use WGS 84 (EPSG:4326) with coordinates in decimal degrees as [longitude, latitude].

The older 2008 GeoJSON specification allowed a crs member to declare alternative coordinate systems. RFC 7946 removed this. If you encounter GeoJSON with a crs field, it was written against the outdated spec and should be converted to WGS 84.

GeoJSON// This is NOT valid RFC 7946 GeoJSON
{
  "type": "FeatureCollection",
  "crs": {
    "type": "name",
    "properties": { "name": "urn:ogc:def:crs:EPSG::3857" }
  },
  "features": [ ... ]
}

If you receive data like this, reproject the coordinates to WGS 84 and remove the crs member.

Common Coordinate Reference Systems

EPSG CodeNameUsage
4326WGS 84GPS, GeoJSON, most web APIs. Units: degrees.
3857Web MercatorGoogle Maps, Mapbox, Leaflet tile layers. Units: meters.
4269NAD83North American data (USGS, Statistics Canada). Units: degrees.
32601–32660UTM Zones (WGS 84)Surveying, engineering, military. Units: meters.
2154RGF93 / Lambert-93French national mapping. Units: meters.
27700OSGB 1936British Ordnance Survey. Units: meters.
4674SIRGAS 2000South American data. Units: degrees.

WGS 84 vs Web Mercator

These two are commonly confused:

WGS 84 (EPSG:4326) — A geographic CRS using latitude and longitude in degrees. This is what GeoJSON uses and what GPS receivers output.

Web Mercator (EPSG:3857) — A projected CRS using meters. Web map tiles (Google, Mapbox, OpenStreetMap) use this projection internally. It distorts areas significantly at high latitudes — Greenland appears as large as Africa, though it's 14 times smaller.

When working with GeoJSON, your coordinates are always in EPSG:4326. Mapping libraries handle the reprojection to Web Mercator for display automatically.

Why WGS 84 for GeoJSON?

The RFC 7946 authors chose WGS 84 as the single required CRS for good reasons:

  • Universal compatibility — every mapping library, GPS device, and geospatial API understands WGS 84
  • No ambiguity — consumers never need to guess or detect the CRS
  • Global coverage — works everywhere on Earth, unlike regional systems like UTM zones or national grids
  • Simplicity — coordinates are intuitive decimal degrees that humans can read and verify

Converting Between Coordinate Systems

If your data isn't in WGS 84, you need to reproject before creating GeoJSON. Common tools:

GDAL/OGR (command line)

Shellogr2ogr -f GeoJSON -t_srs EPSG:4326 output.geojson input.shp

Python (pyproj)

Pythonfrom pyproj import Transformer

transformer = Transformer.from_crs("EPSG:3857", "EPSG:4326", always_xy=True)
lon, lat = transformer.transform(x_meters, y_meters)

JavaScript (proj4js)

JavaScriptimport proj4 from "proj4";

// Define source CRS (British National Grid)
proj4.defs("EPSG:27700", "+proj=tmerc +lat_0=49 +lon_0=-2 ...");

const [lon, lat] = proj4("EPSG:27700", "EPSG:4326", [530000, 180000]);

PostGIS

SQL (PostGIS)SELECT ST_AsGeoJSON(
  ST_Transform(geom, 4326)
) FROM my_table;

QGIS: Right-click a layer → Export → Save Features As → set CRS to EPSG:4326 and format to GeoJSON.

Coordinate Order Confusion

Different systems use different coordinate orders, which is a constant source of bugs:

SystemOrderExample (London)
GeoJSON / WKTlongitude, latitude-0.1276, 51.5074
Google Maps APIlatitude, longitude51.5074, -0.1276
Leaflet L.latLng()latitude, longitude51.5074, -0.1276
GPS (NMEA)latitude, longitude51.5074, -0.1276
EPSG:4326 (strict)latitude, longitude51.5074, -0.1276

Note the irony: EPSG:4326 technically defines lat/lon order, but GeoJSON uses lon/lat. This is a deliberate choice by the GeoJSON spec authors to match the mathematical convention of [x, y].

Use our Coordinate Flip Tool if your coordinates are in the wrong order.

EPSG Codes Explained

EPSG codes are numeric identifiers maintained by the IOGP (International Association of Oil & Gas Producers) in the EPSG Geodetic Parameter Dataset. They provide a shorthand way to reference complete CRS definitions:

  • EPSG:4326 = WGS 84 geographic (lat/lon in degrees)
  • EPSG:3857 = WGS 84 / Pseudo-Mercator (meters)
  • EPSG:32633 = WGS 84 / UTM zone 33N (meters)

You can look up any EPSG code at epsg.io for its full definition, bounds, and proj4 string.

Tips for Working with CRS

  • Always check the CRS of your source data before converting to GeoJSON. Shapefiles have a .prj file; databases have SRID columns.
  • Don't mix coordinate systems in a single dataset. Reproject everything to WGS 84 first.
  • Choose an appropriate CRS when performing distance and area calculations. A planar coordinate system is best for localized data, such as UTM whereas a geographic coordinate system, such as WGS 84, is best for global data. Just remember to do geodesic calculations when using a geographic coordinate system!

Common EPSG Codes

The following EPSG codes appear in the vast majority of geospatial workflows. Understanding what each one represents and when to use it will save hours of debugging.

EPSG CodeNameUnitsWhen to Use
4326WGS 84Degrees (lon/lat)GeoJSON (required by RFC 7946), GPS data, web APIs, data exchange between systems. This is the default CRS for nearly all geospatial web services.
3857Web MercatorMeters (x/y)Web map tile rendering (Google Maps, Mapbox, OpenStreetMap, Leaflet basemaps). Coordinates range from roughly -20,037,508 to 20,037,508 meters. Not suitable for area or distance calculations due to severe distortion away from the equator.
32632WGS 84 / UTM Zone 32NMeters (easting/northing)Surveying and engineering in Europe (covers 6°E to 12°E). UTM zones provide high accuracy within their 6-degree-wide bands. Each zone has its own EPSG code: 32601 (zone 1N) through 32660 (zone 60N) for the northern hemisphere, and 32701 through 32760 for the southern hemisphere.
27700OSGB 1936 / British National GridMeters (easting/northing)Ordnance Survey mapping in Great Britain. Coordinates use a transverse Mercator projection centered on 2°W. Easting values range from 0 to 700,000 and northing from 0 to 1,300,000. Required for UK government datasets and OS data products.
4269NAD83Degrees (lon/lat)North American data from USGS, US Census Bureau, Statistics Canada, and INEGI (Mexico). Practically identical to WGS 84 for most purposes (sub-meter difference), but technically a different datum.
2154RGF93 v1 / Lambert-93Meters (easting/northing)French national mapping and official government datasets. Uses a Lambert conformal conic projection. Easting values center around 700,000 meters.

You can look up the full definition, bounds, and proj4 string for any EPSG code at epsg.io. For example, epsg.io/4326 shows the WGS 84 definition, its valid geographic extent, and conversion parameters.

How to Check Your Data's CRS

Before converting any dataset to GeoJSON, you must confirm its CRS. Using the wrong assumption leads to coordinates that are displaced by hundreds or thousands of kilometers.

Shapefiles: Check the .prj File

Every Shapefile should include a .prj file containing the CRS definition in Well-Known Text (WKT) format. Open it in any text editor:

Shellcat my_data.prj
# Output example:
# GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],
# PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]

If the .prj file references GCS_WGS_1984 or EPSG:4326, the data is already in the correct CRS for GeoJSON. If it references something else (e.g., British_National_Grid or NAD83_UTM_Zone_10N), you need to reproject.

ogrinfo (GDAL Command Line)

The ogrinfo utility from GDAL reports the CRS along with other metadata for any supported vector format:

Shellogrinfo -al -so my_data.shp
# Look for the "Layer SRS WKT:" section in the output
# It will show the full CRS definition

ogrinfo -al -so my_data.geojson
# GeoJSON files should report EPSG:4326

QGIS Layer Properties

In QGIS, right-click any layer in the Layers panel, select Properties, and open the Information tab. The CRS is displayed under Coordinate Reference System, including the EPSG code, proj4 string, and extent in native units. You can also see the CRS in the bottom-right corner of the QGIS window for the current project.

GeoJSON Files

Valid RFC 7946 GeoJSON is always EPSG:4326. If the coordinates look like large numbers (e.g., [530000, 180000] instead of [-0.1, 51.5]), the data was likely exported from a projected CRS without reprojecting. Check for a legacy crs member in the file — if present, it indicates the original CRS before the data was incorrectly labeled as GeoJSON.

PostGIS

Query the SRID of a geometry column directly:

SQL (PostGIS)SELECT Find_SRID('public', 'my_table', 'geom');
-- Returns: 4326

-- Or check a specific geometry
SELECT ST_SRID(geom) FROM my_table LIMIT 1;

Common CRS Mistakes

CRS-related bugs are among the most frequent issues in geospatial work. Here are the mistakes that cause the most wasted time.

Mixing EPSG:4326 and EPSG:3857 Without Reprojecting

EPSG:4326 coordinates are in degrees (e.g., [-73.98, 40.75]) while EPSG:3857 coordinates are in meters (e.g., [-8235851, 4975773]). Plotting 3857 data on a 4326 map — or vice versa — places features in the wrong location entirely. A point that should be in New York City ends up near the null island at [0, 0] in the Gulf of Guinea, or off the map altogether.

Fix: always reproject to a common CRS before combining datasets. For GeoJSON output, that target is always EPSG:4326.

Assuming All Latitude/Longitude Data is WGS 84

NAD83 (EPSG:4269) and WGS 84 (EPSG:4326) both use degrees, and their coordinates differ by less than 2 meters in most of North America. However, older datums like NAD27 (EPSG:4267) can differ from WGS 84 by up to 200 meters. ED50 (EPSG:4230), used in older European datasets, diverges by 100+ meters from WGS 84. Always verify the datum, not just the coordinate format.

Forgetting the SRID in PostGIS

When importing GeoJSON into PostGIS with ST_GeomFromGeoJSON, the resulting geometry may have SRID 0 (unknown) rather than 4326. Spatial operations that compare geometries with different SRIDs will fail. Always wrap with ST_SetSRID(..., 4326) after parsing GeoJSON.

Using Web Mercator for Area or Distance Calculations

EPSG:3857 distorts areas dramatically at high latitudes. A polygon measured in Web Mercator at 60°N will report an area roughly 4 times its true size. For accurate measurements, use a local projected CRS (like the appropriate UTM zone) or cast to the PostGIS geography type, which computes on the ellipsoid.

Swapping Latitude and Longitude

GeoJSON uses [longitude, latitude] order. Many APIs and tools use [latitude, longitude]. If your points appear reflected across the diagonal (ending up in the ocean when they should be on land), the coordinates are likely swapped. Use our Coordinate Flip Tool to fix this.

Further Reading