Repository navigation
Conversation
Phase 5 of making the projection system generic. Math: standard Snyder transverse Mercator formulas on the WGS84 ellipsoid, verified independently in Python before porting - the meridian arc against Simpson integration of the meridian radius (<0.5mm divergence) and round trips over 252 points covering all zones and latitudes to 89 degrees (max error 1.06e-08 degrees). - UtmDefinition.swift: UtmHemisphere and UtmDefinition implementing both directions of the projection with a per-zone central meridian, the 0.9996 scale factor, the 500_000 false easting and per-hemisphere false northing. Sector extents follow the EPSG convention (easting 100_000-900_000, northing 0-10_000_000); the world bounding box is the zone sector and no WKT pattern is registered (UTM .prj files would need per-zone parsing). - Projection gains all 120 zone cases (northern 32601-32660, southern 32701-32760) and init?(srid:) accepts the contiguous SRID ranges. wraparoundExtent is nil (zone coordinates never wrap), kind is planar; description now defaults to the EPSG label so it scales with the SRID count. - ProjectionRegistry resolves definitions via an eagerly built dictionary; registration coverage is asserted at runtime by the new UtmDefinitionTests sweep over all UTM SRIDs. Tests: SRID-to-zone/hemisphere mapping for all 120 SRIDs, registry coverage sweep, central meridian math per zone, known forward values (zone-edge equator eastings, scaled meridian arcs, both hemispheres), hemisphere symmetry (equal eastings, exact 10_000_000 northing offset), round trips, boundingBox/contains/distance, antimeridian no-ops in date-line zones, normalize/clamp, WKB round trips and random generation within the zone sector.
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
Phase 5 of making the projection system generic — the UTM family. Stacks on #240 (phase 4: registry-driven WKT matching); merge the chain in order. The API decision from the plan discussion was option 1: 120 dedicated enum cases.
Math
Standard Snyder transverse Mercator on the WGS84 ellipsoid (k₀ = 0.9996, 500_000 m false easting, per-hemisphere false northing). Verified independently before porting:
Coordinate3D.init?(easting:northing:zone:hemisphere:)) already matched the verified math; the new definition adds the long-missing 4326→UTM directionChanges
UtmDefinition.swift:UtmHemisphere+UtmDefinition— both directions of the projection, per-zone central meridian, EPSG sector extents ([100_000–900_000, 0–10_000_000]), world box = zone sector, no WKT patterns (per-zone.prjmatching would need zone-number parsing — left out of scope)Projection: 120 new cases;init?(srid:)accepts the contiguous SRID ranges without enumerating cases;wraparoundExtentisnil(zone coordinates never wrap);descriptiondefaults to theEPSG:label so it scales with SRID countProjectionRegistry: definitions resolve through an eagerly built dictionary (SRID ranges can't drive exhaustive switches); registration coverage is asserted by tests at runtime and viaassertionFailurein debugTesting (+13)
Full suite: 2463 tests in 177 suites, zero warnings.