Skip to content

Commit 1cc1052

Browse files
committed
Apply MarceloBanik fix for #8717
1 parent 985a0c5 commit 1cc1052

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

src/gmt_map.c

+17-14
Original file line numberDiff line numberDiff line change
@@ -9271,32 +9271,35 @@ void gmt_ECEF_forward (struct GMT_CTRL *GMT, double in[], double out[]) {
92719271
}
92729272

92739273
/*! . */
9274-
void gmt_ECEF_inverse (struct GMT_CTRL *GMT, double in[], double out[]) {
9274+
void gmt_ECEF_inverse(struct GMT_CTRL *GMT, double in[], double out[]) {
92759275
/* Convert ECEF coordinates to geodetic lon, lat, height given the datum parameters.
92769276
* GMT->current.proj.datum.from is always the ellipsoid to use */
92779277

92789278
unsigned int i;
9279-
double in_p[3], sin_lat, cos_lat, N, p, theta, sin_theta, cos_theta;
9279+
double in_p[3], sin_lat, cos_lat, N, p, r, theta, sin_theta, cos_theta, slam, clam, sphi, cphi;
92809280

92819281
/* First remove the xyz shifts, us in_p to avoid changing in */
92829282
for (i = 0; i < 3; i++) in_p[i] = in[i] - GMT->current.proj.datum.from.xyz[i];
92839283

92849284
p = hypot (in_p[GMT_X], in_p[GMT_Y]);
9285-
if (p > 0.0) { /* Not the S|N pole so we can invert */
9286-
theta = atan (in_p[GMT_Z] * GMT->current.proj.datum.from.a / (p * GMT->current.proj.datum.from.b));
9287-
sincos (theta, &sin_theta, &cos_theta);
9288-
out[GMT_X] = d_atan2d (in_p[GMT_Y], in_p[GMT_X]);
9289-
out[GMT_Y] = atand ((in_p[GMT_Z] + GMT->current.proj.datum.from.ep_squared * GMT->current.proj.datum.from.b * pow (sin_theta, 3.0)) / (p - GMT->current.proj.datum.from.e_squared * GMT->current.proj.datum.from.a * pow (cos_theta, 3.0)));
9290-
if (in_p[GMT_Z] > 0.0 && out[GMT_Y] < 0.0) out[GMT_Y] = -out[GMT_Y];
9291-
if (in_p[GMT_Z] < 0.0 && out[GMT_Y] > 0.0) out[GMT_Y] = -out[GMT_Y];
9285+
slam = p != 0 ? in_p[GMT_Y] / p : 0;
9286+
clam = p != 0 ? in_p[GMT_X] / p : 1;
9287+
theta = atan(in_p[GMT_Z] * GMT->current.proj.datum.from.a / (p * GMT->current.proj.datum.from.b));
9288+
sincos(theta, &sin_theta, &cos_theta);
9289+
sphi = in_p[GMT_Z] + GMT->current.proj.datum.from.ep_squared * GMT->current.proj.datum.from.b * pow(sin_theta, 3.0);
9290+
cphi = p - GMT->current.proj.datum.from.e_squared * GMT->current.proj.datum.from.a * pow(cos_theta, 3.0);
9291+
out[GMT_X] = d_atan2d(slam, clam);
9292+
out[GMT_Y] = d_atan2d(sphi, cphi);
9293+
if (in_p[GMT_Z] > 0.0 && out[GMT_Y] < 0.0) out[GMT_Y] = -out[GMT_Y];
9294+
if (in_p[GMT_Z] < 0.0 && out[GMT_Y] > 0.0) out[GMT_Y] = -out[GMT_Y];
9295+
if (fabs(out[GMT_Y]) < 89.999) {
92929296
sincosd (out[GMT_Y], &sin_lat, &cos_lat);
9293-
N = GMT->current.proj.datum.from.a / sqrt (1.0 - GMT->current.proj.datum.from.e_squared * sin_lat * sin_lat);
9297+
N = GMT->current.proj.datum.from.a / sqrt(1.0 - GMT->current.proj.datum.from.e_squared * sin_lat * sin_lat);
92949298
out[GMT_Z] = (p / cos_lat) - N;
92959299
}
9296-
else { /* S or N pole, use sign of in_p[GMT_Z] to set latitude and height */
9297-
out[GMT_X] = 0.0; /* Might as well pick0 since any longitude will work */
9298-
out[GMT_Y] = (in_p[GMT_Z] > 0.0) ? 90.0 : -90.0; /* EIther at north or south pole, check via Z coordinate */
9299-
out[GMT_Z] = in_p[GMT_Z] - copysign (GMT->current.proj.datum.from.b, in_p[GMT_Z]);
9300+
else { /* very close to the poles */
9301+
r = hypot(p, in_p[GMT_Z]);
9302+
out[GMT_Z] = r - hypot(GMT->current.proj.datum.from.b, p);
93009303
}
93019304
}
93029305

0 commit comments

Comments
 (0)