diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-11-29 20:53:21 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-11-29 20:57:40 +0100 |
| commit | 284feecd27f3fd43569d3d37d62ae7b0153c20ce (patch) | |
| tree | 148cbc42826a93e758911be21a4dabc573c0eb10 | |
| parent | edd7f165f88958c1d3147150639b67b8dd60db09 (diff) | |
| download | PROJ-284feecd27f3fd43569d3d37d62ae7b0153c20ce.tar.gz PROJ-284feecd27f3fd43569d3d37d62ae7b0153c20ce.zip | |
Spherical tmerc forward: do not restrict to [-90,90] longitude range
The restriction was a copy&paste from the Evenden/Snyder approximate
ellipsoidal implementation, but the spherical one is exact, so this
restriction isn't needed.
Also tune a bit the handling of lat=0, |lon| > 90
| -rw-r--r-- | src/projections/tmerc.cpp | 29 | ||||
| -rw-r--r-- | test/gie/builtins.gie | 68 |
2 files changed, 78 insertions, 19 deletions
diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index 2d13b064..8f897061 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -115,25 +115,11 @@ static PJ_XY approx_e_fwd (PJ_LP lp, PJ *P) return (xy); } -static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) { +static PJ_XY tmerc_spherical_fwd (PJ_LP lp, PJ *P) { PJ_XY xy = {0.0,0.0}; double b, cosphi; const auto *Q = &(static_cast<struct tmerc_data*>(P->opaque)->approx); - /* - * Fail if our longitude is more than 90 degrees from the - * central meridian since the results are essentially garbage. - * Is error -20 really an appropriate return value? - * - * http://trac.osgeo.org/proj/ticket/5 - */ - if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) { - xy.x = HUGE_VAL; - xy.y = HUGE_VAL; - proj_context_errno_set( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); - return xy; - } - cosphi = cos(lp.phi); b = cosphi * sin (lp.lam); if (fabs (fabs (b) - 1.) <= EPS10) { @@ -145,7 +131,12 @@ static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) { xy.y = cosphi * cos (lp.lam) / sqrt (1. - b * b); b = fabs ( xy.y ); - if (b >= 1.) { + if (cosphi == 1 && (lp.lam < -M_HALFPI || lp.lam > M_HALFPI) ) { + /* Helps to be able to roundtrip |longitudes| > 90 at lat=0 */ + /* We could also map to -M_PI ... */ + xy.y = M_PI; + } + else if (b >= 1.) { if ((b - 1.) > EPS10) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); return xy; @@ -192,7 +183,7 @@ static PJ_LP approx_e_inv (PJ_XY xy, PJ *P) { return lp; } -static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) { +static PJ_LP tmerc_spherical_inv (PJ_XY xy, PJ *P) { PJ_LP lp = {0.0, 0.0}; double h, g; const auto *Q = &(static_cast<struct tmerc_data*>(P->opaque)->approx); @@ -611,8 +602,8 @@ static PJ *setup(PJ *P, TMercAlgo eAlg) { return nullptr; if( P->es == 0 ) { - P->inv = approx_s_inv; - P->fwd = approx_s_fwd; + P->inv = tmerc_spherical_inv; + P->fwd = tmerc_spherical_fwd; } else { diff --git a/test/gie/builtins.gie b/test/gie/builtins.gie index 0f86bed2..e870f1d4 100644 --- a/test/gie/builtins.gie +++ b/test/gie/builtins.gie @@ -5771,6 +5771,74 @@ expect -223413.466406322 111769.145040597 accept -2 -1 expect -223413.466406322 -111769.145040597 +accept 0 0 +expect 0 0 +roundtrip 1 + +accept 0 90 +expect 0 10053096.491487337276 +roundtrip 1 + +accept 0 -90 +expect 0 -10053096.491487337276 +roundtrip 1 + +accept 170 60 +expect 557076.820490954560 13361866.764138307422 +roundtrip 1 + +accept 89 0.01 +expect 30344312.098578717560 64001.116414904580 +roundtrip 1 + +accept 91 0.01 +expect 30344312.098578717560 20042191.866555366665 +roundtrip 1 + +accept 179.999 0.01 +expect 111.701070433669 20105075.972255337983 +roundtrip 1 + +accept -89 0.01 +expect -30344312.098578717560 64001.116414904580 +roundtrip 1 + +accept -91 0.01 +expect -30344312.098578717560 20042191.866555366665 +roundtrip 1 + +accept -179.999 0.01 +expect -111.701070433669 20105075.972255337983 +roundtrip 1 + +accept 89 -0.01 +expect 30344312.098578717560 -64001.116414904580 +roundtrip 1 + +accept 91 -0.01 +expect 30344312.098578717560 -20042191.866555366665 +roundtrip 1 + +accept 179.999 -0.01 +expect 111.701070433669 -20105075.972255337983 +roundtrip 1 + +accept -89 -0.01 +expect -30344312.098578717560 -64001.116414904580 +roundtrip 1 + +accept -91 -0.01 +expect -30344312.098578717560 -20042191.866555366665 +roundtrip 1 + +accept -179.999 -0.01 +expect -111.701070433669 -20105075.972255337983 +roundtrip 1 + +accept 150 0 +expect 3515559.323737951461 20106192.982974674553 +roundtrip 1 + direction inverse accept 200 100 expect 0.001790493 0.000895247 |
