<div dir="ltr"><div>Sorry, I should me more explicit</div><div>What I mean is:</div><div></div><div> - take 9.6.0</div><div> - replace the function pj_conformal_lat_inverse in latitudes.cpp with the new implementation</div><div> - replace its declaration in proj_internal.h <br></div><div> - replace its usage in spilhaus.cpp</div><div><br></div><div>... that is this patch</div><div><br></div><div>------- begin patch --------------</div><div><span style="font-family:monospace">diff --git a/src/latitudes.cpp b/src/latitudes.cpp<br>index 7d49f667..c5e277f8 100644<br>--- a/src/latitudes.cpp<br>+++ b/src/latitudes.cpp<br>@@ -36,33 +36,17 @@ double pj_conformal_lat(double phi, double e) {<br> }<br> <br> /*****************************************************************************/<br>-double pj_conformal_lat_inverse(double chi, double e, double threshold) {<br>+<br>+double pj_conformal_lat_inverse(double chi, const PJ *P) {<br> /***********************************<br>- * The inverse formula of the conformal latitude<br>- * for phi (geodetic latitude) in terms of chi (conformal latitude),<br>- * Snyder, A working manual, formula 3-4<br>+ * The geodetic latitude, phi, in terms of the conformal latitude, chi.<br> *<br> * chi: conformal latitude, in radians<br>- * e: ellipsoid eccentricity<br>- * threshold: between two consecutive iteratinons to break the loop, radians<br>- * returns: geodetic latitude, in radians<br>+ * returns: geodetic latitude, phi, in radians<br>+ * Copied from merc.cpp<br> ***********************************/<br>- if (e == 0.0)<br>+ if (P->e == 0.0)<br> return chi;<br> <br>- const double taninit = tan(M_PI / 4 + chi / 2);<br>- double phi = chi;<br>- for (int i = 0; i < 10; i++) {<br>- const double esinphi = e * sin(phi);<br>- const double new_phi =<br>- 2 * atan(taninit *<br>- std::pow(((1 + esinphi) / (1 - esinphi)), (e / 2))) -<br>- 0.5 * M_PI;<br>- if (abs(new_phi - phi) < threshold) {<br>- phi = new_phi;<br>- break;<br>- }<br>- phi = new_phi;<br>- }<br>- return phi;<br>+ return atan(pj_sinhpsi2tanphi(P->ctx, tan(chi), P->e));<br> }<br>diff --git a/src/proj_internal.h b/src/proj_internal.h<br>index 922c7074..54b64341 100644<br>--- a/src/proj_internal.h<br>+++ b/src/proj_internal.h<br>@@ -923,7 +923,7 @@ double *pj_authset(double);<br> double pj_authlat(double, double *);<br> <br> double pj_conformal_lat(double phi, double e);<br>-double pj_conformal_lat_inverse(double chi, double e, double threshold);<br>+double pj_conformal_lat_inverse(double chi, const PJ *P);<br> <br> COMPLEX pj_zpoly1(COMPLEX, const COMPLEX *, int);<br> COMPLEX pj_zpolyd1(COMPLEX, const COMPLEX *, int, COMPLEX *);<br>diff --git a/src/projections/spilhaus.cpp b/src/projections/spilhaus.cpp<br>index 01b86800..ba9a6c57 100644<br>--- a/src/projections/spilhaus.cpp<br>+++ b/src/projections/spilhaus.cpp<br>@@ -98,8 +98,7 @@ static PJ_LP spilhaus_inverse(PJ_XY xy, PJ *P) {<br> aatan2(cosphi_s * sinlam_s,<br> Q->sinalpha * cosphi_s * coslam_s - Q->cosalpha * sinphi_s);<br> <br>- const double THRESHOLD = 1e-10;<br>- lp.phi = pj_conformal_lat_inverse(lp.phi, P->e, THRESHOLD);<br>+ lp.phi = pj_conformal_lat_inverse(lp.phi, P);<br> <br> return lp;<br> }<br></span></div><div>------- end patch --------------</div><div><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sun, 4 May 2025 at 20:27, Greg Troxel <<a href="mailto:gdt@lexort.com">gdt@lexort.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Javier Jimenez Shaw <<a href="mailto:j1@jimenezshaw.com" target="_blank">j1@jimenezshaw.com</a>> writes:<br>
<br>
> The PR was <a href="https://github.com/OSGeo/PROJ/pull/4446" rel="noreferrer" target="_blank">https://github.com/OSGeo/PROJ/pull/4446</a><br>
><br>
> Maybe the function that impacts the tests is "pj_conformal_lat_inverse".<br>
> You can try with the new implementation.<br>
> The changes should be small. (See that the signature of the function is a<br>
> bit different). It is used only in one place.<br>
<br>
<br>
Do you mean:<br>
<br>
take proj 9.6.0<br>
<br>
read the diff to pj_conformal_lat_inverse from the PR, and hand patch<br>
it in, except not changing the signature<br>
<br>
build and rerun tests<br>
<br>
I guess I could further keep the code and compare the two results.<br>
<br>
<br>
I looked at that code, and it jumped out at me that are abs() was used,<br>
which is a C function, not C++, and is integer only.<br>
<br>
With this patch (to 9.6.0), I get a pass:<br>
<br>
--- src/latitudes.cpp.~1~ 2025-03-13 10:31:27.000000000 -0400<br>
+++ src/latitudes.cpp 2025-05-04 14:23:04.656697860 -0400<br>
@@ -58,7 +58,7 @@<br>
2 * atan(taninit *<br>
std::pow(((1 + esinphi) / (1 - esinphi)), (e / 2))) -<br>
0.5 * M_PI;<br>
- if (abs(new_phi - phi) < threshold) {<br>
+ if (std::abs(new_phi - phi) < threshold) {<br>
phi = new_phi;<br>
break;<br>
}<br>
<br>
Interesting that this only causes trouble with spilhaus, at least as far<br>
as tests catch it.<br>
</blockquote></div>