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 .prj says 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:

  1. 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.
  2. 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.

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:

  1. 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.
  2. Reproject. Vector ▸ Data Management Tools ▸ Reproject Layer (algorithm native:reprojectlayer), target EPSG:32633. This writes a new layer with recalculated coordinates.
  3. 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.
  4. 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.

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 layer to 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

Sources