[PROJ] Geodetic to Authalic latitude conversions
Jérôme St-Louis
jerome at ecere.com
Tue Sep 10 18:36:24 PDT 2024
Sorry I should correct a few confusing mistakes in my previous e-mail:
- I was talking mainly about authalic latitude ==> geodetic
latitude conversion, not the other way around.
/pj_authlat()/ returns the geodetic latitude for a given authalic
latitude (the name of the function is quite confusing -- I would propose
to rename to something less ambiguous if it is only used internally)
- The function currently uses 3 /sin()/ calls for order 3 (not 2,
made a typo)
- The ISEA projection does not currently make use of /pj_authlat()/
or /pj_qsfn() /for automatically converting authalic / geodetic
latitudes, but I am proposing to introduce this when using non-spherical
ellipsoid (just like LAEA of which it is a modified form).
Best,
-Jerome
On 9/10/24 9:19 PM, Jérôme St-Louis via PROJ wrote:
>
> Hi Even, all,
>
> As suggested in https://github.com/OSGeo/PROJ/pull/4211 , I've just
> written an implementation of the authalic / geodetic latitude
> conversion with the goal to automatically perform this conversion when
> using ISEA with an non-spherical ellipsoid, and was wondering whether
> we would want to improve the PROJ version (/pj_authlat()/ for the
> geodetic ==> authalic), which is used for ISEA, but also by:
>
> - Equal Area Cylindrical (cea.cpp)
> - EqualEarth (eqearth.cpp)
> - HEALPix (healpix.cpp) -- which might also imply rHEALPix
> - Lambert Azimuthal Equal Area (laea.cpp)
>
> The current version of /pj_authlat()/ uses a series expansion based on
> the eccentricity squared (I believe this is based on a Lagrange
> reversion <https://en.wikipedia.org/wiki/Lagrange_inversion_theorem>
> as mentioned here
> <https://en.wikipedia.org/wiki/Latitude#Inverse_formulae_and_series>),
> and Charles Karney in this paper <https://arxiv.org/pdf/2212.05818>
> establishes that:
>
>> /series expansions using the third flattening as the small parameter
>> uniformly result in smaller truncation errors compared to using the
>> eccentricity./
> The current version also only uses order 3, whereas GeographicLib
> would normally use order 6 for double precision, with order 4 being
> the minimum configuration.
> The current order 3, which requires 2 /sin()/ calls, gives precision
> up to roughly 8 decimals.
> Order 6 would mean twice the number of /sin()/ calls, and the 8
> decimals should be enough to point to Waldo on a page
> <https://xkcd.com/2170/>, however C.K. argues that:
>
>> /Modern geodetic libraries should strive to achieve full
>> double-precision accuracy /(page 4)/
>> /
>
> and I would much agree with that.
>
> Based on the direction we want to go, I would submit a PR including
> adjustments to avoid the separate heap allocation for the doubles (as
> discussed here
> <https://github.com/OSGeo/PROJ/pull/4211#pullrequestreview-2233903246>),
> and adjustments for tests etc.
>
> PROJ currently does not use the full GeographicLib which already
> includes code for conversion between different auxiliary latitudes,
> does it?
>
> (
> https://github.com/geographiclib/geographiclib/blob/main/src/AuxLatitude.cpp
> )
>
> See my proposed new version below, which I wrote based on equation 20
> on page 3, and matrix A20 on page 13 from the paper, applying
> optimizations similar to the current /pj_authlat()/.
>
> Kind regards,
>
> -Jerome
>
>> void pj_authset(double a, double b, double cp[6])
>> {
>> // https://arxiv.org/pdf/2212.05818
>> // ∆η(ζ) = S^(L)(ζ) · Cηζ · P^(M) (n) + O(n^L+1) -- (20)
>> double n = (a - b) / (a + b); // Third flattening
>> static const double C[21] = // (A20)
>> {
>> 4 / 3.0, 4 / 45.0, -16/35.0, -2582 /14175.0, 60136
>> /467775.0, 28112932/ 212837625.0,
>> 46 / 45.0, 152/945.0, -11966 /14175.0, -21016 /
>> 51975.0, 251310128/ 638512875.0,
>> 3044/2835.0, 3802 /14175.0, -94388 /
>> 66825.0, -8797648/ 10945935.0,
>> 6059 / 4725.0, 41072 /
>> 93555.0, -1472637812/ 638512875.0,
>> 768272
>> /467775.0, -455935736/ 638512875.0,
>> 4210684958/1915538625.0
>> };
>> double p;
>>
>> cp[0] = C[ 0] * n;
>>
>> p = n * n;
>> cp[0] += C[ 1] * p;
>> cp[1] = C[ 6] * p;
>>
>> p *= n;
>> cp[0] += C[ 2] * p;
>> cp[1] += C[ 7] * p;
>> cp[2] = C[11] * p;
>>
>> p *= n;
>> cp[0] += C[ 3] * p;
>> cp[1] += C[ 8] * p;
>> cp[2] += C[12] * p;
>> cp[3] = C[15] * p;
>>
>> p *= n;
>> cp[0] += C[ 4] * p;
>> cp[1] += C[ 9] * p;
>> cp[2] += C[13] * p;
>> cp[3] += C[16] * p;
>> cp[4] = C[18] * p;
>>
>> p *= n;
>> cp[0] += C[ 5] * p;
>> cp[1] += C[10] * p;
>> cp[2] += C[14] * p;
>> cp[3] += C[17] * p;
>> cp[4] += C[19] * p;
>> cp[5] = C[20] * p;
>> }
>>
>> double pj_authlat(double auth, const double * cp)
>> {
>> // https://arxiv.org/pdf/2212.05818
>> // ∆η(ζ) = S^(L)(ζ) · Cηζ · P^(M) (n) + O(n^L+1) -- (20)
>> double a2x = auth + auth, a4x = a2x + a2x, a8x = a4x + a4x;
>> return auth +
>> cp[0] * sin(a2x) +
>> cp[1] * sin(a4x) +
>> cp[2] * sin(a4x + a2x) +
>> cp[3] * sin(a8x) +
>> cp[4] * sin(a8x + a2x) +
>> cp[5] * sin(a8x + a4x);
>> }
>
> _______________________________________________
> PROJ mailing list
> PROJ at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/proj
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20240910/f5effbd3/attachment-0001.htm>
More information about the PROJ
mailing list