@@ -9268,13 +9268,22 @@ void gmt_ECEF_inverse (struct GMT_CTRL *GMT, double in[], double out[]) {
9268
9268
for (i = 0 ; i < 3 ; i ++ ) in_p [i ] = in [i ] - GMT -> current .proj .datum .from .xyz [i ];
9269
9269
9270
9270
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
+ }
9278
9287
}
9279
9288
9280
9289
#if 0
0 commit comments