Skip to content

Commit 28e6194

Browse files
committed
bonne: fix inverse map projection computations when lat_1 < 0 (fixes OSGeo#3848)
The fixes are directly following hints of Snyder's "Map projections: A working manual"
1 parent a654e42 commit 28e6194

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

src/projections/bonne.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,35 +55,45 @@ static PJ_XY bonne_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
5555
static PJ_LP bonne_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
5656
PJ_LP lp = {0.0, 0.0};
5757
struct pj_opaque *Q = static_cast<struct pj_opaque *>(P->opaque);
58-
double rh;
5958

6059
xy.y = Q->cphi1 - xy.y;
61-
rh = hypot(xy.x, xy.y);
60+
const double rh = copysign(hypot(xy.x, xy.y), Q->phi1);
6261
lp.phi = Q->cphi1 + Q->phi1 - rh;
63-
if (fabs(lp.phi) > M_HALFPI) {
62+
const double abs_phi = fabs(lp.phi);
63+
if (abs_phi > M_HALFPI) {
6464
proj_errno_set(P, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN);
6565
return lp;
6666
}
67-
if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10)
67+
if (M_HALFPI - abs_phi <= EPS10)
6868
lp.lam = 0.;
69-
else
70-
lp.lam = rh * atan2(xy.x, xy.y) / cos(lp.phi);
69+
else {
70+
const double lm = rh / cos(lp.phi);
71+
if (Q->phi1 > 0) {
72+
lp.lam = lm * atan2(xy.x, xy.y);
73+
} else {
74+
lp.lam = lm * atan2(-xy.x, -xy.y);
75+
}
76+
}
7177
return lp;
7278
}
7379

7480
static PJ_LP bonne_e_inverse(PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */
7581
PJ_LP lp = {0.0, 0.0};
7682
struct pj_opaque *Q = static_cast<struct pj_opaque *>(P->opaque);
77-
double s, rh;
7883

7984
xy.y = Q->am1 - xy.y;
80-
rh = hypot(xy.x, xy.y);
85+
const double rh = copysign(hypot(xy.x, xy.y), Q->phi1);
8186
lp.phi = pj_inv_mlfn(Q->am1 + Q->m1 - rh, Q->en);
82-
if ((s = fabs(lp.phi)) < M_HALFPI) {
83-
s = sin(lp.phi);
84-
lp.lam =
85-
rh * atan2(xy.x, xy.y) * sqrt(1. - P->es * s * s) / cos(lp.phi);
86-
} else if (fabs(s - M_HALFPI) <= EPS10)
87+
const double abs_phi = fabs(lp.phi);
88+
if (abs_phi < M_HALFPI) {
89+
const double sinphi = sin(lp.phi);
90+
const double lm = rh * sqrt(1. - P->es * sinphi * sinphi) / cos(lp.phi);
91+
if (Q->phi1 > 0) {
92+
lp.lam = lm * atan2(xy.x, xy.y);
93+
} else {
94+
lp.lam = lm * atan2(-xy.x, -xy.y);
95+
}
96+
} else if (abs_phi - M_HALFPI <= EPS10)
8797
lp.lam = 0.;
8898
else {
8999
proj_errno_set(P, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN);

test/gie/builtins.gie

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,18 @@ expect -0.001796699 0.500904369
686686
accept -200 -100
687687
expect -0.001796698 0.499095631
688688

689+
-------------------------------------------------------------------------------
690+
operation +proj=bonne +ellps=GRS80 +lat_1=-0.5
691+
-------------------------------------------------------------------------------
692+
tolerance 0.1 mm
693+
accept 2 1
694+
expect 222605.2961 165827.6478
695+
roundtrip 1
696+
697+
accept 2 -1
698+
expect 222605.2961 -55321.1396
699+
roundtrip 1
700+
689701
-------------------------------------------------------------------------------
690702
operation +proj=bonne +ellps=GRS80 +lat_1=90
691703
-------------------------------------------------------------------------------
@@ -697,6 +709,17 @@ direction inverse
697709
accept 0 0
698710
expect 0 90
699711

712+
-------------------------------------------------------------------------------
713+
operation +proj=bonne +ellps=GRS80 +lat_1=-90
714+
-------------------------------------------------------------------------------
715+
tolerance 0.1 mm
716+
accept 0 -90
717+
expect 0 0
718+
719+
direction inverse
720+
accept 0 0
721+
expect 0 -90
722+
700723
-------------------------------------------------------------------------------
701724
operation +proj=bonne +R=6400000 +lat_1=0.5
702725
-------------------------------------------------------------------------------
@@ -720,6 +743,18 @@ expect -0.001790562 0.500895246
720743
accept -200 -100
721744
expect -0.001790561 0.499104753
722745

746+
-------------------------------------------------------------------------------
747+
operation +proj=bonne +R=6400000 +lat_1=-0.5
748+
-------------------------------------------------------------------------------
749+
tolerance 0.1 mm
750+
accept 2 1
751+
expect 223368.1156 167517.5994
752+
roundtrip 1
753+
754+
accept 2 -1
755+
expect 223368.1156 -55884.5552
756+
roundtrip 1
757+
723758
-------------------------------------------------------------------------------
724759
operation +proj=bonne +R=6400000 +lat_1=90
725760
-------------------------------------------------------------------------------
@@ -731,6 +766,17 @@ direction inverse
731766
accept 0 0
732767
expect 0 90
733768

769+
-------------------------------------------------------------------------------
770+
operation +proj=bonne +R=6400000 +lat_1=-90
771+
-------------------------------------------------------------------------------
772+
tolerance 0.1 mm
773+
accept 0 -90
774+
expect 0 0
775+
776+
direction inverse
777+
accept 0 0
778+
expect 0 -90
779+
734780
===============================================================================
735781
# Cal Coop Ocean Fish Invest Lines/Stations
736782
# Cyl, Sph&Ell

0 commit comments

Comments
 (0)