Ben,

the general plan if we wanted to introduce support for DerivedProjectedCRS in the database is sound, but I still don't think that using that concept for polyhedral projections with a face identifier is ISO-19111 compliant. AFAICS, there is no Coordinate System subclass that allows mixing linear axis (X,Y) and an ordinal one (face number). In particular a Cartesian CS is "a coordinate system in Euclidean space which gives the position of points relative to n mutually perpendicular straight axes all having the same unit of measure".

Even

Le 27/03/2026 à 12:13, Ben Griffin via PROJ a écrit :
Hi all,

Following the earlier thread on face/octant coordinates and the UTM zone 
analogy, I've been investigating whether DERIVEDPROJCRS could be used to 
formally express planar net projections as derived from  intermediate 
octahedral ProjectedCRS.

In doing so I found that the C++ side is already largely in place — the object 
model, WKT parser, and  operation factory all handle DerivedProjectedCRS 
correctly.
The operation factory catches  via the DerivedCRS* cast and routes through 
createOperationsDerivedTo, so WGS84 → ProjectedCRS → derivedProjectedCRS chains 
already work when the CRS is constructed programmatically or from inline WKT.

The gap, as I understand it, is purely in the database layer:
1. There is no derived_projected_crs table in proj.db / user.db
2. crs_view has no entry for this type, so authority-code lookup fails
3. createCoordinateReferenceSystem() has no dispatch for the type
4. createProjectedCRSEnd() throws a generic error if text_definition contains a 
DERIVEDPROJCRS WKT
I my thought is to offer a fix that is additive and non-breaking:
A new derived_projected_crs table (FK to projected_crs as base, consistent with 
ISO 19111's restriction that the base must be a ProjectedCRS);
A new type “derived projected” in crs_view;
A new createDerivedProjectedCRS() factory method;
And a clearer error message, with the existing text_definition path pointing 
users to the new derived_projected_crs table.

Use Cases (there may be others)
* Polyhedral projections, where a face index is a necessary part of the 
coordinate — analogous  to a UTM zone number.
The intermediate ProjectedCRS could carry the ellipsoid relationship and the 
face identifier; the DerivedProjectedCRS consumes both and produces a globally 
unambiguous planar coordinate. PROJ already includes several polyhedral 
projections (ISEA, HEALPix) where this two-layer architecture might be the 
correct formal expression. Any future polyhedral work (such as my own project!) 
would benefit from the same foundation.

* Datum-agnostic net/tile projections — a butterfly net derived from an 
octahedral CRS that is itself derived from ED50  rather than WGS84 is just a 
different base ProjectedCRS. The net definition doesn't change. Currently we 
are expected to register a separate CRS for each datum combination.

* Rotated or recentred projections — a Transverse Mercator variant recentred on 
a local origin, expressed as derived  from a standard TM ProjectedCRS, rather 
than as a fresh projection from the ellipsoid. The datum relationship is 
inherited, not repeated.

In brief, and as I understand it, the ISO 19111:2019 defines 
DerivedProjectedCRS as a first-class CRS type, and PROJ's C++ object model 
reflects this faithfully. However without database registration support, the 
type cannot be used in the authority-code workflows that most users depend on — 
making it effectively unavailable in practice.

I have started to compose a PR against master in order to close this gap, but I 
felt it wise to check in: is there anything architecturally that would make 
this unwelcome, or any prior discussion I should be aware of, or does the plan 
sound reasonable?

=== Affected files ===
** SQL (data/sql)
proj_db_table_defs.sql : derived_projected_crs table; extend crs_view.
consistency_checks_triggers.sql : Duplicate preventions (2) on crs_view, insert 
rejections (coordinate_system not found, base_crs not found)

** src/iso19111/factory.cpp
Add #define DERIVED_PROJECTED "derived projected”
Add functions to support DerivedProjectedCRS
Modify createCoordinateReferenceSystem, createObject, createProjectedCRSEnd to 
support DerivedProjectedCRS

** Public API
include/proj/io.hpp
public `createDerivedProjectedCRS(const std::string &code)` on 
`AuthorityFactory`

** C API
src/iso19111/c_api.cpp
Wire authority-code lookup in `proj_create_derived_projected_crs()` to use 
`createDerivedProjectedCRS()`

** Tests
test/unit/test_factory.cpp createDerivedProjectedCRS, 
createCoordinateReferenceSystem,
     `text_definition` :  `projected_crs` containing `DERIVEDPROJCRS` WKT gives 
directed error
     `text_definition` in `derived_projected_crs` round-trips correctly
     `cs2cs`-equivalent pipeline resolves end-to-end for a registered 
`DerivedProjectedCRS`
** No change
No need to modify the wkt2 grammar/parser, iso19111 io, operations, crs, or 
their test frameworks.

Best regards
-Ben


_______________________________________________
PROJ mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/proj

--
http://www.spatialys.com
My software is free, but my time generally not.

_______________________________________________
PROJ mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/proj

Reply via email to