Skip to content

Commit 7825ff4

Browse files
authored
Detect pole in inverse ECEF in mapproject (#8117)
* Detect pole in inverse ECEF See issue reported on the forum. When x^2 + y^2 is zero we are at one of the poles so avoid dividing by 0. * Update gmt_map.c * Update gmt_map.c
1 parent 0f1bc88 commit 7825ff4

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/gmt_map.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -9268,13 +9268,22 @@ void gmt_ECEF_inverse (struct GMT_CTRL *GMT, double in[], double out[]) {
92689268
for (i = 0; i < 3; i++) in_p[i] = in[i] - GMT->current.proj.datum.from.xyz[i];
92699269

92709270
p = hypot (in_p[GMT_X], in_p[GMT_Y]);
9271-
theta = atan (in_p[GMT_Z] * GMT->current.proj.datum.from.a / (p * GMT->current.proj.datum.from.b));
9272-
sincos (theta, &sin_theta, &cos_theta);
9273-
out[GMT_X] = d_atan2d (in_p[GMT_Y], in_p[GMT_X]);
9274-
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)));
9275-
sincosd (out[GMT_Y], &sin_lat, &cos_lat);
9276-
N = GMT->current.proj.datum.from.a / sqrt (1.0 - GMT->current.proj.datum.from.e_squared * sin_lat * sin_lat);
9277-
out[GMT_Z] = (p / cos_lat) - N;
9271+
if (p > 0.0) { /* Not the S|N pole so we can invert */
9272+
theta = atan (in_p[GMT_Z] * GMT->current.proj.datum.from.a / (p * GMT->current.proj.datum.from.b));
9273+
sincos (theta, &sin_theta, &cos_theta);
9274+
out[GMT_X] = d_atan2d (in_p[GMT_Y], in_p[GMT_X]);
9275+
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)));
9276+
if (in_p[GMT_Z] > 0.0 && out[GMT_Y] < 0.0) out[GMT_Y] = -out[GMT_Y];
9277+
if (in_p[GMT_Z] < 0.0 && out[GMT_Y] > 0.0) out[GMT_Y] = -out[GMT_Y];
9278+
sincosd (out[GMT_Y], &sin_lat, &cos_lat);
9279+
N = GMT->current.proj.datum.from.a / sqrt (1.0 - GMT->current.proj.datum.from.e_squared * sin_lat * sin_lat);
9280+
out[GMT_Z] = (p / cos_lat) - N;
9281+
}
9282+
else { /* S or N pole, use sign of in_p[GMT_Z] to set latitude and height */
9283+
out[GMT_X] = 0.0; /* Might as well pick0 since any longitude will work */
9284+
out[GMT_Y] = (in_p[GMT_Z] > 0.0) ? 90.0 : -90.0; /* EIther at north or south pole, check via Z coordinate */
9285+
out[GMT_Z] = in_p[GMT_Z] - copysign (GMT->current.proj.datum.from.b, in_p[GMT_Z]);
9286+
}
92789287
}
92799288

92809289
#if 0

0 commit comments

Comments
 (0)