BUG: Honour PROJ spherification parameters in Geod (issue #1157) - #1610
BUG: Honour PROJ spherification parameters in Geod (issue #1157)#1610HugoFara wants to merge 1 commit into
Conversation
Geod does not hand its init string to PROJ; it parses the ellipsoid out
in Python. That parser discarded every parameter without a value:
# We can ignore safely any parameter that doesn't have a value
if kvpair.find("=") == -1:
continue
which is where +R_A and the rest of the spherification family went. The
result was silently wrong rather than unsupported: Geod('+ellps=WGS84
+R_A') returned ellipsoidal answers to a question asked about a sphere,
with no error and no warning, while PROJ's own geod CLI honoured the
flag.
Collect the spherification parameters before valueless parameters are
discarded, and apply PROJ's formulas from src/ell_set.cpp, including the
mutual exclusion order and the collapse to a sphere afterwards. All eight
now agree with PROJ to the millimetre; the +R_A radius also matches the
published WGS84 authalic sphere radius of 6371007.1809 m.
Unlike PROJ, the latitude of +R_lat_a/+R_lat_g is accepted only as
decimal degrees, not DMS. CRS('+ellps=WGS84 +R_A').get_geod() is
unchanged: +R_A has no representation in a CRS, so PROJ drops it there
too.
|
Hi @HugoFara |
|
Hi @jjimenezshaw . I couldn't find a way to reach either function from pyproj, maybe you can help me here. Both are declared in Only
Have I missed a supported route? If pyproj is expected to build against I also notived there is a way to let PROJ do the work through the public API only.
That covers named ellipsoids, explicit The trade-off is that it's a much bigger change than #1157 warrants: it moves Would you prefer I take this PR that way, or keep it narrow and open a separate issue for the delegation? Happy either way. |
Geodparses the ellipsoid out of its init string in Python rather than handing the string to PROJ, and that parser dropped every parameter without a value:+R_Aand the rest of the spherification family went through there. The result was silently wrong rather than unsupported —Geod('+ellps=WGS84 +R_A')returned ellipsoidal answers with no error and no warning, while PROJ's owngeodCLI honoured the flag.This collects those parameters before valueless ones are discarded and applies the formulas from PROJ
src/ell_set.cpp(ellps_spherification), including its mutual-exclusion order and the collapse to a sphere afterwards.Semi-major axis for
+ellps=WGS84, againstPROJ_DEBUG=3 geod ...:+R_A+R_V+R_a+R_g+R_h+R_lat_a=45+R_lat_g=45+R_CGeod.fwdnow reproduces thegeodCLI to 7 decimal places on all of them. The+R_Aradius also matches the published WGS84 authalic sphere radius (6371007.1809 m) to 0.2 mm, so the expected values do not rest on PROJ alone.Two deliberate limits:
+R_lat_a/+R_lat_glatitude withproj_dmstorand so accepts DMS; this accepts decimal degrees only and raisesGeodErrorotherwise.CRS('+ellps=WGS84 +R_A').get_geod()is unchanged.+R_Ahas no representation in a CRS, and PROJ drops it there too, so honouring it would diverge from PROJ rather than match it.Verification: 14 new tests, all failing before the change and passing after. Full suite
1047 passed,mypyclean,pre-commitclean. Built against PROJ 9.8.1.history.rstfor all changes andapi/*.rstfor new API