Skip to content

Commit f3a3a53

Browse files
committed
ecef2geodetic: avoid NaN and needless computation
attempt to fix #87
1 parent 4f2e7eb commit f3a3a53

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/pymap3d/ecef.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,20 @@ def ecef2geodetic(
138138
# eqn. 4a
139139
u = sqrt(0.5 * (r**2 - E**2) + 0.5 * hypot(r**2 - E**2, 2 * E * z))
140140

141-
Q = hypot(x, y)
141+
hxy = hypot(x, y)
142142

143143
huE = hypot(u, E)
144144

145145
# eqn. 4b
146146
try:
147147
Beta = empty_like(r)
148-
ibad = isclose(u, 0) | isclose(Q, 0)
149-
Beta[~ibad] = atan(huE[~ibad] / u[~ibad] * z[~ibad] / Q[~ibad])
148+
ibad = isclose(u, 0) | isclose(hxy, 0)
149+
Beta[~ibad] = atan(huE[~ibad] / u[~ibad] * z[~ibad] / hxy[~ibad])
150+
# eqn. 13
151+
Beta[~ibad] += (
152+
(ell.semiminor_axis * u[~ibad] - ell.semimajor_axis * huE[~ibad] + E**2)
153+
* sin(Beta[~ibad])
154+
) / (ell.semimajor_axis * huE[~ibad] * 1 / cos(Beta[~ibad]) - E**2 * cos(Beta[~ibad]))
150155
iz = ibad & isclose(z, 0)
151156
i1 = ibad & ~iz & (z > 0)
152157
i2 = ibad & ~iz & ~i1
@@ -158,7 +163,14 @@ def ecef2geodetic(
158163
try:
159164
with warnings.catch_warnings(record=True):
160165
warnings.simplefilter("error")
161-
Beta = atan(huE / u * z / Q)
166+
Beta = atan(huE / u * z / hxy)
167+
# eqn. 13
168+
Beta += (
169+
(ell.semiminor_axis * u - ell.semimajor_axis * huE + E**2) * sin(Beta)
170+
) / (
171+
ell.semimajor_axis * huE * 1 / cos(Beta)
172+
- E**2 * cos(Beta)
173+
)
162174
except (ArithmeticError, RuntimeWarning):
163175
if isclose(z, 0):
164176
Beta = 0
@@ -167,20 +179,13 @@ def ecef2geodetic(
167179
else:
168180
Beta = -pi / 2
169181

170-
# eqn. 13
171-
dBeta = ((ell.semiminor_axis * u - ell.semimajor_axis * huE + E**2) * sin(Beta)) / (
172-
ell.semimajor_axis * huE * 1 / cos(Beta) - E**2 * cos(Beta)
173-
)
174-
175-
Beta += dBeta
176-
177182
# eqn. 4c
178183
# %% final output
179184
lat = atan(ell.semimajor_axis / ell.semiminor_axis * tan(Beta))
180185

181186
try:
182187
# patch latitude for float32 precision loss
183-
lim_pi2 = pi / 2 - finfo(dBeta.dtype).eps
188+
lim_pi2 = pi / 2 - finfo(Beta.dtype).eps
184189
lat = where(Beta >= lim_pi2, pi / 2, lat)
185190
lat = where(Beta <= -lim_pi2, -pi / 2, lat)
186191
except NameError:
@@ -197,7 +202,7 @@ def ecef2geodetic(
197202
except NameError:
198203
pass
199204

200-
alt = hypot(z - ell.semiminor_axis * sin(Beta), Q - ell.semimajor_axis * cosBeta)
205+
alt = hypot(z - ell.semiminor_axis * sin(Beta), hxy - ell.semimajor_axis * cosBeta)
201206

202207
# inside ellipsoid?
203208
inside = (

0 commit comments

Comments
 (0)