CRS Governance and Reprojection Standards

Coordinate reference systems are the one dimension of a spatial product that cannot be renegotiated after the fact: get the CRS wrong and every distance, intersection, and join computed downstream is quietly incorrect while every schema field still validates. This reference sits inside Geospatial Data Mesh Fundamentals and defines how a federated estate governs CRS across many independently owned domains — declaring a canonical storage CRS, reprojecting only at domain boundaries, and delivering per output port in the projection each consumer expects. It builds directly on Spatial Domain Boundary Design, because the boundary is exactly where reprojection is allowed to happen, and on Metadata Cataloging for Raster/Vector, which records the declared crs_epsg that this governance enforces. The recurring failures it prevents are mundane and expensive: axis-order inversion, precision loss from repeated round-trips, and mercator-metre math applied to EPSG:4326 degrees.

Figure — Sources in mixed CRSs are reprojected to a canonical EPSG:4326 store at ingest, then reprojected again only at delivery into the projection each output port serves.

CRS reprojection flow from mixed sources through a canonical store to per-port delivery Three sources on the left in EPSG:4326, EPSG:32633 UTM 33N, and EPSG:3857 web mercator all flow into a single reproject step at the ingest boundary that converts them to EPSG:4326. The normalized data lands in a canonical store holding EPSG:4326 in lon/lat order as the single source of truth. From the store, delivery reprojects at the output boundary into two ports: EPSG:3857 vector tiles for web maps, and EPSG:4326 features for the OGC API. A note states that EPSG:4326 is stored and delivered lon/lat, with axis order asserted at every boundary. → 3857 → 4326 EPSG:4326 native source EPSG:32633 UTM 33N source EPSG:3857 web mercator src Reproject ingest boundary → EPSG:4326 Canonical store EPSG:4326 lon/lat single source of truth EPSG:3857 tiles web mercator MVT EPSG:4326 features OGC API Features Axis order: EPSG:4326 is stored and delivered lon/lat order asserted explicitly at every reprojection boundary

Architectural Boundaries & Design Rationale

CRS governance rests on one principle: there is exactly one canonical storage CRS for the mesh, and every product is reprojected into it at the moment it crosses an ingest boundary. This site standardizes on EPSG:4326 for canonical storage — the concrete rollout is documented in Standardizing on EPSG:4326 Across Domains — while delivery ports may serve any approved projection the consumer needs. Reprojection is confined to the two boundaries, ingest and delivery, and is forbidden in the interior. That confinement is not stylistic; it directly eliminates the failure modes that a federated estate accumulates when every domain reprojects wherever it likes.

Four concrete failures motivate the standard:

  • Axis-order inversion. EPSG:4326 is officially latitude-then-longitude, but most tooling and every GeoJSON payload use longitude-then-latitude. A domain that follows the authority order where its neighbours follow the tooling order produces geometry that lands in the wrong hemisphere. The contract must assert lon_lat explicitly, exactly as Data Contracts for Spatial Products records it.
  • Repeated round-trip precision loss. Reprojecting 4326 → 3857 → 4326 across successive interior hops accumulates floating-point drift and can shift vertices by centimetres to metres. Reprojecting only at boundaries caps the number of transforms a coordinate ever undergoes.
  • Mercator-metre math on degrees. A consumer that runs a buffer or distance query assuming metres against EPSG:4326 degrees computes a nonsense result that no schema check catches.
  • Silent cross-domain CRS mismatch. Two domains joined on a shared extent but stored in different CRSs produce empty or shifted joins. A single canonical store makes every interior geometry comparable by construction.

The delivery side is where governance meets consumer reality. A tile port serves EPSG:3857 because web map clients demand web mercator; a features port serves EPSG:4326 for OGC API Features. Both reproject from the canonical store at the output boundary, so the store never holds more than one projection and the ports never leak a non-canonical CRS back into storage.

Specification & Contract Reference

CRS governance is expressed as a small set of enforceable parameters attached to every domain and output port. These are validated at registration and at the boundary gate.

Parameter Scope Constraint / Convention Rationale
canonical_crs Mesh EPSG:4326 Single interior projection; never overridden per domain
canonical_axis_order Mesh lon_lat Explicit to defeat authority/tooling ambiguity
source_crs_allowlist Ingest [4326, 3857, 4269, 32610, 32611, 32633] Only approved projections may be reprojected in
reproject_boundaries Topology ingest, delivery Interior reprojection is prohibited
delivery_crs Output port 3857 (tiles) | 4326 (features) Per-port projection served to consumers
min_precision_decimals Quality 6 (~0.11 m) Guards against round-trip precision loss
transform_pipeline Governance Named PROJ pipeline or EPSG code Pinned so a transform is reproducible and auditable
datum_shift_grid Governance e.g. null | NAD83→WGS84 Declared when a datum shift is required, not implicit

The distinction between a bare CRS change and a datum shift matters: reprojecting EPSG:32633 to EPSG:4326 is a coordinate operation within the WGS 84 datum, whereas moving from EPSG:4269 (NAD83) involves a datum transformation whose grid must be declared and pinned. Leaving the datum shift implicit is how “correct” reprojections drift by a metre.

Production Implementation

Reprojection at a boundary must be idempotent and reproducible: the same input and the same pinned transform always yield byte-comparable geometry, and re-running the step never compounds error. Below, ogr2ogr normalizes an incoming vector source to the canonical EPSG:4326 at the ingest boundary, and a PostGIS ST_Transform produces the EPSG:3857 delivery view — followed by a validation query that proves the transform did not silently corrupt the extent. Zero-trust applies here too: the boundary trusts only the declared source CRS after verifying it against the allowlist, never a guessed projection.

