Short answer
Reprojecting a vector layer in QGIS is exact — every vertex is recalculated, with no resampling and no data loss — but the operation is only correct if the layer's declared source CRS is right before you start. The two failure modes are confusing assigning a CRS (relabelling coordinates) with reprojecting them (recomputing coordinates), and trusting on-the-fly display alignment as if it changed the data on disk. Get the source CRS right, choose a target CRS that matches your measurement task, write a new file, and verify.
Assign vs reproject: the distinction that causes most errors
These are two completely different operations and QGIS lets you do both, which is why they get mixed up.
- Assign / set CRS changes only the label. It tells QGIS "interpret these existing numbers as belonging to this CRS." The coordinates themselves do not move. You assign a CRS only when the file's declared CRS is missing or genuinely wrong — for example a shapefile whose coordinates are clearly UTM metres but whose
.prjsays EPSG:4326. - Reproject recalculates the coordinates into a new CRS and writes them out. A point at (450000, 4650000) in UTM becomes a new longitude/latitude pair. This is the operation you want almost every time you "want a layer in another CRS."
The classic mistake is assigning a CRS to "move" a layer onto the basemap. If the source coordinates were correct, assigning a different CRS sends the layer to the wrong place; if they were wrong, assigning fixes the label but you still then need to reproject. Decide first: are the numbers right and I want different numbers (reproject), or are the numbers right but the label is wrong (assign)?
On-the-fly reprojection is display only
QGIS reprojects layers on the fly to render mixed-CRS data in one project CRS. This is a convenience for viewing, not a transformation of your files. Two consequences matter:
- Layers can look perfectly aligned while the files on disk are in different CRSs. The moment you export, run a Processing tool that respects layer CRS, or hand the data to someone with a different project CRS, the mismatch reappears.
- Measurement and analysis tools use the layer's own CRS (or the project CRS / ellipsoid for the measure tool), not the display. A layer in EPSG:4326 will produce buffers and areas in degrees regardless of how nicely it sits on a metric basemap.
Confirm the source CRS before you touch anything
Never trust the label blindly. Inspect both the declared CRS and the raw coordinate values, because the coordinates themselves tell you which CRS is plausible.
ogrinfo -al -so layer.shpreports the declared SRS plus the layer extent. If the SRS says EPSG:4326 but the extent reads651000 6862000 : 660000 6871000, the declaration is lying — those are metres, not degrees.- Degrees fall in the range roughly -180 to 180 and -90 to 90. Anything larger is a projected system.
- UTM eastings are typically 160000–834000; northings up to ~9300000. A "false easting" of 500000 is the giveaway for a UTM or Transverse Mercator zone.
- For a shapefile, check that the
.prjsidecar exists at all. A missing.prjmeans the layer has no declared CRS, which is a metadata problem to fix by assigning, not a transformation problem.
If you genuinely do not know the CRS, overlay the layer on a trusted reference (an OpenStreetMap basemap, a known administrative boundary) after trying a candidate CRS. The correct CRS is the one under which the features land on the right real-world locations.
Choosing the target CRS by task
There is no single "best" CRS — choose by what you are about to measure:
- Distance and local area in metres: the appropriate UTM zone for your longitude (e.g. EPSG:32633 for zone 33N) or a national grid (EPSG:27700 British National Grid, EPSG:2154 RGF93 / Lambert-93). These minimise distortion within their zone.
- Area over a wide region: an equal-area projection such as ETRS89-LAEA (EPSG:3035) for Europe or an Albers equal-area for a country.
- Web display / tiles: Web Mercator (EPSG:3857) — but never for measurement, because its scale factor grows toward the poles and inflates areas and distances dramatically away from the equator.
- Storage of raw lat/long: EPSG:4326 is fine as an archival/exchange CRS; just reproject before any metric calculation.
Worked workflow
For a delivery where you receive points in WGS 84 (EPSG:4326) and need 500 m buffers and area statistics in metres for an area around 13°E, 41°N:
- Verify the source CRS. Right-click ▸ Properties ▸ Information; confirm EPSG:4326 and that the coordinates fall in the expected degree range. If they are large numbers (hundreds of thousands), the CRS label is wrong — assign the real one first.
- Reproject. Vector ▸ Data Management Tools ▸ Reproject Layer (algorithm
native:reprojectlayer), target EPSG:32633. This writes a new layer with recalculated coordinates. - Buffer in the projected layer. Now a 500 m buffer is genuinely 500 m. Buffering the EPSG:4326 layer with "500" would mean 500 degrees, which is meaningless.
- Save with the CRS recorded so the next person inherits the right reference.
The command-line equivalent, useful for batch jobs, is:
ogr2ogr -s_srs EPSG:4326 -t_srs EPSG:32633 \
-f GPKG points_utm33.gpkg points_wgs84.gpkg
-s_srs only needs to be set if the source CRS is missing or wrong; if the file declares it correctly, ogr2ogr -t_srs EPSG:32633 out.gpkg in.gpkg is enough. If your data lives in PostGIS, the same transform is ST_Transform(geom, 32633), and you set a missing SRID with ST_SetSRID(geom, 4326) (the database analogue of assign, not reproject).
Datum transformations hide in the EPSG change
Changing the EPSG code can involve a datum shift, not just a map-projection change. Going from NAD27 to NAD83, or any transform crossing datums, may require a transformation grid (NTv2 / .gsb) to be metre-accurate. QGIS shows available datum transformations and a stated accuracy; PROJ supplies the pipeline. If you skip this, layers can be offset by tens to hundreds of metres — small enough to miss on a zoomed-out map, large enough to ruin a cadastral or engineering deliverable. Set Settings ▸ Options ▸ CRS Handling to prompt for the transformation so the choice is explicit and logged.
Datum shifts that commonly bite:
- NAD27 (EPSG:4267) to NAD83 (EPSG:4269) in North America. The shift varies by location and can exceed 100 m without the NADCON/HARN grid.
- ED50 to ETRS89 in Europe: tens of metres up to roughly 200 m depending on country.
- WGS84 vs ETRS89: now roughly 0.5 to 0.8 m apart due to plate motion. Fine to ignore for mapping, not for survey-grade work.
If the PROJ grid files are absent, PROJ falls back to a lower-accuracy null or three-parameter shift without failing, which is a quiet source of metre-level error. With GDAL you can pin the operation explicitly with ogr2ogr -ct "<PROJ pipeline>".
Validation: prove the reprojection is correct
- Measure a known control distance in the reprojected layer with the measure tool and compare against a survey value or a trusted reference. The numbers should agree to within projection distortion (sub-metre to a few metres within a UTM zone).
- Overlay a trusted reference layer and check alignment at the corners of the extent, not just the centre — datum errors grow outward.
- Inspect attribute-free geometry: vertex count should be unchanged by reprojection (it moves vertices, it does not add or remove them).
ogrinfo -so out.gpkg layerto confirm the written SRS and feature count.
Common mistakes and why they happen
- Assigning when you meant to reproject. Relabels coordinates and physically dislocates the layer. Fix: reproject; only assign to correct a wrong/missing label.
- Measuring in a geographic CRS. Buffers and areas come out in degrees. The map looks right because of on-the-fly display, so the error is invisible. Fix: reproject to a projected CRS first.
- Web Mercator for analysis. Its area/distance scale error is enormous away from the equator. Fix: reserve EPSG:3857 for tiles, use UTM/LAEA for measurement.
- Skipping the datum transformation prompt. Silent offsets of tens of metres. Fix: enable the CRS-handling prompt and record the chosen transform.
- Treating on-the-fly as permanent. The file never changed. Fix: export/Reproject Layer to write a new file.
Bathyl perspective
We log a layer's reprojection chain the way a lab logs sample handling: declared source CRS, the assign-vs-reproject decision, the target CRS, and the datum transformation actually applied. A measurement is only as trustworthy as the coordinate chain behind it, so we make that chain visible enough for a reviewer to audit without rerunning the work.
Related reading
- QGIS Raster Reprojection Workflow
- Datum Transformations for GIS Teams
- QGIS Print Layout for Technical Maps
- QGIS vs ArcGIS for Geological and Terrain Workflows
- GIS and spatial analysis