Skip to content

Chain vertical CRS transformations through intermediate same-datum vertical CRS#4708

Open
phaarnes wants to merge 4 commits intoOSGeo:masterfrom
phaarnes:fix/vert-to-vert-operations-chaining
Open

Chain vertical CRS transformations through intermediate same-datum vertical CRS#4708
phaarnes wants to merge 4 commits intoOSGeo:masterfrom
phaarnes:fix/vert-to-vert-operations-chaining

Conversation

@phaarnes
Copy link
Contributor

Summary

When transforming between two vertical CRSs and no direct registered operation exists for the exact pair, PROJ now searches for registered operations involving an intermediate vertical CRS that shares the same datum as the source or target. The intermediate CRS may differ in axis direction (height vs depth), units (metres vs feet), or both. Previously PROJ fell back to a ballpark transformation, discarding available registered operations.

Example

EPSG:5705 (Baltic 1977 height) → EPSG:5706 (Caspian depth)

EPSG:5438 transforms 5705 → 5611 (Caspian height). CRS 5611 and 5706 share the Caspian datum but differ in axis direction. PROJ now composes:

5705 →(EPSG:5438)→ 5611 →(height-to-depth axisswap)→ 5706

Before (ballpark fallback)

+proj=affine +s33=-1
(50.0, 40.0, 100) → (50.0, 40.0, -100.0)  ← wrong

After (registered operation + axis conversion)

+proj=pipeline +step +proj=geogoffset +dh=28 +step +proj=axisswap +order=1,2,-3
(50.0, 40.0, 100) → (50.0, 40.0, -128.0)  ← correct

Implementation

New method createOperationsVertToVertWithIntermediateVert in coordinateoperationfactory.cpp, using two strategies:

  1. Pivot on target datum: Find candidate vertical CRSs sharing the target's datum. If a registered operation exists from the source to any candidate, compose it with the candidate→target axis/unit conversion.
  2. Pivot on source datum: Find candidate vertical CRSs sharing the source's datum. If a registered operation exists from any candidate to the target, compose the source→candidate conversion with that operation.

This mirrors the existing createOperationsGeogToVertWithIntermediateVert (geographic→vertical paths) but extends it to vertical→vertical paths. Uses the existing findCandidateVertCRSForDatum infrastructure.

Changes

  • src/iso19111/operation/coordinateoperationfactory.cpp: Added createOperationsVertToVertWithIntermediateVert method with anti-recursion guard; invoked from createOperationsFromDatabaseWithVertCRS when no direct result is found.
  • test/unit/test_operationfactory.cpp: Two new tests — Strategy 1 (5705→5706, height→depth) and Strategy 2 (5706→5705, depth→height).
  • NEWS.md: Added entry under 9.8.0 Updates.
  • docs/source/operations/operations_computation.rst: Updated "Vertical CRS to a Vertical CRS" section documenting the new intermediate CRS pivot logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chain vertical CRS transformations through intermediate vertical CRS sharing the same datum

1 participant