Repository navigation
Conversation
Implements #243 for the WGS84-pivot architecture established in #247, shipping datum-capable built-in projections and the public transformation helper for user-defined datum CRSs. Phase 1 - Datum metadata model: - public Ellipsoid (wgs84/grs80/clarke1866/airy1830 with derived eccentricities and axes) and public Datum (wgs84/etrs89/nad27/ osgb1936) - Projection.datum accessor resolved from the definition; ProjectionDefinition gains a datum requirement (default WGS84); CustomProjection gains a datum field. Phase 2 - verified math infrastructure: - public HelmertTransformation: 7-parameter Helmert with position vector convention, exact rotation matrices, geocentric legs on arbitrary source ellipsoids, both directions with explicit result projection labeling. Well-known sets for NAD27 ("NAD27 to WGS 84 (4)", ~10 m) and OSGB36 ("OSGB 1936 to WGS 84 (6)", EPSG:1314, ~2 m) sourced from the EPSG registry and verified against pyproj/PROJ reference values. - internal TransverseMercatorMath(ellipsoid:) generalizing the Snyder TM formulas with a latitude-of-origin; UtmDefinition delegates to it (guarded by the existing UTM known-value tests, behavior provably unchanged). Phase 3 - built-in datum CRSs: - EPSG:4267 NAD27 geodetic, EPSG:4277 OSGB36 geodetic, EPSG:4258 ETRS89 geodetic (identity shift; OS labels ETRS89 data as WGS84 at meter accuracy) and EPSG:27700 British National Grid (helmert + TM on Airy 1830: lat0 49, lon0 -2, k 0.9996012717, FE 400000, FN -100000) - all registered in the registry seed with WKT matcher fragments (BNG probes before the generic Mercator fragments), datum metadata, test-appropriate unbounded extents (BNG keeps its southwest negative-northing region valid). Fixtures: The reference values were computed independently with pyproj/PROJ before porting, at 9-decimal precision; round-trip errors measured at ~3.3e-9 deg (NAD27) and ~1.4e-8 deg (OSGB36). Tests (+12): datum metadata, Helmert both directions + round trips, per-CRS reference fixtures, route-pivot round trips, British National Grid values with the southwest sector, algorithm smoke tests, WKB round trips and WKT matching for the new SRIDs. ETRS89-bearing WKT strings now match EPSG:4258 instead of returning nil. Also extends the README Projections section with the datum CRSs, the accuracy tier note and attribution, and links the grid shift support issue (#248).
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #243 for the WGS84-pivot architecture from #247. Ships datum-capable built-in CRSs and the public transformation helper for user-defined datum CRSs. Grid shift support (NADCON/OSTN15/NTv2, sub-meter accuracy) is deliberately filed as a separate issue (#248) per the review decision — load-don't-bundle, per-file license review.
Phase 1 — Datum metadata (additive)
public struct Ellipsoid(wgs84,grs80,clarke1866,airy1830, EPSG-registr υalues + derived axes/eccentricities)public struct Datum(wgs84,etrs89,nad27,osgb1936)Projection.datum,ProjectionDefinition.datum(default WGS84),CustomProjection.datumfieldPhase 2 — Verified math infrastructure
public struct HelmertTransformation— 7-parameter helmert (position vector convention, exact rotation matrices, geocentric legs on arbitrary source ellipsoids) with both directions and explicit result labeling: well-known sets for NAD27 ("NAD27 to WGS 84 (4)", ~10 m) and OSGB36 ("OSGB 1936 to WGS 84 (6)", EPSG:1314, ~2 m) pulled from the EPSG registryTransverseMercatorMath(ellipsoid:)— internal generalization of the Snyder TM formulas with a latitude-of-origin;UtmDefinitionnow delegates to it (day-1 UTM suite proves the WGS84 math byte-equivalent)Phase 3 — Built-in datum CRSs
.prjmentionsTransverse_Mercator, which would otherwise match 3395 — same ordering rule as Identify UTM zones in WKT strings via regex #244's Pseudo-Mercator)validExtent: nil) — the SW sector carries negative northings (FN = −100 km), which a nominal sector box would reject/clamp away; pinned by testsVerification discipline (pyproj ground truth first)
Reference values were computed independently with pyproj/PROJ before porting, at 9-decimal precision (kept
2>/dev/null-suppressed warnings of the used epsg codes are documented in the test doc comments):Fixture points include in-domain N. America and UK points, a south-west BNG case (northing 14_401.7), and the geographic/+height round trips.
Changes
New files:
Datum.swift,HelmertTransformation.swift,TransverseMercatorMath.swift, the four CRS definitions;datumdrinks threaded throughProjection/definitions/CustomProjection; UTM delegates to the TM math.Projectionexposes the new static constants.Testing (+12)
DatumTests,HelmertTransformationTests,DatumCrsTests(reference fixtures, round trips via the WGS84 pivot incl. 4267→27700, algorithm smoke tests, WKB round trips with embedded SRIDs, WKT matching).GEOGCS["ETRS89"]now matches EPSG:4258 (previously nil).Full suite: 2500 tests in 183 suites, zero warnings.