Skip to content

Commit cdfa697

Browse files
committed
dca type annotation
1 parent d78f825 commit cdfa697

7 files changed

Lines changed: 105 additions & 47 deletions

File tree

src/pymap3d/dca.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
from __future__ import annotations
2525

26+
from ._typing import FloatLike
27+
2628
from .mathfun import sin, cos, radians
2729
from .ecef import ecef2enu, enu2ecef
2830
from .enu import geodetic2enu, enu2geodetic, aer2enu, enu2aer
@@ -42,7 +44,7 @@
4244
]
4345

4446

45-
def enu2dca(e, n, u, heading, deg: bool = True):
47+
def enu2dca(e: FloatLike, n: FloatLike, u: FloatLike, heading: FloatLike, deg: bool = True):
4648
"""
4749
Converts ENU (East, North, Up) coordinates to DCA (Downrange, Crossrange, Above).
4850
"""
@@ -56,7 +58,7 @@ def enu2dca(e, n, u, heading, deg: bool = True):
5658
return dr, cr, u
5759

5860

59-
def dca2enu(dr, cr, above, heading, deg: bool = True):
61+
def dca2enu(dr: FloatLike, cr: FloatLike, above: FloatLike, heading: FloatLike, deg: bool = True):
6062
"""
6163
Converts DCA (Downrange, Crossrange, Above) coordinates to ENU (East, North, Up).
6264
"""
@@ -70,23 +72,33 @@ def dca2enu(dr, cr, above, heading, deg: bool = True):
7072
return e, n, above
7173

7274

73-
def dca2ned(dr, cr, above, heading, deg: bool = True):
75+
def dca2ned(dr: FloatLike, cr: FloatLike, above: FloatLike, heading: FloatLike, deg: bool = True):
7476
"""
7577
Converts DCA (Downrange, Crossrange, Above) coordinates to NED (North, East, Down).
7678
"""
7779
e, n, u = dca2enu(dr, cr, above, heading, deg=deg)
7880
return n, e, -u
7981

8082

81-
def ned2dca(n, e, d, heading, deg: bool = True):
83+
def ned2dca(n: FloatLike, e: FloatLike, d: FloatLike, heading: FloatLike, deg: bool = True):
8284
"""
8385
Converts NED (North, East, Down) coordinates to DCA (Downrange, Crossrange, Above).
8486
"""
8587
dr, cr, above = enu2dca(e, n, -d, heading, deg=deg)
8688
return dr, cr, above
8789

8890