bash
#!/usr/bin/env bash
set -euo pipefail

SRC="${1:?source dataset}"          # e.g. parcels_utm33.gpkg (EPSG:32633)
SRC_EPSG="${2:?declared source EPSG}"

# Zero-trust: refuse any source CRS outside the enterprise allowlist.
case "$SRC_EPSG" in
  4326|3857|4269|32610|32611|32633) ;;
  *) echo "FATAL: EPSG:${SRC_EPSG} not in source allowlist"; exit 1 ;;
esac

# Reproject to canonical EPSG:4326 at the ingest boundary.
# -s_srs is set explicitly (never trust the file's embedded CRS blindly);
# lon/lat axis order is forced so authority ordering cannot leak in.
ogr2ogr -f GPKG parcels_4326.gpkg "$SRC" \
  -s_srs "EPSG:${SRC_EPSG}" -t_srs EPSG:4326 \
  -lco GEOMETRY_NAME=geom --config OGR_CT_FORCE_TRADITIONAL_GIS_ORDER YES
echo "normalized ${SRC} (EPSG:${SRC_EPSG}) -> EPSG:4326"
sql
-- Canonical storage holds EPSG:4326; delivery views reproject at the output port.
-- ST_Transform is deterministic for a pinned source/target pair.
CREATE MATERIALIZED VIEW parcels_tiles_3857 AS
SELECT parcel_id,
       ST_Transform(geom, 3857) AS geom          -- delivery boundary → web mercator
FROM   parcels_4326;                             -- interior stays EPSG:4326

-- Validation: the reprojected extent must round-trip back within tolerance,
-- proving no axis flip or datum drift crept in at the boundary.
SELECT parcel_id
FROM   parcels_tiles_3857 t
JOIN   parcels_4326 c USING (parcel_id)
WHERE  NOT ST_Equals(
         ST_SnapToGrid(ST_Transform(t.geom, 4326), 0.000001),
         ST_SnapToGrid(c.geom, 0.000001)
       );
-- Zero rows returned == reprojection is lossless within 1e-6 degrees.

Run the validation query in CI after every reprojection change. A non-empty result set means the transform pipeline, the source CRS declaration, or the axis order is wrong — and the delivery view must be rebuilt before it is published, never patched in place.

Diagnostic Runbook

When consumers report geometry in the wrong place, empty joins, or distances that make no sense, isolate the CRS fault in order.

  1. Confirm the declared source CRS. Run ogrinfo -so -al source.gpkg | grep -i srs and compare against source_crs_allowlist. A source outside the allowlist should have been rejected at ingest. Remediation: reproject upstream to an allowlisted CRS or add the projection through a governed allowlist change, never silently.
  2. Check axis order. If features are mirrored or in the wrong hemisphere, the boundary likely honored authority lat/lon order. Remediation: force OGR_CT_FORCE_TRADITIONAL_GIS_ORDER YES (or PostGIS ST_FlipCoordinates on the offending set) and re-run.
  3. Detect interior reprojection. Search pipeline code for ST_Transform/-t_srs calls outside the ingest and delivery boundaries. Remediation: remove them; the interior must remain EPSG:4326.
  4. Measure round-trip drift. Run the validation query from the implementation section. Remediation: if rows return, pin the transform_pipeline and, for datum-shifted sources, install and declare the datum_shift_grid.
  5. Verify delivery projection. Confirm the tile port serves EPSG:3857 and the features port serves EPSG:4326 with ST_SRID(geom). Remediation: rebuild the materialized view with the correct target SRID.
  6. Reconcile against the catalog contract. Cross-check the served CRS against the declared crs_epsg recorded in Metadata Cataloging for Raster/Vector. Remediation: if they diverge, the contract or the port is wrong; treat any change to crs_epsg as a breaking version bump.

SLA Targets & Performance Baselines

CRS governance carries measurable guarantees that feed the mesh’s alerting.

Metric Target Alert Threshold Remediation Action
Round-trip reprojection error < 1e-6 degrees any row failing the validation query Pin transform pipeline; install datum grid
Non-canonical interior geometry 0 features any interior SRID ≠ 4326 Remove interior transform; re-normalize at ingest
Axis-order inversions 0 any mirrored feature detected Force lon/lat order; flip and re-publish
Source CRS allowlist violations 0 admitted any out-of-allowlist source registered Reproject upstream; deny at ingest gate
Delivery reprojection latency (p95) < 200 ms > 500 ms for 5 min Materialize view; add spatial index on delivery
Datum-shift declaration coverage 100% of shifted sources any implicit datum change Declare and pin datum_shift_grid

Governance & Compliance Notes

CRS is a compliance surface, not merely a technical one. Only projections on the source_crs_allowlist may enter the mesh, because an unapproved projection silently breaks every cross-domain join and undermines downstream SLAs, and the allowlist is the single enforcement point for that rule. Every reprojection at a boundary emits an audit event recording the source CRS, target CRS, the pinned transform_pipeline, and any datum_shift_grid applied — this trail is what lets an auditor reconstruct exactly how a coordinate reached its delivered position. Because a CRS change is never backward-compatible, it is always governed as a breaking change under Versioning Spatial Data Contracts with SemVer: the crs_epsg in the contract and the projection served at the port must agree, and any divergence forces a major version and a parallel migration rather than an in-place edit. Held to this standard, the mesh keeps one canonical truth, reprojects only where it is accountable to, and delivers each consumer the projection it needs without ever polluting the interior.