Short answer
Most "my data jumped" problems are not projection problems — they are datum problems. Changing a map projection (say UTM to Web Mercator within WGS 84) does not move anything on the ground; changing the datum — the reference frame that ties coordinates to the Earth — physically relocates every point, by anything from sub-metre to several hundred metres. The danger is that GIS software will often apply a null or low-accuracy transformation silently, so the map still looks plausible while every position is systematically off. The fix is to know your source datum, choose an appropriate transformation (frequently a grid like NTv2), and verify against control.
Datum vs projection: keep them separate
A coordinate reference system has two independent parts:
- The datum (geodetic reference frame): an ellipsoid plus a realisation that fixes its position and orientation relative to the Earth — for example NAD27, NAD83, WGS 84, ETRS89, GDA94/GDA2020.
- The projection: the math that flattens that ellipsoid onto a plane — UTM, Lambert Conformal Conic, Web Mercator.
Reprojecting within one datum is exact and shifts nothing on the ground. Going between datums requires a datum transformation, and this is where positional error enters. EPSG codes bundle datum and projection together, so changing the EPSG code can quietly imply a datum change you did not consciously request. EPSG:4326 (WGS 84) and EPSG:4269 (NAD83) are nearly but not exactly the same; EPSG:4267 (NAD27) differs from NAD83 by tens to over a hundred metres depending on location.
Why a wrong transformation is invisible
The reason datum errors are dangerous is that they are consistent and smooth. A 30 m offset across an entire dataset does not break topology, does not throw an error, and does not look wrong on a zoomed-out map. It only surfaces when the layer is overlaid with correctly-transformed data, measured against a survey monument, or used for cadastral, engineering, or hazard work where metres matter. By then the analysis is done.
A common silent failure is the null transformation (the so-called "+towgs84=0,0,0" or an EPSG transformation with no parameters): the software treats two datums as identical because no better operation was selected or available. For NAD27↔NAD83 that null assumption is wrong by up to ~100 m in the continental US.
Transformation methods, in order of accuracy
Several families exist; pick the most accurate one whose area of use covers your data:
- Grid-based (NTv2,
.gsb): a regular grid of latitude/longitude corrections interpolated per point. This is the highest-accuracy general method and is the standard for transformations like NAD27→NAD83, OSGB36→ETRS89, and many national realisations. Accuracy is typically sub-metre to a few centimetres where the grid is published. - Geocentric / Helmert (3- or 7-parameter): translation (and for 7-parameter, rotation and scale) applied in geocentric XYZ. Good for continental-scale transforms; accuracy commonly a metre to several metres for 3-parameter, better for well-fitted 7-parameter.
- Time-dependent (14-parameter): needed between modern, plate-fixed frames where coordinates drift with tectonic motion (e.g. ITRF realisations, GDA94 vs GDA2020), accounting for the epoch.
PROJ ships many of these and can download the required grids from its CDN (or you install the proj-data package). The right choice depends on the datum pair, the region, and the accuracy you need.
Worked example: inspecting and pinning a transformation
Before trusting a transform, look at what PROJ will actually do. For NAD27 to NAD83 over the conterminous US:
projinfo -s EPSG:4267 -t EPSG:4269 --summary
This lists candidate operations with their accuracy and area of use. A grid-based operation (e.g. using the NADCON or NTv2 grids) will report sub-metre accuracy; a fallback null/ballpark operation will report something like "unknown / 999 m" — a red flag. Choose the grid-based one and pin it so every run is identical:
echo "POINT(-100.0 40.0)" | \
cs2cs EPSG:4267 EPSG:4269 \
--area "USA - CONUS" -d 8
In QGIS, Settings ▸ Options ▸ CRS Handling lets you set transformation defaults and enable a prompt; when you reproject between datums, QGIS shows the candidate operations with their accuracies and area of use. Always pick the one with the smallest stated accuracy whose area of use covers your data, and prefer grid-based operations when offered. The chosen operation is recorded in the project, which makes the decision auditable.
In PostGIS, datum-aware transforms go through the same PROJ engine via ST_Transform; for control over the pipeline you can use ST_Transform(geom, target_srid) knowing the database's PROJ has the relevant grids installed, and ST_SetSRID only to declare a missing SRID (never to change datums).
When you do and do not need a transformation
- No transformation needed: same datum, different projection (e.g. ETRS89/UTM 32N → ETRS89/LAEA). PROJ applies an exact, parameter-free operation.
- Transformation needed: any datum change. ETRS89 vs WGS 84 are within ~1 m and often treated as equivalent for mapping, but NAD27 vs NAD83, OSGB36 vs ETRS89, and old vs new national datums require a real transformation, ideally a grid.
- Epoch matters: high-precision work between dynamic frames must specify the coordinate epoch, or tectonic drift introduces a growing error.
Validation: prove the datum step worked
- Control points: transform a known survey monument or trig point and compare to its published coordinates in the target datum. Agreement to the transformation's stated accuracy confirms success.
- Overlay growth test: a residual offset that grows toward the edges of the extent is the signature of a missing or wrong datum transformation, because the error is spatially varying.
- Inspect the operation used: in QGIS read the applied datum transformation in the project properties; with PROJ use
projinfo/cs2csoutput. If accuracy reads "999 m" or "unknown", you used a null transform. - Round-trip check: transform A→B→A and confirm you return to the original within tolerance.
Common mistakes and why they happen
- Assuming WGS 84 ≈ NAD27. They differ by up to ~100 m. The map looks fine, the positions are wrong. Fix: apply a grid-based NAD27→NAD83 transform.
- Accepting the default/null transformation. Software picks the only available operation, which may be a ballpark or null one. Fix: enable the prompt, choose the highest-accuracy operation covering your area.
- Confusing assign-SRID with transform.
ST_SetSRID(or QGIS "set CRS") relabels; it does not move data across datums. Fix: useST_Transformfor an actual datum change. - Missing PROJ grids. Without the
.gsb/grid files, PROJ falls back to a lower-accuracy operation. Fix: installproj-dataor allow the PROJ network grid download. - Ignoring epoch on dynamic datums. GDA94 vs GDA2020 and ITRF realisations drift over time. Fix: specify the epoch for precise work.
Bathyl perspective
We record the datum transformation as part of the deliverable's provenance — source datum, target datum, the exact operation chosen, and its stated accuracy — because a position is only as defensible as the reference frame behind it. A clean-looking map sitting 40 m off true is worse than an obviously broken one, since nobody questions it. Making the datum chain explicit is what lets a reviewer trust the coordinates without re-surveying them.
Related reading
- QGIS Reproject Layer Workflow
- QGIS Raster Reprojection Workflow
- Why Buffers Are Wrong in Degrees
- Why Area Calculations Are Wrong in Latitude Longitude
- GIS and spatial analysis