Skip to content

Commit f1feb1e

Browse files
committed
handle vector input for height computation, move to new function
1 parent 4ca0a99 commit f1feb1e

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

skyfield/tests/test_topos.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def test_intersection_from_pole(ts):
260260
error_degrees = abs(earth_point.latitude.degrees - 90.0)
261261
error_mas = 60.0 * 60.0 * 1000.0 * error_degrees
262262
assert error_mas < 0.1
263-
assert earth_point.elevation.m < 0.01
263+
assert earth_point.elevation.m < 0.1
264264

265265
def test_intersection_from_equator(ts):
266266
t = ts.utc(2018, 1, 19, 14, 37, 55)
@@ -275,7 +275,7 @@ def test_intersection_from_equator(ts):
275275
error_degrees = abs(earth_point.longitude.degrees - 0.0)
276276
error_mas = 60.0 * 60.0 * 1000.0 * error_degrees
277277
assert error_mas < 0.1
278-
assert earth_point.elevation.m < 0.01
278+
assert earth_point.elevation.m < 0.1
279279

280280
def test_limb_intersection_points(ts):
281281
t = ts.utc(2018, 1, 19, 14, 37, 55)
@@ -307,23 +307,23 @@ def test_limb_intersection_points(ts):
307307

308308
error_degrees = abs(intersection_bottom.latitude.degrees + 90.0)
309309
assert error_degrees < 0.1
310-
assert intersection_bottom.elevation.m < 0.01
310+
assert intersection_bottom.elevation.m < 0.1
311311

312312
error_degrees = abs(intersection_top.latitude.degrees - 90.0)
313313
assert error_degrees < 0.1
314-
assert intersection_top.elevation.m < 0.01
314+
assert intersection_top.elevation.m < 0.1
315315

316316
error_degrees = abs(intersection_left.latitude.degrees - 0.0)
317317
assert error_degrees < 0.1
318318

319319
error_degrees = abs(intersection_left.longitude.degrees - left_limb_lon)
320320
assert error_degrees < 0.1
321-
assert intersection_left.elevation.m < 0.01
321+
assert intersection_left.elevation.m < 0.1
322322

323323
error_degrees = abs(intersection_right.latitude.degrees - 0.0)
324324
assert error_degrees < 0.1
325325

326326
error_degrees = abs(intersection_right.longitude.degrees - right_limb_lon)
327327
assert error_degrees < 0.1
328-
assert intersection_right.elevation.m < 0.01
328+
assert intersection_right.elevation.m < 0.1
329329

skyfield/toposlib.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# -*- coding: utf-8 -*-
22

3-
from numpy import arctan2, array, array2string, cos, exp, sin, sqrt
3+
from numpy import (
4+
arctan2, array, array2string, asarray, cos, exp, float64, sin, sqrt
5+
)
6+
47
from .constants import ANGVEL, DAY_S, RAD2DEG, T0, pi, tau
58
from .earthlib import refract
69
from .framelib import itrs
@@ -212,12 +215,18 @@ def height_of(self, position):
212215
213216
"""
214217
xyz_au, x, y, aC, R, lat = self._compute_latitude(position)
215-
if R > 1.e-12:
216-
height_au = R / cos(lat) - aC
217-
else:
218-
height_au = abs(xyz_au[2]) - self.semi_minor_axis.au
218+
height_au = self._compute_height(R, lat, aC, xyz_au)
219219
return Distance(height_au)
220220

221+
def _compute_height(self, R, lat, aC, xyz_au):
222+
height_au = asarray(R)
223+
near_pole = height_au <= 1.e-12
224+
if near_pole.any():
225+
height_au[near_pole] = abs(xyz_au[2]) - self.semi_minor_axis.au
226+
else:
227+
height_au[~near_pole] = R / cos(lat) - aC
228+
return float64(height_au)
229+
221230
def geographic_position_of(self, position):
222231
"""Return the `GeographicPosition` of a ``position``.
223232
@@ -229,10 +238,7 @@ def geographic_position_of(self, position):
229238
"""
230239
xyz_au, x, y, aC, R, lat = self._compute_latitude(position)
231240
lon = (arctan2(y, x) - pi) % tau - pi
232-
if R > 1.e-12:
233-
height_au = R / cos(lat) - aC
234-
else:
235-
height_au = abs(xyz_au[2]) - self.semi_minor_axis.au
241+
height_au = self._compute_height(R, lat, aC, xyz_au)
236242
return GeographicPosition(
237243
latitude=Angle(radians=lat),
238244
longitude=Angle(radians=lon),
@@ -280,12 +286,13 @@ def intersection_of(self, position, direction):
280286
"""Return the surface point intersected by a vector.
281287
282288
The ``position`` and ``direction`` describe the tail and orientation
283-
of the vector to intersect the ellipsoid, respectively. The vector must
284-
be provided in ICRF coordinates with a ``.center``` of 399, the center
285-
of the Earth. The direction should be an |xyz| unit vector. Returns a
286-
`GeographicPosition` giving the geodetic ``latitude`` and ``longitude``
287-
at the point that the ray intersects the surface of the Earth.
288-
289+
of the vector to intersect the ellipsoid, respectively. The position
290+
must be provided in ICRF coordinates with a ``.center``` of 399, the
291+
center of the Earth. The direction should be an |xyz| unit vector in
292+
the same coordinate frame. Returns a `GeographicPosition` giving the
293+
geodetic ``latitude`` and ``longitude`` at the point that the ray
294+
intersects the surface of the Earth.
295+
289296
The main calculation implemented here is based on JPL's NAIF toolkit;
290297
https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/ellipses.html
291298
"""
@@ -309,7 +316,7 @@ def intersection_of(self, position, direction):
309316

310317
# Define a distortion matrix to map the ellipsoid into a unit sphere
311318
a = self.radius.au
312-
c = a * (1.0 - 1.0 / self.inverse_flattening)
319+
c = self.semi_minor_axis.au
313320
d_matrix = array(
314321
[[1.0 / a, 0.0, 0.0], [0.0, 1.0 / a, 0.0], [0.0, 0.0, 1.0 / c]]
315322
)
@@ -344,9 +351,9 @@ def intersection_of(self, position, direction):
344351
)
345352

346353
# Retrieve latitude and longitude
347-
intersection_latlon = self.geographic_position_of(intersection)
354+
geo_intersection = self.geographic_position_of(intersection)
348355

349-
return intersection_latlon
356+
return geo_intersection
350357

351358
wgs84 = Geoid('WGS84', 6378137.0, 298.257223563)
352359
iers2010 = Geoid('IERS2010', 6378136.6, 298.25642)

0 commit comments

Comments
 (0)