Skip to content

Commit c188454

Browse files
authored
Apply MarceloBanik fix for #8717 (#8720)
1 parent 52cd66e commit c188454

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
@@ -9274,32 +9274,35 @@ void gmt_ECEF_forward (struct GMT_CTRL *GMT, double in[], double out[]) {
92749274
}
92759275

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

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

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

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

0 commit comments

Comments
 (0)