Feature: Snyder Polyhedral Equal Area projections#4758
Conversation
|
@felixpalmer Lots of cool stuff here :) Thank you for this! As discussed in #4389 (comment) , I was also planning to propose a replacement for the current ISEA projection based on a generalized ISEA / RTEA / IVEA method, using a closed-form inverse solution, and address some issues with the current set of parameters. You've taken that a step further with support for different polyhedron nets (and multiple unfolding setups too!!) which is also very cool. Is this using Snyder's original equations, which did not have a closed-form inverse, or the Slice and Dice approach with closed form inverse? We should discuss :) I was also going to test some further improvements suggested by @brsr which could potentially fully remove the need for Slerp in the inverse.
That is quite impressive. Was that tested throughout the globe surface or only for some specific test points? |
|
@jerstlouis the equations are from A5, DGGAL and BRSR, as noted in the header. I didn't reference Slice & Dice for the code, but it is possible that the 3 sources did. I'm open to improvements to the code and equations (e.g. removing the The roundtrip error is just based on a static set of points, you're right that perhaps it is worse if this is expanded across the globe |
|
@felixpalmer In particular, to replace the current
EDIT: It seems that you already support this with Would specifying the rhombic triacontahedron solid naturally yield the RTEA projection (as in DGGAL, https://www.mdpi.com/2220-9964/9/5/315, and https://www.tandfonline.com/doi/full/10.1080/17538947.2022.2130459?utm_source=researchgate.net&utm_medium=article ? I see the special names of Hexakis icosahedron and Decakis dodecahedron that you give to the disdyakis triacontahedron, but based on Snyder's paper specifically, the center of the faces is what is used for tracing the great circles, so the names of the solids would be the Dodecahedron and the Icosahedron (as per the DSEA and ISEA acronyms), right? And for Rhombic Triacontahedron that also naturally yields RT(S)EA. It's a very nice feature to be able to unfold them onto the different nets. Would this unfolding also work on polyhedrons without icosahedral symmetry? The unfolding net needs to have same symmetry as the projection solid? |
|
@jerstlouis could we continue the ISEA discussion here? I've given you access, feel free to update the constants - you understand them better than me. As you say it is already supported by the code.
I believe so, the code is designed to be a generic spherical-planar triangle mapper so you would just need to generate the relevant config files. The ISEA PR is a good example of what is required to add a new projection & polyhedron
Yes I thought a lot about the naming. I settled on this approach as the name tells us which vertex to use as the apex and how many triangles to cut the face into. See the docs for details For brevity (and following the example set by
Yes, this PR literally implements |
Yes, but technically these all refer to the same polyhedron, and I wonder if there couldn't be a more explicitly way to describe it, especially if we consider the possibility to specify the polyhedron and the choice of radiating vertex as projection parameters. For the RTEA configuration, would the name specifying that great circle setup mapping for the d120 be kisrhombic triacontahedron ? Also of course I'm very curious whether this modularity would help test the Archmidean solids configuration like the Truncated Icosahedron (TISEA / TIVEA), and still map that to the icosahedral net and the 5x6 space :) |
I think it should be tetrakis (rhombic) triacontahedron - so a triacontahedron with each face cut into 4 It is true that these all have the same vertices, but by naming them this way you can avoid the whole "radiating vertex" concept as the apex is always in the center of the base polyhedron face (the tip of the kis pyramid) |
|
@felixpalmer Thanks, I am starting to understand how these *kis prefixes work :) tetrakis rhombic triacontahedron makes sense, kis pyramids with 4 faces on each of the 30 faces of the rhombic triacontahedron. kisrhombic triacontahedron is one of the name of the d120 mentioned on https://en.wikipedia.org/wiki/Disdyakis_triacontahedron and likely just a shorthand for that longer name. And apparently "disdya" means twice two-fold (also 4), so disdyakis triacontahedron, tetrakis rhombic triacontahedron, kisrhombic triacontahedron would all naturally mean the RT(S)EA setup. |
|
Converted to draft PR to safe-guard against a premature merge. There's a lot going on in this PR request. This looks impressive but from my very superficial first glance it seems as if there's reimplementations of already existing functionality. In particular, my spidey sense is triggered by |
|
@kbevers The authalic conversion stuff is something that I pointed out before in the codebase was already duplicated in multiple places, and which would be nice to re-use throughout (in multiple other projections). Also the version in this PR in the current stage I think is not taking into consideration the selected ellipsoid's flattening which it ideally should... trying to work with @felixpalmer on improving a few things. |
|
As noted in the changelist, the render scripts are purely to help reviewers recreate the images. The authalic conversion @jerstlouis already pointed out is likely implemented in a number of places in the codebase and I agree we should be leveraging the existing code. I would love to reduce the amount of code added, I'm aware that it is a lot, @jerstlouis is interested in collaborating on this |
|
@jerstlouis @kbevers I've removed the |
Sure. @felixpalmer Can we please do that?
This PR should first be considered as fixes and improvements (performance and precision, likely fixing #4389) to the existing ISEA projection, and also introducing the underlying capability to support the vertex-oriented equal-area icosahedral projection (IVEA) which avoids the cusps of ISEA and is generally superior to ISEA for all practical purposes (@felixpalmer did you remove the There are many reasons for supporting these projections in PROJ:
Could you please approve the workflows so that any remaining issue can be addressed? (maybe after @felixpalmer amends to remove |
|
@rouault I've removed the legacy ISEA code, just for comparison the new implementation is actually slightly less LoC that the previous one (934 rather than 954). As @jerstlouis says it can thus be viewed as a better refactor of the existing implementation.
To add to what @jerstlouis wrote, I believe such a family of projections would be useful in PROJ to provide a robust, canonical reference for others to build upon. ISEA is historically the most popular of the bunch, but other variants actually provide superior performance (e.g. DSEA / IVEA) but are not adopted due to lack of good implementations. I certainly would have been very grateful for such a reference when building the A5 DGGS! I note that there is also good precedent (other than PS @jerstlouis yes |
|
This is a massive PR and I am in no way confident in reviewing the projection implementation. The general state of the code looks better than when I last looked at it, but before I sink too much time into this I'd like a have the following clarified or reworked. At this stage I am mostly focused on documentation and overall structure of the code, as well as long-term maintainability. Documentation and usage
Code
|
|
@rouault I would like to stress the merit of a reference implementation for this family of map projections. Beyond DGGS, they also provide a natural mechanism to minimise distortion in equal-area projections. This implementation is too an homage to the work of John Snyder. @mpadillaruiz @brsr @joaocsmanuel @sunayana All of you have proper insight into this projection family. Would be great if some of you could provide an extra review to this PR. |
Read https://github.com/OSGeo/PROJ/tree/master/docs/docbuild to see how to automatically generate documentation and that file in particular. |
Co-authored-by: Even Rouault <even.rouault@spatialys.com>
Co-authored-by: Even Rouault <even.rouault@spatialys.com>
Co-authored-by: Even Rouault <even.rouault@spatialys.com>
|
@felixpalmer could you tell what was done with AI (Claude)? |
No, that doc page is there to give a high level explanation of the general Snyder polyhedral approach, while
Thanks for the pointer, figures added and regenerated using
The split wasn't purely stylistic — the headers also delineate where existing open-source code came from (gl-matrix, A5, Snyder's construction). That said, I'm happy to inline them into a single
Agreed, I was surprised there was no such common code myself. I would propose moving just the
Removed. It was there to help generate net layout diagrams like this: |
|
@jjimenezshaw there isn't a clean split, I use it as a tool. So for refactors, design discussions etc. The docs are all handwritten, anything that has a header indicating inclusion from another project was translated using AI but is not worth reviewing (this is well-tested deployed code). The rest I wrote myself, AI was used to assist, not to blindly generate. |
|
I wonder if we can split this pull up into more easily digestible pieces. I think of this pull as having two conceptual parts:
The projection in 1 can be used on its own, independent from any global partitioning scheme. It would have mandatory parameters Regarding part 2, I notice that This probably needs discussion. |
Perhaps as a first step we could go back to splitting that more general code for a specific triangle into the common shared (actually I think it is still split in the last version, but inside |
|
Would it be possible to update the PROJ scripts to be able to optionally show that red dot where the default projected 0,0 happens to be? The previous images with the red dot were a very significant improvement showing where that happens to be compared to the previous version (and the images currently in this PR after the recent change). Not having this clearly illustrated is a major pain point in trying to use these projections. |
I don't think the meta operation necessarily results in right triangles? (though for the trigonometric formulation, the math is different as it cannot assume one angle is 90 degrees). Wondering if you made the optimization yet where actually for the typical unfolding the full meta operation is not necessary (you only need it if the net explicitly unfolds the two different parts of the fanned triangles from face center to face vertices into a specially cut-out net -- just the kis operation is otherwise enough). The future custom nets would allow that, but none of the the current hardcoded configurations need that I think (only 12 projection triangles rather than 24 are necessary for the tetrahedron, and only 60 rather than 120 are needed for the dodecahedron and icosahedron) |
|
@brsr thanks for the input and your great work this PR has built on. Long-term agree the partitioning code should be sharable with @jerstlouis red-dot: agree it's useful UX, but it's a
If the face is a regular polygon it does. You're right that this won't work for RTEA but let's deal with that in the future if we add that projection |

docs/source/*.rstfor new APIBackground
Please read the updated documentation in
docs/source/operations/projections/polyhedral.rstfirst as well as Snyder's original paper: AN EQUAL-AREA MAP PROJECTION FOR POLYHEDRAL GLOBES (CARTOGRAPHICA Vol 29 No 1 SPRING 1992 pp 10–21)Back-compatibility with existing
iseaGives same results, with comparisons in
test/gie/builtins.gie. I would propose we remove the oldiseacode, replacing with this implementation.Architecture
To define a projection a polyhedron and net must be defined. The simplest example is that of the 4-sided tetrahedron along with the net definitions:
0as the rootThese details are not exposed to the user via the PROJ API, instead they reference them by name, e.g.
+proj=tsea +net=starWhen building the projection, the following process followed:
pj_polyhedral_datastructpj_polyhedral_dataThe design is generic and adding polyhedra/nets is straightforward and doesn't require large code updates
Change list
Example renders
ISEAExample renders
TSEAExample renders
DSEA