ProjNET v3: modernized engine with expanded projection/transformation coverage and a built-in EPSG catalog#137
Open
mkaring wants to merge 1837 commits into
Open
ProjNET v3: modernized engine with expanded projection/transformation coverage and a built-in EPSG catalog#137mkaring wants to merge 1837 commits into
mkaring wants to merge 1837 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update CompatibilitySuppressions.xml to record the approved v3 API deltas that remain intentionally accepted while dotnet pack validates against the 2.1.0 baseline. Document the rule in engineering governance so future public API work keeps the package validation gate in sync. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Refresh the workflow action references to the latest available release tags across CI, benchmarks, CodeQL, and mutation testing. Keep the existing workflows unchanged functionally while moving off older action lines and newer artifact/cache backends. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Hello,
this is a massive pull request — it's a major overhaul of ProjNet4GeoAPI that brings the library
very close to feature parity with PROJ.
Most of this work was done earlier this year during the AI Exploration Camp we held at
TKI Chemnitz, where the whole point was to explore what we can actually build with the current
generation of AI tooling. This branch is the result of running that experiment on a real,
non-trivial codebase.
A note on the commit history up front: please don't read too much into it. The ~1,800 commits
were used to track the implementation process of the AI agents step by step — they are not meant to
be a curated, reviewable history. If the content is fine with you, I'm happy to rewrite/squash the
branch into whatever shape you'd like. For what it's worth, this was all done before the GitHub
Copilot pricing change, so an ungodly number of tokens went into it.
Below is a fuller description of what actually changed, and how it was validated.
What this changes (high level)
library targets
net8.0(AOT/trim-safe) alongsidenetstandard2.0/netstandard2.1, and theruntime no longer depends on
proj.db.(186 upstream
PROJ_HEADidentifiers were surveyed — parity matrix indocs/projection-coverage.md),plus term-by-term fidelity fixes for a long list of projections (
omerc,tpeqd,ocea,the stereographic variants, exact
tmerc/gauss_kruger/utm,krovak,nzmg,loxim,ortho,s2/healpix/rhealpix,isea,lagrng,vandg, …).Molodensky / Molodensky-Badekas, deformation models, TIN shift, Horner, horizontal/vertical/xyz
grid shifts (NTv2 / GTX / GeoTIFF), prime-meridian and topocentric transforms, 4D
+proj=axisswap, and full pipeline composition/concatenation. Operation selection prefersmetadata-backed EPSG operations over equal-parameter identity fallbacks.
and compound/derived CRS), on a new buffered span-based
WktTokenizer.with a public configuration API and
PROJNET_GRID_*environment variables — seedocs/grids.md.System.Text.Jsonin tests (dropped Newtonsoft), Nerdbank.GitVersioning, StyleCop/analyzersenforced in-build, and CI for build/parity, benchmarks, CodeQL, and Stryker mutation testing.
References and validation
For the references I mostly used two books:
Especially the Reference Manual contains a lot of specific implementation detail and
pre-calculated worked examples — those are now all part of the algorithms and the unit tests.
Snyder's Appendix A worked examples, for instance, are used directly as regression test vectors.
The formula citations (chapter/section/page) are embedded in the shipped XML documentation so the
provenance of each projection is explicit.
Secondly, the original PROJ library was used to validate the implementation: I ran specific
coordinates through
projand fed the results into the unit tests as the expected values (there isa direct
proj2projparity suite for exactly this). The projection code was also comparedterm-by-term against PROJ's C++ implementations, including the ellipsoidal-vs-spherical handling and
edge cases (poles, equator, antimeridian, domain boundaries).
Where it helped, the implementation and tests also cross-check against additional authoritative
sources whose citations you'll find in the code and fixtures:
used to independently verify ellipsoidal formulations (e.g. Hotine Oblique Mercator variants A/B,
Lambert Conformal Conic 1SP/2SP).
/ projected series.
The EPSG catalog
I also got the EPSG catalog in its entirety into the library — all known EPSG coordinate systems
are now contained within it (7,217 CRS definitions; common lookups such as
4326/3857work outof the box). The whole thing is implemented in C# directly, via a code generator that reads the
EPSG WKT export at build time, so there is no runtime
proj.dbdependency.I tried to keep the initial startup time, the lookup time, and the memory footprint as low as
reasonably possible: the generator emits on-demand, switch-based lookup paths split across focused
partial files instead of large eager arrays, so nothing pays for CRS definitions it never touches.
Scale of the change
Measured against the upstream
developmerge base (94079f12, "Increase version minor"):720 files changed, +302,944 / −14,886. The insertion count looks enormous, but it is dominated by
generated data and tests rather than hand-written code:
src/ProjNet/Data).g.cs/ switch lookupstest/ProjNet.Tests)src/ProjNet/CoordinateSystems)src/ProjNet/IO)Testing
reported 3,024 passing / 807 skipped, 0 failures, on a 0-warning build.
proj2proj parity (values produced by
proj), Snyder Appendix A numerical vectors, plusdeformation-model, TIN-shift, and grid (NTv2/GTX/GeoTIFF) fixtures.
PublicAPI.Shipped.txt) so API drift is caughtin CI, and there are BenchmarkDotNet suites for WKT parsing and projection/transform throughput.
Breaking changes
The one intentional, source-breaking change is that the public model is now immutable: mutating
setters were replaced by
With…(…)clone helpers, a few types were sealed, and[Serializable]wasremoved from the public surface (
VerticalDatumnow emitsVERT_DATUM[…]rather thanDATUM[…]).Full before/after migration recipes are in
MIGRATION-v3.md. The projection fidelity fixes canchange output coordinates for the affected projections — those are correctness fixes, not API breaks,
but downstream consumers may need to refresh stored numeric baselines.
Licensing / attribution
Still LGPL-2.1-or-later, with per-file SPDX headers and consolidated attribution in
NOTICE.mdand
LICENSES/. PROJ-derived portions are attributed under the PROJ-MIT text, and the vendoredNKG/Kartverket grid fixtures under CC-BY-4.0.
How to review
Diffing the tree against currentupstream
developis the meaningful view (the per-commithistory, as noted, is throwaway and can be reshaped on request).
Good entry points for reading:
README.md,CHANGELOG.md,MIGRATION-v3.md,docs/(concepts, cookbook, grids,projection-coverage), and
src/ProjNet/ENGINEERING_GOVERNANCE.md.Happy to split this up, squash the history, or adjust scope however makes it easiest to review.