Repository navigation
Conversation
Phase 2 of making the projection system generic: extract the inline transform math into a ProjectionDefinition strategy protocol and route all conversions through a registry, keeping EPSG:4326 as the pivot. - ProjectionDefinition protocol: forward/inverse relative to the EPSG:4326 pivot, plus validExtent and worldBoundingBox metadata - Definitions for EPSG:4326 (identity), EPSG:3857 (Web Mercator), EPSG:4978 (ECEF, with the geodetic/ECEF helpers moved here) and noSRID (null math) - ProjectionRegistry maps a Projection to its definition - Coordinate3D.projected(to:) now dispatches through the registry; clamped() uses the definition's validExtent; latitudeProjected/ longitudeProjected derive from the full projection - BoundingBox.expanded(byDistance:) and Random's world box use the registry metadata instead of per-CRS switches noSRID keeps its historical semantics, now documented and pinned by tests: verbatim copy to .noSRID, verbatim relabel to EPSG:4326 and EPSG:3857 (planar-meter convention), interpreted as EPSG:4326 into EPSG:4978. New tests: round trips across all projection pairs, pivot routing, noSRID semantics, per-axis helper consistency, altitude/m preservation and clamped() extents.
This was referenced Sep 14, 2026
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 2 of making the projection system generic. Stacks on #237 (phase 1:
ProjectionKind+ capability flags) — review/merge that one first.Extracts the inline transform math into a
ProjectionDefinitionstrategy protocol and routes all conversions through a registry, keeping EPSG:4326 as the pivot.Changes
ProjectionDefinitionprotocol (new file):forward/inverseconversions relative to the EPSG:4326 pivot, plusvalidExtentandworldBoundingBoxmetadataProjectionRegistry: maps eachProjectionto its definitionEpsg4326Definition(identity),Epsg3857Definition(Web Mercator),Epsg4978Definition(ECEF — geodetic/ECEF helpers moved here fromCoordinate3D),NoSridDefinition(null math)Coordinate3D.projected(to:): the 4×4 nested switch matrix replaced byinverse → 4326 pivot → forwardthrough the registryCoordinate3D.clamped(): uses the definition'svalidExtentlatitudeProjected/longitudeProjected: derive from the full projection (noSRID special case preserved)BoundingBox.expanded(byDistance:)andRandom's world box: use registry metadata instead of per-CRS switchesnoSRID semantics (pinned by tests)
The historical convention is preserved and now documented:
.noSRIDcopies values verbatim.noSRIDinto EPSG:4326 or EPSG:3857 copies values verbatim (the library treats noSRID values as planar meters —intersection/unaryUnionrely on this).noSRIDinto EPSG:4978 interprets the values as EPSG:4326Testing
clamped()extents