89-
def ecef2dca(x, y, z, lat0, lon0, h0, heading, ell: Ellipsoid | None = None, deg: bool = True):
91+
def ecef2dca(
92+
x: FloatLike,
93+
y: FloatLike,
94+
z: FloatLike,
95+
lat0: FloatLike,
96+
lon0: FloatLike,
97+
h0: FloatLike,
98+
heading: FloatLike,
99+
ell: Ellipsoid | None = None,
100+
deg: bool = True,
101+
):
90102
"""
91103
Converts ECEF (Earth-Centered, Earth-Fixed) coordinates to DCA (Downrange, Crossrange, Above).
92104
"""
@@ -96,13 +108,13 @@ def ecef2dca(x, y, z, lat0, lon0, h0, heading, ell: Ellipsoid | None = None, deg
96108

97109

98110
def dca2ecef(
99-
dr,
100-
cr,
101-
above,
102-
lat0,
103-
lon0,
104-
h0,
105-
heading,
111+
dr: FloatLike,
112+
cr: FloatLike,
113+
above: FloatLike,
114+
lat0: FloatLike,
115+
lon0: FloatLike,
116+
h0: FloatLike,
117+
heading: FloatLike,
106118
ell: Ellipsoid | None = None,
107119
deg: bool = True,
108120
):
@@ -115,7 +127,15 @@ def dca2ecef(
115127

116128

117129
def geodetic2dca(
118-
lat, lon, h, lat0, lon0, h0, heading, ell: Ellipsoid | None = None, deg: bool = True
130+
lat: FloatLike,
131+
lon: FloatLike,
132+
h: FloatLike,
133+
lat0: FloatLike,
134+
lon0: FloatLike,
135+
h0: FloatLike,
136+
heading: FloatLike,
137+
ell: Ellipsoid | None = None,
138+
deg: bool = True,
119139
):
120140
"""
121141
Converts geodetic coordinates (latitude, longitude, altitude) to DCA (Downrange, Crossrange, Above) coordinates.
@@ -125,13 +145,13 @@ def geodetic2dca(
125145

126146

127147
def dca2geodetic(
128-
dr,
129-
cr,
130-
above,
131-
lat0,
132-
lon0,
133-
h0,
134-
heading,
148+
dr: FloatLike,
149+
cr: FloatLike,
150+
above: FloatLike,
151+
lat0: FloatLike,
152+
lon0: FloatLike,
153+
h0: FloatLike,
154+
heading: FloatLike,
135155
ell: Ellipsoid | None = None,
136156
deg: bool = True,
137157
):
@@ -142,15 +162,15 @@ def dca2geodetic(
142162
return enu2geodetic(e, n, u, lat0, lon0, h0, ell, deg=deg)
143163

144164

145-
def aer2dca(az, el, srange, heading, deg: bool = True):
165+
def aer2dca(az: FloatLike, el: FloatLike, srange: FloatLike, heading: FloatLike, deg: bool = True):
146166
"""
147167
Converts AER (Azimuth, Elevation, Range) coordinates to DCA (Downrange, Crossrange, Above).
148168
"""
149169
e, n, u = aer2enu(az, el, srange, deg=deg)
150170
return enu2dca(e, n, u, heading, deg=deg)
151171

152172

153-
def dca2aer(dr, cr, above, heading, deg: bool = True):
173+
def dca2aer(dr: FloatLike, cr: FloatLike, above: FloatLike, heading: FloatLike, deg: bool = True):
154174
"""
155175
Converts DCA (Downrange, Crossrange, Above) coordinates to AER (Azimuth, Elevation, Range).
156176
"""

src/pymap3d/ecef.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ def geodetic2ecef(
8888

8989

9090
def ecef2geodetic(
91-
x: FloatArray,
92-
y: FloatArray,
93-
z: FloatArray,
91+
x: FloatLike | FloatArray,
92+
y: FloatLike | FloatArray,
93+
z: FloatLike | FloatArray,
9494
ell: Ellipsoid | None = None,
9595
deg: bool = True,
9696
) -> tuple:
@@ -138,7 +138,7 @@ def ecef2geodetic(
138138

139139
huE = hypot(u, E)
140140

141-
def _inside_numpy(x: FloatArray, y: FloatArray, z: FloatArray):
141+
def _inside_numpy(x, y, z) -> NDArray:
142142
# inside ellipsoid?
143143
return (
144144
x**2 / ell.semimajor_axis**2
@@ -156,7 +156,7 @@ def _inside_scalar(x: float, y: float, z: float) -> bool:
156156
< 1
157157
)
158158

159-
def _lat_alt_numpy(x: NDArray, y: NDArray, z: NDArray, Beta: NDArray) -> tuple:
159+
def _lat_alt_numpy(x, y, z, Beta) -> tuple:
160160
"""eqation 4c using Numpy"""
161161
lat = atan(ell.semimajor_axis / ell.semiminor_axis * tan(Beta))
162162
# patch latitude for float32 precision loss

src/pymap3d/nvector.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from __future__ import annotations
22

3+
from ._typing import FloatLike
34
from .mathfun import degrees, radians, sin, cos, atan2, asin
45
from .ecef import geodetic2ecef, ecef2geodetic
56
from .ellipsoid import Ellipsoid
67

78

8-
def geodetic2nvector(lat, lon, deg: bool = True) -> tuple:
9+
def geodetic2nvector(lat: FloatLike, lon: FloatLike, deg: bool = True) -> tuple:
910
"""
1011
Convert geodetic coordinates (latitude, longitude) to an n-vector.
1112
@@ -37,7 +38,7 @@ def geodetic2nvector(lat, lon, deg: bool = True) -> tuple:
3738
return n1, n2, n3
3839

3940

40-
def nvector2geodetic(n1, n2, n3, deg=True) -> tuple:
41+
def nvector2geodetic(n1: FloatLike, n2: FloatLike, n3: FloatLike, deg: bool = True) -> tuple:
4142
"""
4243
Convert an n-vector back to geodetic coordinates (latitude, longitude).
4344
@@ -64,7 +65,9 @@ def nvector2geodetic(n1, n2, n3, deg=True) -> tuple:
6465
return lat, lon
6566

6667

67-
def ecef2nvector(x, y, z, ell: Ellipsoid | None = None, deg: bool = True):
68+
def ecef2nvector(
69+
x: FloatLike, y: FloatLike, z: FloatLike, ell: Ellipsoid | None = None, deg: bool = True
70+
):
6871
"""
6972
Convert ECEF coordinates to an n-vector.
7073
@@ -85,7 +88,14 @@ def ecef2nvector(x, y, z, ell: Ellipsoid | None = None, deg: bool = True):
8588
return geodetic2nvector(lat, lon, deg=deg)
8689

8790

88-
def nvector2ecef(n1, n2, n3, alt=0, ell: Ellipsoid | None = None, deg: bool = True):
91+
def nvector2ecef(
92+
n1: FloatLike,
93+
n2: FloatLike,
94+
n3: FloatLike,
95+
alt: FloatLike = 0,
96+
ell: Ellipsoid | None = None,
97+
deg: bool = True,
98+
):
8999
"""
90100
Convert an n-vector to ECEF coordinates.
91101

src/pymap3d/sidereal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import logging
99

1010
from .timeconv import str2dt
11-
from ._typing import FloatLike, DatetimeLike
11+
from ._typing import FloatLike, DatetimeLike
1212

1313
try:
1414
import astropy.units as u

src/pymap3d/tests/test_dca.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,25 @@ def get_ellipsoid_params():
2121
)
2222
def test_enu_dca(enu, dca, heading):
2323

24-
assert pm.dca2enu(*dca, heading) == pytest.approx(enu)
25-
assert pm.enu2dca(*enu, heading) == pytest.approx(dca)
24+
assert pm.dca2enu(*dca, heading=heading) == pytest.approx(enu)
25+
assert pm.enu2dca(*enu, heading=heading) == pytest.approx(dca)
2626

2727
ned = enu[1], enu[0], -enu[2]
28-
assert pm.dca2ned(*dca, heading) == pytest.approx(ned)
29-
assert pm.ned2dca(*ned, heading) == pytest.approx(dca)
28+
assert pm.dca2ned(*dca, heading=heading) == pytest.approx(ned)
29+
assert pm.ned2dca(*ned, heading=heading) == pytest.approx(dca)
30+
31+
32+
def test_enu_dca_numpy():
33+
np = pytest.importorskip("numpy")
34+
e = np.array([0, 0, 0])
35+
n = np.array([0, 0, 0])
36+
u = np.array([0, 0, 0])
37+
d = np.array([0, 0, 0])
38+
c = np.array([0, 0, 0])
39+
a = np.array([0, 0, 0])
40+
heading = 15
41+
assert pm.dca2enu(d, c, a, heading=heading) == pytest.approx((0, 0, 0))
42+
assert pm.enu2dca(e, n, u, heading=heading) == pytest.approx((0, 0, 0))
3043

3144

3245
@pytest.mark.parametrize(

src/pymap3d/tests/test_enu.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,26 @@ def test_scalar_enu(xyz):
2828
def test_array_enu():
2929
np = pytest.importorskip("numpy")
3030

31-
xyz = (np.asarray(0), np.asarray(A), np.asarray(50))
32-
llh = (np.asarray(0), np.asarray(90), np.asarray(-100))
33-
enu = pm.ecef2enu(*xyz, *llh)
34-
assert pm.enu2ecef(*enu, *llh) == approx(xyz)
31+
x = np.asarray(0)
32+
y = np.asarray(A)
33+
z = np.asarray(50)
34+
lat = np.asarray(0)
35+
lon = np.asarray(90)
36+
h = np.asarray(-100)
3537

36-
xyz = (np.atleast_1d(0), np.atleast_1d(A), np.atleast_1d(50))
37-
llh = (np.atleast_1d(0), np.atleast_1d(90), np.atleast_1d(-100))
38-
enu = pm.ecef2enu(*xyz, *llh)
39-
assert pm.enu2ecef(*enu, *llh) == approx(xyz)
38+
e, n, u = pm.ecef2enu(x, y, z, lat, lon, h)
39+
40+
assert pm.enu2ecef(e, n, u, lat, lon, h) == approx((x, y, z))
41+
42+
x = np.atleast_1d(0)
43+
y = np.atleast_1d(A)
44+
z = np.atleast_1d(50)
45+
lat = np.atleast_1d(0)
46+
lon = np.atleast_1d(90)
47+
h = np.atleast_1d(-100)
48+
49+
e, n, u = pm.ecef2enu(x, y, z, lat, lon, h)
50+
assert pm.enu2ecef(e, n, u, lat, lon, h) == approx((x, y, z))
4051

4152

4253
@pytest.mark.parametrize(
@@ -52,8 +63,11 @@ def test_enu_ecef(enu, lla, xyz):
5263
assert isinstance(y, float)
5364
assert isinstance(z, float)
5465

55-
rlla = (radians(lla[0]), radians(lla[1]), lla[2])
56-
assert pm.enu2ecef(*enu, *rlla, deg=False) == approx(xyz)
66+
rlat = radians(lla[0])
67+
rlon = radians(lla[1])
68+
rh = lla[2]
69+
70+
assert pm.enu2ecef(*enu, rlat, rlon, rh, deg=False) == approx(xyz)
5771

5872
e, n, u = pm.ecef2enu(*xyz, *lla)
5973
assert e == approx(enu[0])
@@ -63,7 +77,7 @@ def test_enu_ecef(enu, lla, xyz):
6377
assert isinstance(n, float)
6478
assert isinstance(u, float)
6579

66-
e, n, u = pm.ecef2enu(*xyz, *rlla, deg=False)
80+
e, n, u = pm.ecef2enu(*xyz, rlat, rlon, rh, deg=False)
6781
assert e == approx(enu[0])
6882
assert n == approx(enu[1])
6983
assert u == approx(enu[2])

src/pymap3d/tests/test_rsphere.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def test_rsphere_eqavol():
2222
def test_rsphere_authalic():
2323
assert rsphere.authalic() == approx(6371007.1809)
2424

25+
2526
def test_rsphere_curve():
2627
assert rsphere.curve(0) == approx(6356788.163646411)
2728
assert rsphere.curve(90) == approx(6399593.625758492)

0 commit comments

Comments
 (0)