pygeodesy 24.5.15__py2.py3-none-any.whl → 24.6.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
- PyGeodesy-24.6.1.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +4 -4
- pygeodesy/albers.py +41 -41
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +32 -31
- pygeodesy/auxilats/auxLat.py +80 -51
- pygeodesy/azimuthal.py +123 -124
- pygeodesy/basics.py +46 -10
- pygeodesy/booleans.py +13 -14
- pygeodesy/cartesianBase.py +25 -23
- pygeodesy/clipy.py +3 -3
- pygeodesy/constants.py +3 -3
- pygeodesy/css.py +50 -42
- pygeodesy/datums.py +42 -41
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/dms.py +6 -6
- pygeodesy/ecef.py +41 -41
- pygeodesy/ellipsoidalBase.py +41 -41
- pygeodesy/ellipsoidalBaseDI.py +3 -4
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoidalNvector.py +11 -12
- pygeodesy/ellipsoids.py +45 -38
- pygeodesy/elliptic.py +3 -4
- pygeodesy/epsg.py +4 -3
- pygeodesy/errors.py +52 -20
- pygeodesy/etm.py +68 -65
- pygeodesy/fmath.py +44 -49
- pygeodesy/formy.py +129 -115
- pygeodesy/frechet.py +118 -103
- pygeodesy/fstats.py +21 -14
- pygeodesy/fsums.py +124 -80
- pygeodesy/gars.py +10 -9
- pygeodesy/geodesicw.py +19 -17
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +39 -33
- pygeodesy/geodesicx/gxarea.py +12 -9
- pygeodesy/geodesicx/gxbases.py +3 -4
- pygeodesy/geodesicx/gxline.py +6 -8
- pygeodesy/geodsolve.py +29 -28
- pygeodesy/geohash.py +60 -57
- pygeodesy/geoids.py +34 -32
- pygeodesy/hausdorff.py +114 -101
- pygeodesy/heights.py +137 -130
- pygeodesy/internals.py +16 -11
- pygeodesy/interns.py +3 -6
- pygeodesy/iters.py +19 -17
- pygeodesy/karney.py +21 -17
- pygeodesy/ktm.py +25 -18
- pygeodesy/latlonBase.py +12 -11
- pygeodesy/lazily.py +6 -6
- pygeodesy/lcc.py +24 -25
- pygeodesy/ltp.py +143 -113
- pygeodesy/ltpTuples.py +207 -150
- pygeodesy/mgrs.py +26 -26
- pygeodesy/named.py +172 -90
- pygeodesy/namedTuples.py +33 -25
- pygeodesy/nvectorBase.py +8 -8
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +18 -18
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +13 -10
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +18 -18
- pygeodesy/sphericalBase.py +17 -21
- pygeodesy/sphericalTrigonometry.py +21 -21
- pygeodesy/streprs.py +5 -5
- pygeodesy/trf.py +13 -11
- pygeodesy/triaxials.py +68 -64
- pygeodesy/units.py +35 -35
- pygeodesy/unitsBase.py +24 -11
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +3 -3
- pygeodesy/utm.py +183 -187
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +104 -106
- pygeodesy/vector2d.py +6 -7
- pygeodesy/vector3d.py +16 -17
- pygeodesy/vector3dBase.py +4 -5
- pygeodesy/webmercator.py +43 -51
- PyGeodesy-24.5.15.dist-info/RECORD +0 -116
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/ltp.py
CHANGED
|
@@ -13,23 +13,23 @@ and L{ChLVe} and L{Ltp}, L{ChLV}, L{LocalError}, L{Attitude} and L{Frustum}.
|
|
|
13
13
|
# make sure int/int division yields float quotient, see .basics
|
|
14
14
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
15
15
|
|
|
16
|
-
from pygeodesy.basics import _args_kwds_names,
|
|
16
|
+
from pygeodesy.basics import _args_kwds_names, map1, map2, _xsubclassof # .datums
|
|
17
17
|
from pygeodesy.constants import EPS, INT0, _umod_360, _0_0, _0_01, _0_5, _1_0, \
|
|
18
18
|
_2_0, _60_0, _90_0, _100_0, _180_0, _3600_0, \
|
|
19
19
|
_N_1_0 # PYCHOK used!
|
|
20
20
|
from pygeodesy.datums import _WGS84, _xinstanceof
|
|
21
21
|
from pygeodesy.ecef import _EcefBase, EcefKarney, _llhn4, _xyzn4
|
|
22
22
|
from pygeodesy.errors import _NotImplementedError, _TypesError, _ValueError, \
|
|
23
|
-
_xattr, _xkwds, _xkwds_get
|
|
23
|
+
_xattr, _xkwds, _xkwds_get, _xkwds_pop2
|
|
24
24
|
from pygeodesy.fmath import fabs, fdot, Fhorner
|
|
25
25
|
from pygeodesy.fsums import _floor, _Fsumf_, fsumf_, fsum1f_
|
|
26
|
-
from pygeodesy.interns import
|
|
27
|
-
|
|
26
|
+
from pygeodesy.interns import _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, _M_, \
|
|
27
|
+
_invalid_, _lat0_, _lon0_, _ltp_, _name_, _too_
|
|
28
28
|
# from pygeodesy.lazily import _ALL_LAZY # from vector3d
|
|
29
29
|
from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
|
|
30
30
|
ChLVYX2Tuple, Footprint5Tuple, Local9Tuple, \
|
|
31
31
|
ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
|
|
32
|
-
from pygeodesy.named import _NamedBase, notOverloaded
|
|
32
|
+
from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
|
|
33
33
|
from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
|
|
34
34
|
from pygeodesy.props import Property, Property_RO, property_doc_, property_RO, \
|
|
35
35
|
_update_all
|
|
@@ -42,44 +42,34 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
|
|
|
42
42
|
# from math import fabs, floor as _floor # from .fmath, .fsums
|
|
43
43
|
|
|
44
44
|
__all__ = _ALL_LAZY.ltp
|
|
45
|
-
__version__ = '24.
|
|
45
|
+
__version__ = '24.05.31'
|
|
46
46
|
|
|
47
47
|
_height0_ = _height_ + _0_
|
|
48
48
|
_narrow_ = 'narrow'
|
|
49
49
|
_wide_ = 'wide'
|
|
50
|
-
_Xyz_ = 'Xyz'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _fov_2(**fov):
|
|
54
|
-
# Half a field-of-view angle in C{degrees}.
|
|
55
|
-
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
56
|
-
if EPS < f < _90_0:
|
|
57
|
-
return f
|
|
58
|
-
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
59
|
-
raise LocalError(txt=t, **fov)
|
|
60
50
|
|
|
61
51
|
|
|
62
52
|
class Attitude(_NamedBase):
|
|
63
|
-
'''The
|
|
53
|
+
'''The pose of a plane or camera in space.
|
|
64
54
|
'''
|
|
65
55
|
_alt = Meter( alt =_0_0)
|
|
66
56
|
_roll = Degrees(roll=_0_0)
|
|
67
57
|
_tilt = Degrees(tilt=_0_0)
|
|
68
58
|
_yaw = Bearing(yaw =_0_0)
|
|
69
59
|
|
|
70
|
-
def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, name
|
|
60
|
+
def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, **name):
|
|
71
61
|
'''New L{Attitude}.
|
|
72
62
|
|
|
73
|
-
@kwarg alt_attitude:
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
@kwarg alt_attitude: Altitude (C{meter}) above earth or previous attitude
|
|
64
|
+
(L{Attitude} or L{Attitude4Tuple}) with the C{B{alt}itude},
|
|
65
|
+
B{C{tilt}}, B{C{yaw}} and B{C{roll}}.
|
|
76
66
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees180}), negative down
|
|
77
67
|
(clockwise rotation along and around the x- or East axis).
|
|
78
68
|
@kwarg yaw: Bearing, heading (compass C{degrees360}), clockwise from North
|
|
79
69
|
(counter-clockwise rotation along and around the z- or Up axis).
|
|
80
70
|
@kwarg roll: Roll, bank (C{degrees180}), positive to the right and down
|
|
81
71
|
(clockwise rotation along and around the y- or North axis).
|
|
82
|
-
@kwarg name: Optional name C{str}).
|
|
72
|
+
@kwarg name: Optional C{B{name}=NN} C{str}).
|
|
83
73
|
|
|
84
74
|
@raise AttitudeError: Invalid B{C{alt_attitude}}, B{C{tilt}}, B{C{yaw}} or
|
|
85
75
|
B{C{roll}}.
|
|
@@ -97,7 +87,7 @@ class Attitude(_NamedBase):
|
|
|
97
87
|
for n, v in t.items():
|
|
98
88
|
if v:
|
|
99
89
|
setattr(self, n, v)
|
|
100
|
-
n = name
|
|
90
|
+
n = _name__(name, _or_nameof=t)
|
|
101
91
|
if n:
|
|
102
92
|
self.name = n
|
|
103
93
|
|
|
@@ -149,23 +139,26 @@ class Attitude(_NamedBase):
|
|
|
149
139
|
|
|
150
140
|
bank = roll
|
|
151
141
|
|
|
152
|
-
def rotate(self, x_xyz, y=None, z=None, Vector=None, **
|
|
142
|
+
def rotate(self, x_xyz, y=None, z=None, Vector=None, **name_Vector_kwds):
|
|
153
143
|
'''Transform a (local) cartesian by this attitude's matrix.
|
|
154
144
|
|
|
155
|
-
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector
|
|
156
|
-
|
|
145
|
+
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Cartesian},
|
|
146
|
+
L{Vector3d} or L{Vector3Tuple}).
|
|
157
147
|
@kwarg y: Y component of vector (C{scalar}), same units as B{C{x}}.
|
|
158
148
|
@kwarg z: Z component of vector (C{scalar}), same units as B{C{x}}.
|
|
159
|
-
@kwarg Vector: Class to return transformed point (C{Cartesian},
|
|
160
|
-
|
|
161
|
-
@kwarg
|
|
162
|
-
|
|
149
|
+
@kwarg Vector: Class to return transformed point (C{Cartesian}, L{Vector3d}
|
|
150
|
+
or C{Vector3Tuple}) or C{None}.
|
|
151
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
152
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
153
|
+
C{B{Vector} is None}.
|
|
163
154
|
|
|
164
|
-
@return: A B{C{Vector}} instance or
|
|
165
|
-
C{
|
|
155
|
+
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
156
|
+
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
166
157
|
|
|
167
158
|
@raise AttitudeError: Invalid B{C{x_xyz}}, B{C{y}} or B{C{z}}.
|
|
168
159
|
|
|
160
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
161
|
+
|
|
169
162
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}.
|
|
170
163
|
'''
|
|
171
164
|
try:
|
|
@@ -177,8 +170,9 @@ class Attitude(_NamedBase):
|
|
|
177
170
|
raise AttitudeError(x_xyz=x_xyz, y=y, z=z, cause=x)
|
|
178
171
|
|
|
179
172
|
x, y, z = (fdot(r, *xyz) for r in self.matrix)
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
n, kwds = _name2__(name_Vector_kwds, _or_nameof=self)
|
|
174
|
+
return Vector3Tuple(x, y, z, name=n) if Vector is None else \
|
|
175
|
+
Vector(x, y, z, name=n, **kwds)
|
|
182
176
|
|
|
183
177
|
@property_doc_(' tilt/pitch/elevation from horizontal in C{degrees180}, negative down.')
|
|
184
178
|
def tilt(self):
|
|
@@ -214,7 +208,7 @@ class Attitude(_NamedBase):
|
|
|
214
208
|
def _r2d(r):
|
|
215
209
|
return fsumf_(_N_1_0, *r)
|
|
216
210
|
|
|
217
|
-
return Vector3d(*map(_r2d, self.matrix),
|
|
211
|
+
return Vector3d(*map(_r2d, self.matrix), name__=tyr3d)
|
|
218
212
|
|
|
219
213
|
@property_doc_(' yaw/bearing/heading in compass C{degrees360}, clockwise from North.')
|
|
220
214
|
def yaw(self):
|
|
@@ -247,12 +241,13 @@ class Frustum(_NamedBase):
|
|
|
247
241
|
_tan_h_2 = _0_0 # tan(_h_2)
|
|
248
242
|
_v_2 = _0_0 # half vfov in degrees
|
|
249
243
|
|
|
250
|
-
def __init__(self, hfov, vfov, ltp=None):
|
|
244
|
+
def __init__(self, hfov, vfov, ltp=None, **name):
|
|
251
245
|
'''New L{Frustum}.
|
|
252
246
|
|
|
253
247
|
@arg hfov: Horizontal field-of-view (C{degrees180}).
|
|
254
248
|
@arg vfov: Vertical field-of-view (C{degrees180}).
|
|
255
249
|
@kwarg ltp: Optional I{local tangent plane} (L{Ltp}).
|
|
250
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
256
251
|
|
|
257
252
|
@raise LocalError: Invalid B{C{hfov}} or B{C{vfov}}.
|
|
258
253
|
'''
|
|
@@ -263,8 +258,10 @@ class Frustum(_NamedBase):
|
|
|
263
258
|
|
|
264
259
|
if ltp:
|
|
265
260
|
self._ltp = _xLtp(ltp)
|
|
261
|
+
if name:
|
|
262
|
+
self.name # PYCHOK effect
|
|
266
263
|
|
|
267
|
-
def footprint5(self, alt_attitude, tilt=0, yaw=0, roll=0, z=_0_0, ltp=None): # MCCABE 15
|
|
264
|
+
def footprint5(self, alt_attitude, tilt=0, yaw=0, roll=0, z=_0_0, ltp=None, **name): # MCCABE 15
|
|
268
265
|
'''Compute the center and corners of the intersection with (or projection
|
|
269
266
|
to) the I{local tangent plane} (LTP).
|
|
270
267
|
|
|
@@ -280,6 +277,7 @@ class Frustum(_NamedBase):
|
|
|
280
277
|
@kwarg z: Optional height of the footprint (C{meter}) above I{local tangent plane}.
|
|
281
278
|
@kwarg ltp: The I{local tangent plane} (L{Ltp}), overriding this
|
|
282
279
|
frustum's C{ltp}.
|
|
280
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
283
281
|
|
|
284
282
|
@return: A L{Footprint5Tuple}C{(center, upperleft, upperight, loweright,
|
|
285
283
|
lowerleft)} with the C{center} and 4 corners, each an L{Xyz4Tuple}.
|
|
@@ -350,7 +348,7 @@ class Frustum(_NamedBase):
|
|
|
350
348
|
+ _xy2(a, e + v, -h, -t, r) # swapped
|
|
351
349
|
# turn center and corners by yaw, clockwise
|
|
352
350
|
p = self.ltp if ltp is None else ltp # None OK
|
|
353
|
-
return Footprint5Tuple(_xyz5(b, xy5, z, p)) # *_xyz5
|
|
351
|
+
return Footprint5Tuple(_xyz5(b, xy5, z, p), **name) # *_xyz5
|
|
354
352
|
|
|
355
353
|
@Property_RO
|
|
356
354
|
def hfov(self):
|
|
@@ -413,7 +411,7 @@ class LocalCartesian(_NamedBase):
|
|
|
413
411
|
_t0 = None # origin (..., lat0, lon0, height0, ...) L{Ecef9Tuple}
|
|
414
412
|
_9Tuple = Local9Tuple
|
|
415
413
|
|
|
416
|
-
def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None,
|
|
414
|
+
def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
|
|
417
415
|
'''New L{LocalCartesian} converter.
|
|
418
416
|
|
|
419
417
|
@kwarg latlonh0: The (geodetic) origin (C{LatLon}, L{LatLon4Tuple}, L{Ltp}
|
|
@@ -426,9 +424,10 @@ class LocalCartesian(_NamedBase):
|
|
|
426
424
|
surface and for C{scalar} B{C{latlonh0}}, ignored otherwise.
|
|
427
425
|
@kwarg ecef: An ECEF converter (L{EcefKarney} I{only}) for C{scalar}
|
|
428
426
|
B{C{latlonh0}}, ignored otherwise.
|
|
429
|
-
@kwarg
|
|
430
|
-
|
|
431
|
-
|
|
427
|
+
@kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
|
|
428
|
+
C{B{lon00}=B{lon0}} for the arbitrary I{polar} longitude
|
|
429
|
+
(C{degrees}), see method C{reverse} and property C{lon00}
|
|
430
|
+
for further details.
|
|
432
431
|
|
|
433
432
|
@raise LocalError: If B{C{latlonh0}} not C{LatLon}, L{LatLon4Tuple}, L{Ltp},
|
|
434
433
|
L{LocalCartesian} or L{Ecef9Tuple} or B{C{latlonh0}},
|
|
@@ -439,7 +438,7 @@ class LocalCartesian(_NamedBase):
|
|
|
439
438
|
@note: If BC{latlonh0} is an L{Ltp} or L{LocalCartesian}, only C{lat0}, C{lon0},
|
|
440
439
|
C{height0} and I{polar} C{lon00} are copied, I{not} the ECEF converter.
|
|
441
440
|
'''
|
|
442
|
-
self.reset(latlonh0, lon0=lon0, height0=height0, ecef=ecef,
|
|
441
|
+
self.reset(latlonh0, lon0=lon0, height0=height0, ecef=ecef, **lon00_name)
|
|
443
442
|
|
|
444
443
|
def __eq__(self, other):
|
|
445
444
|
'''Compare this and an other instance.
|
|
@@ -464,29 +463,33 @@ class LocalCartesian(_NamedBase):
|
|
|
464
463
|
'''
|
|
465
464
|
return self._ecef
|
|
466
465
|
|
|
467
|
-
def _ecef2local(self, ecef, Xyz,
|
|
466
|
+
def _ecef2local(self, ecef, Xyz, name_Xyz_kwds):
|
|
468
467
|
'''(INTERNAL) Convert geocentric/geodetic to local, like I{forward}.
|
|
469
468
|
|
|
470
469
|
@arg ecef: Geocentric (and geodetic) (L{Ecef9Tuple}).
|
|
471
470
|
@arg Xyz: An L{XyzLocal}, L{Enu} or L{Ned} I{class} or C{None}.
|
|
472
|
-
@arg
|
|
471
|
+
@arg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
472
|
+
additional B{C{Xyz}} keyword arguments, ignored if
|
|
473
|
+
C{B{Xyz} is None}.
|
|
473
474
|
|
|
474
|
-
@return: An C{B{Xyz}(x, y, z, ltp, **B{
|
|
475
|
-
C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
475
|
+
@return: An C{B{Xyz}(x, y, z, ltp, **B{name_Xyz_kwds}} instance or
|
|
476
|
+
if C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
476
477
|
height, ltp, ecef, M)} with this C{ltp}, B{C{ecef}}
|
|
477
478
|
(L{Ecef9Tuple}) converted to this C{datum} and C{M=None},
|
|
478
479
|
always.
|
|
480
|
+
|
|
481
|
+
@raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
|
|
479
482
|
'''
|
|
480
483
|
ltp = self
|
|
481
484
|
if ecef.datum != ltp.datum:
|
|
482
485
|
ecef = ecef.toDatum(ltp.datum)
|
|
483
|
-
|
|
486
|
+
n, kwds = _name2__(name_Xyz_kwds, _or_nameof=ecef)
|
|
487
|
+
x, y, z = self.M.rotate(ecef.xyz, *ltp._t0_xyz)
|
|
484
488
|
r = Local9Tuple(x, y, z, ecef.lat, ecef.lon, ecef.height,
|
|
485
|
-
ltp, ecef, None, name=
|
|
489
|
+
ltp, ecef, None, name=n)
|
|
486
490
|
if Xyz:
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
r = r.toXyz(Xyz=Xyz, **Xyz_kwds)
|
|
491
|
+
_xsubclassof(*_XyzLocals4, Xyz=Xyz) # Vector3d
|
|
492
|
+
r = r.toXyz(Xyz=Xyz, name=n, **kwds)
|
|
490
493
|
return r
|
|
491
494
|
|
|
492
495
|
@Property_RO
|
|
@@ -495,7 +498,7 @@ class LocalCartesian(_NamedBase):
|
|
|
495
498
|
'''
|
|
496
499
|
return self.ecef.datum.ellipsoid
|
|
497
500
|
|
|
498
|
-
def forward(self, latlonh, lon=None, height=0, M=False, name
|
|
501
|
+
def forward(self, latlonh, lon=None, height=0, M=False, **name):
|
|
499
502
|
'''Convert I{geodetic} C{(lat, lon, height)} to I{local} cartesian
|
|
500
503
|
C{(x, y, z)}.
|
|
501
504
|
|
|
@@ -507,7 +510,7 @@ class LocalCartesian(_NamedBase):
|
|
|
507
510
|
to and above (or below) the ellipsoid's surface.
|
|
508
511
|
@kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix},
|
|
509
512
|
iff available (C{bool}).
|
|
510
|
-
@kwarg name: Optional name (C{str}).
|
|
513
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
511
514
|
|
|
512
515
|
@return: A L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)}
|
|
513
516
|
with I{local} C{x}, C{y}, C{z}, I{geodetic} C{(lat}, C{lon},
|
|
@@ -521,7 +524,7 @@ class LocalCartesian(_NamedBase):
|
|
|
521
524
|
C{scalar} for C{scalar} B{C{latlonh}} or invalid
|
|
522
525
|
or if B{C{height}} invalid.
|
|
523
526
|
'''
|
|
524
|
-
lat, lon, h, n = _llhn4(latlonh, lon, height, Error=LocalError, name
|
|
527
|
+
lat, lon, h, n = _llhn4(latlonh, lon, height, Error=LocalError, **name)
|
|
525
528
|
t = self.ecef._forward(lat, lon, h, n, M=M)
|
|
526
529
|
x, y, z = self.M.rotate(t.xyz, *self._t0_xyz)
|
|
527
530
|
m = self.M.multiply(t.M) if M else None
|
|
@@ -549,7 +552,7 @@ class LocalCartesian(_NamedBase):
|
|
|
549
552
|
'''(INTERNAL) Convert I{local} to geocentric/geodetic, like I{.reverse}.
|
|
550
553
|
|
|
551
554
|
@arg local: Local (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer} or L{Local9Tuple}).
|
|
552
|
-
@kwarg nine:
|
|
555
|
+
@kwarg nine: If C{True}, return a 9-, otherwise a 3-tuple (C{bool}).
|
|
553
556
|
@kwarg M: Include the rotation matrix (C{bool}).
|
|
554
557
|
|
|
555
558
|
@return: A I{geocentric} 3-tuple C{(x, y, z)} or if C{B{nine}=True},
|
|
@@ -586,19 +589,21 @@ class LocalCartesian(_NamedBase):
|
|
|
586
589
|
'''
|
|
587
590
|
return self._t0.M
|
|
588
591
|
|
|
589
|
-
def reset(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None,
|
|
590
|
-
'''Reset this converter, see L{LocalCartesian.__init__}
|
|
592
|
+
def reset(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
|
|
593
|
+
'''Reset this converter, see L{LocalCartesian.__init__} for more details.
|
|
591
594
|
'''
|
|
595
|
+
_, name = _xkwds_pop2(lon00_name, lon00=None) # PYCHOK get **name
|
|
592
596
|
if isinstance(latlonh0, LocalCartesian):
|
|
593
597
|
if self._t0:
|
|
594
598
|
_update_all(self)
|
|
595
|
-
self._ecef =
|
|
596
|
-
self._lon00 =
|
|
597
|
-
self._t0 =
|
|
598
|
-
n = name
|
|
599
|
+
self._ecef = latlonh0.ecef
|
|
600
|
+
self._lon00 = latlonh0.lon00
|
|
601
|
+
self._t0 = latlonh0._t0
|
|
602
|
+
n = _name__(name, _or_nameof=latlonh0)
|
|
599
603
|
else:
|
|
604
|
+
n = _name__(name, _or_nameof=self)
|
|
600
605
|
lat0, lon0, height0, n = _llhn4(latlonh0, lon0, height0, suffix=_0_,
|
|
601
|
-
Error=LocalError, name=
|
|
606
|
+
Error=LocalError, name=n)
|
|
602
607
|
if ecef: # PYCHOK no cover
|
|
603
608
|
_xinstanceof(self._Ecef, ecef=ecef)
|
|
604
609
|
_update_all(self)
|
|
@@ -606,11 +611,11 @@ class LocalCartesian(_NamedBase):
|
|
|
606
611
|
elif self._t0:
|
|
607
612
|
_update_all(self)
|
|
608
613
|
self._t0 = self.ecef._forward(lat0, lon0, height0, n, M=True)
|
|
609
|
-
self.lon00 = _xattr(latlonh0, lon00=_xkwds_get(
|
|
614
|
+
self.lon00 = _xattr(latlonh0, lon00=_xkwds_get(lon00_name, lon00=lon0))
|
|
610
615
|
if n:
|
|
611
616
|
self.rename(n)
|
|
612
617
|
|
|
613
|
-
def reverse(self, xyz, y=None, z=None, M=False,
|
|
618
|
+
def reverse(self, xyz, y=None, z=None, M=False, **lon00_name):
|
|
614
619
|
'''Convert I{local} C{(x, y, z)} to I{geodetic} C{(lat, lon, height)}.
|
|
615
620
|
|
|
616
621
|
@arg xyz: A I{local} (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer}, L{Local9Tuple}) or
|
|
@@ -619,10 +624,12 @@ class LocalCartesian(_NamedBase):
|
|
|
619
624
|
@kwarg z: Local C{z} coordinate for C{scalar} B{C{xyz}} and B{C{y}} (C{meter}).
|
|
620
625
|
@kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix}, iff
|
|
621
626
|
available (C{bool}).
|
|
622
|
-
@kwarg
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
627
|
+
@kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
|
|
628
|
+
C{B{lon00}=B{lon0}} for the arbitrary I{polar} longitude
|
|
629
|
+
(C{degrees}), overriding see the property C{B{lon00}=B{lon0}}
|
|
630
|
+
value. The I{polar} longitude (C{degrees}) is returned with
|
|
631
|
+
I{polar} latitudes C{abs(B{lat0}) == 90} for local C{B{x}=0}
|
|
632
|
+
and C{B{y}=0} locations.
|
|
626
633
|
|
|
627
634
|
@return: An L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)} with
|
|
628
635
|
I{local} C{x}, C{y}, C{z}, I{geodetic} C{lat}, C{lon}, C{height},
|
|
@@ -633,9 +640,10 @@ class LocalCartesian(_NamedBase):
|
|
|
633
640
|
@raise LocalError: Invalid B{C{xyz}} or C{scalar} C{x} or B{C{y}} and/or B{C{z}}
|
|
634
641
|
not C{scalar} for C{scalar} B{C{xyz}}.
|
|
635
642
|
'''
|
|
643
|
+
lon00, name =_xkwds_pop2(lon00_name, lon00=self.lon00)
|
|
636
644
|
x, y, z, n = _xyzn4(xyz, y, z, _XyzLocals5, Error=LocalError, name=name)
|
|
637
645
|
c = self.M.unrotate((x, y, z), *self._t0_xyz)
|
|
638
|
-
t = self.ecef.reverse(*c, M=M, lon00=
|
|
646
|
+
t = self.ecef.reverse(*c, M=M, lon00=lon00)
|
|
639
647
|
m = self.M.multiply(t.M) if M else None
|
|
640
648
|
return self._9Tuple(x, y, z, t.lat, t.lon, t.height, self, t, m, name=n or self.name)
|
|
641
649
|
|
|
@@ -661,7 +669,7 @@ class Ltp(LocalCartesian):
|
|
|
661
669
|
'''
|
|
662
670
|
_Ecef = _EcefBase
|
|
663
671
|
|
|
664
|
-
def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None,
|
|
672
|
+
def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
|
|
665
673
|
'''New C{Ltp}, see L{LocalCartesian.__init__} for more details.
|
|
666
674
|
|
|
667
675
|
@kwarg ecef: Optional ECEF converter (L{EcefKarney}, L{EcefFarrell21},
|
|
@@ -669,10 +677,12 @@ class Ltp(LocalCartesian):
|
|
|
669
677
|
L{EcefYou} I{instance}), overriding the default
|
|
670
678
|
L{EcefKarney}C{(datum=Datums.WGS84)} for C{scalar}.
|
|
671
679
|
|
|
680
|
+
@see: Class L{LocalCartesian<LocalCartesian.__init__>} for further details.
|
|
681
|
+
|
|
672
682
|
@raise TypeError: Invalid B{C{ecef}}.
|
|
673
683
|
'''
|
|
674
684
|
LocalCartesian.reset(self, latlonh0, lon0=lon0, height0=height0,
|
|
675
|
-
ecef=ecef,
|
|
685
|
+
ecef=ecef, **lon00_name)
|
|
676
686
|
|
|
677
687
|
@Property
|
|
678
688
|
def ecef(self):
|
|
@@ -719,7 +729,7 @@ class _ChLV(object):
|
|
|
719
729
|
# assert _args_kwds_names(ChLVe.reverse)[1:4] == t
|
|
720
730
|
return t
|
|
721
731
|
|
|
722
|
-
def forward(self, latlonh, lon=None, height=0, M=None, name
|
|
732
|
+
def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
|
|
723
733
|
'''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
|
|
724
734
|
|
|
725
735
|
@arg latlonh: Either a C{LatLon}, L{Ltp} or C{scalar} (geodetic) latitude (C{degrees}).
|
|
@@ -728,7 +738,7 @@ class _ChLV(object):
|
|
|
728
738
|
(C{meter}) for C{scalar} B{C{latlonh}} and B{C{lon}}.
|
|
729
739
|
@kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
|
|
730
740
|
for C{ChLV} only, C{None} otherwise (C{bool}).
|
|
731
|
-
@kwarg name: Optional name (C{str}).
|
|
741
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
732
742
|
|
|
733
743
|
@return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
|
|
734
744
|
I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
|
|
@@ -738,7 +748,7 @@ class _ChLV(object):
|
|
|
738
748
|
|
|
739
749
|
@raise LocalError: Invalid or non-C{scalar} B{C{latlonh}}, B{C{lon}} or B{C{height}}.
|
|
740
750
|
'''
|
|
741
|
-
notOverloaded(self, latlonh, lon=lon, height=height, M=M, name
|
|
751
|
+
notOverloaded(self, latlonh, lon=lon, height=height, M=M, **name)
|
|
742
752
|
|
|
743
753
|
def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK no cover
|
|
744
754
|
'''Convert I{Swiss} projection to WGS84 geodetic coordinates.
|
|
@@ -750,7 +760,7 @@ class _ChLV(object):
|
|
|
750
760
|
@kwarg h_: I{Swiss h'} height for C{scalar} B{C{enh_}} and B{C{n}} (C{meter}).
|
|
751
761
|
@kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
|
|
752
762
|
for C{ChLV} only, C{None} otherwise (C{bool}).
|
|
753
|
-
@kwarg name: Optional name (C{str}).
|
|
763
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
754
764
|
|
|
755
765
|
@return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
|
|
756
766
|
I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
|
|
@@ -848,24 +858,24 @@ class ChLV(_ChLV, Ltp):
|
|
|
848
858
|
'''
|
|
849
859
|
Ltp.__init__(self, latlonh0, **_xkwds(other_Ltp_kwds, ecef=None, name=ChLV.Bern.name))
|
|
850
860
|
|
|
851
|
-
def forward(self, latlonh, lon=None, height=0, M=None, name
|
|
861
|
+
def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK unused M
|
|
852
862
|
# overloaded for the _ChLV.forward.__doc__
|
|
853
|
-
return Ltp.forward(self, latlonh, lon=lon, height=height, M=M, name
|
|
863
|
+
return Ltp.forward(self, latlonh, lon=lon, height=height, M=M, **name)
|
|
854
864
|
|
|
855
865
|
def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK signature
|
|
856
866
|
# overloaded for the _ChLV.reverse.__doc__
|
|
857
|
-
Y, X, h_,
|
|
858
|
-
return Ltp.reverse(self, Y, X, h_, M=M, name=
|
|
867
|
+
Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
|
|
868
|
+
return Ltp.reverse(self, Y, X, h_, M=M, name=n)
|
|
859
869
|
|
|
860
870
|
@staticmethod
|
|
861
|
-
def false2(Y, X, LV95=True, name
|
|
871
|
+
def false2(Y, X, LV95=True, **name):
|
|
862
872
|
'''Add the I{Swiss LV95} or I{LV03} falsing.
|
|
863
873
|
|
|
864
874
|
@arg Y: Unfalsed I{Swiss Y} easting (C{meter}).
|
|
865
875
|
@arg X: Unfalsed I{Swiss X} northing (C{meter}).
|
|
866
876
|
@kwarg LV95: If C{True} add C{LV95} falsing, if C{False} add
|
|
867
877
|
C{LV03} falsing, otherwise leave unfalsed.
|
|
868
|
-
@kwarg name: Optional name (C{str}).
|
|
878
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
869
879
|
|
|
870
880
|
@return: A L{ChLVEN2Tuple}C{(E_LV95, N_LV95)} or a
|
|
871
881
|
L{ChLVyx2Tuple}C{(y_LV03, x_LV03)} with falsed B{C{Y}}
|
|
@@ -873,7 +883,7 @@ class ChLV(_ChLV, Ltp):
|
|
|
873
883
|
with B{C{Y}} and B{C{X}} as-is.
|
|
874
884
|
'''
|
|
875
885
|
e, n = t = _ChLV._falsing2(LV95)
|
|
876
|
-
return t.classof(e + Y, n + X, name
|
|
886
|
+
return t.classof(e + Y, n + X, **name)
|
|
877
887
|
|
|
878
888
|
@staticmethod
|
|
879
889
|
def isLV03(e, n):
|
|
@@ -910,7 +920,7 @@ class ChLV(_ChLV, Ltp):
|
|
|
910
920
|
return None
|
|
911
921
|
|
|
912
922
|
@staticmethod
|
|
913
|
-
def unfalse2(e, n, LV95=None, name
|
|
923
|
+
def unfalse2(e, n, LV95=None, **name):
|
|
914
924
|
'''Remove the I{Swiss LV95} or I{LV03} falsing.
|
|
915
925
|
|
|
916
926
|
@arg e: Falsed I{Swiss E_LV95} or I{y_LV03} easting (C{meter}).
|
|
@@ -918,13 +928,13 @@ class ChLV(_ChLV, Ltp):
|
|
|
918
928
|
@kwarg LV95: If C{True} remove I{LV95} falsing, if C{False} remove
|
|
919
929
|
I{LV03} falsing, otherwise use method C{isLV95(B{e},
|
|
920
930
|
B{n})}.
|
|
921
|
-
@kwarg name: Optional name (C{str}).
|
|
931
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
922
932
|
|
|
923
933
|
@return: A L{ChLVYX2Tuple}C{(Y, X)} with the unfalsed B{C{e}}
|
|
924
934
|
respectively B{C{n}}.
|
|
925
935
|
'''
|
|
926
936
|
Y, X = _ChLV._falsing2(ChLV.isLV95(e, n) if LV95 is None else LV95)
|
|
927
|
-
return ChLVYX2Tuple(e - Y, n - X, name
|
|
937
|
+
return ChLVYX2Tuple(e - Y, n - X, **name)
|
|
928
938
|
|
|
929
939
|
|
|
930
940
|
class ChLVa(_ChLV, LocalCartesian):
|
|
@@ -937,15 +947,15 @@ class ChLVa(_ChLV, LocalCartesian):
|
|
|
937
947
|
def __init__(self, name=ChLV.Bern.name):
|
|
938
948
|
'''New I{Approximate WGS84-Swiss} L{ChLVa} converter, centered at I{Bern, Ch}.
|
|
939
949
|
|
|
940
|
-
@kwarg name: Optional name (C{str})
|
|
950
|
+
@kwarg name: Optional C{B{name}=Bern.name} (C{str}).
|
|
941
951
|
'''
|
|
942
952
|
LocalCartesian.__init__(self, latlonh0=ChLV.Bern, name=name)
|
|
943
953
|
|
|
944
|
-
def forward(self, latlonh, lon=None, height=0, M=None, name
|
|
954
|
+
def forward(self, latlonh, lon=None, height=0, M=None, **name):
|
|
945
955
|
# overloaded for the _ChLV.forward.__doc__
|
|
946
|
-
lat, lon, h,
|
|
947
|
-
a, b, h_
|
|
948
|
-
a2, b2
|
|
956
|
+
lat, lon, h, n = _llhn4(latlonh, lon, height, **name)
|
|
957
|
+
a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
|
|
958
|
+
a2, b2 = a**2, b**2
|
|
949
959
|
|
|
950
960
|
Y = fsumf_( 72.37, 211455.93 * b,
|
|
951
961
|
-10938.51 * b * a,
|
|
@@ -956,13 +966,13 @@ class ChLVa(_ChLV, LocalCartesian):
|
|
|
956
966
|
76.63 * a2,
|
|
957
967
|
-194.56 * b2 * a,
|
|
958
968
|
119.79 * a2 * a) # + 200_000
|
|
959
|
-
return self._ChLV9Tuple(True, M,
|
|
969
|
+
return self._ChLV9Tuple(True, M, n, Y, X, h_, lat, lon, h)
|
|
960
970
|
|
|
961
971
|
def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK signature
|
|
962
972
|
# overloaded for the _ChLV.reverse.__doc__
|
|
963
|
-
Y, X, h_,
|
|
964
|
-
a, b, h =
|
|
965
|
-
ab_d, a2, b2 =
|
|
973
|
+
Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
|
|
974
|
+
a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
|
|
975
|
+
ab_d, a2, b2 = ChLV._ab_d, a**2, b**2
|
|
966
976
|
|
|
967
977
|
lat = _Fsumf_(16.9023892, 3.238272 * b,
|
|
968
978
|
-0.270978 * a2,
|
|
@@ -973,7 +983,7 @@ class ChLVa(_ChLV, LocalCartesian):
|
|
|
973
983
|
0.791484 * a * b,
|
|
974
984
|
0.1306 * a * b2,
|
|
975
985
|
-0.0436 * a * a2).fover(ab_d)
|
|
976
|
-
return self._ChLV9Tuple(False, M,
|
|
986
|
+
return self._ChLV9Tuple(False, M, n, Y, X, h_, lat, lon, h)
|
|
977
987
|
|
|
978
988
|
|
|
979
989
|
class ChLVe(_ChLV, LocalCartesian):
|
|
@@ -995,15 +1005,15 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
995
1005
|
def __init__(self, name=ChLV.Bern.name):
|
|
996
1006
|
'''New I{Approximate WGS84-Swiss} L{ChLVe} converter, centered at I{Bern, Ch}.
|
|
997
1007
|
|
|
998
|
-
@kwarg name: Optional name (C{str})
|
|
1008
|
+
@kwarg name: Optional C{B{name}=Bern.name} (C{str}).
|
|
999
1009
|
'''
|
|
1000
1010
|
LocalCartesian.__init__(self, latlonh0=ChLV.Bern, name=name)
|
|
1001
1011
|
|
|
1002
|
-
def forward(self, latlonh, lon=None, height=0, M=None,
|
|
1012
|
+
def forward(self, latlonh, lon=None, height=0, M=None, gamma=False, **name): # PYCHOK gamma
|
|
1003
1013
|
# overloaded for the _ChLV.forward.__doc__
|
|
1004
|
-
lat, lon, h,
|
|
1005
|
-
a, b, h_
|
|
1006
|
-
ab_M, z, _H
|
|
1014
|
+
lat, lon, h, n = _llhn4(latlonh, lon, height, **name)
|
|
1015
|
+
a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
|
|
1016
|
+
ab_M, z, _H = ChLV._ab_M, 0, Fhorner
|
|
1007
1017
|
|
|
1008
1018
|
B1 = _H(a, 211428.533991, -10939.608605, -2.658213, -8.539078, -0.00345, -0.007992)
|
|
1009
1019
|
B3 = _H(a, -44.232717, 4.291740, -0.309883, 0.013924)
|
|
@@ -1016,7 +1026,7 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1016
1026
|
B6 = 0.000488
|
|
1017
1027
|
X = _H(b, B0, z, B2, z, B4, z, B6).fover(ab_M) # 1,000 Km!
|
|
1018
1028
|
|
|
1019
|
-
t = self._ChLV9Tuple(True, M,
|
|
1029
|
+
t = self._ChLV9Tuple(True, M, n, Y, X, h_, lat, lon, h)
|
|
1020
1030
|
if gamma:
|
|
1021
1031
|
U1 = _H(a, 2255515.207166, 2642.456961, 1.284180, 2.577486, 0.001165)
|
|
1022
1032
|
U3 = _H(a, -412.991934, 64.106344, -2.679566, 0.123833)
|
|
@@ -1025,11 +1035,11 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1025
1035
|
t = t, g
|
|
1026
1036
|
return t
|
|
1027
1037
|
|
|
1028
|
-
def reverse(self, enh_, n=None, h_=0, M=None,
|
|
1038
|
+
def reverse(self, enh_, n=None, h_=0, M=None, gamma=False, **name): # PYCHOK gamma
|
|
1029
1039
|
# overloaded for the _ChLV.reverse.__doc__
|
|
1030
|
-
Y, X, h_,
|
|
1031
|
-
a, b, h
|
|
1032
|
-
s_d, _H, z
|
|
1040
|
+
Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
|
|
1041
|
+
a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
|
|
1042
|
+
s_d, _H, z = ChLV._s_d, Fhorner, 0
|
|
1033
1043
|
|
|
1034
1044
|
A0 = _H(b, ChLV._sLat, 32386.4877666, -25.486822, -132.457771, 0.48747, 0.81305, -0.0069)
|
|
1035
1045
|
A2 = _H(b, -2713.537919, -450.442705, -75.53194, -14.63049, -2.7604)
|
|
@@ -1043,7 +1053,7 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1043
1053
|
lon = _H(a, ChLV._sLon, A1, z, A3, z, A5).fover(s_d)
|
|
1044
1054
|
# == (ChLV._sLon + a * (A1 + a**2 * (A3 + a**2 * A5))) / s_d
|
|
1045
1055
|
|
|
1046
|
-
t = self._ChLV9Tuple(False, M,
|
|
1056
|
+
t = self._ChLV9Tuple(False, M, n, Y, X, h_, lat, lon, h)
|
|
1047
1057
|
if gamma:
|
|
1048
1058
|
U1 = _H(b, 106679.792202, 17876.57022, 4306.5241, 794.87772, 148.1545, 27.8725)
|
|
1049
1059
|
U3 = _H(b, -1435.508, -794.8777, -296.309, -92.908)
|
|
@@ -1053,8 +1063,17 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1053
1063
|
return t
|
|
1054
1064
|
|
|
1055
1065
|
|
|
1056
|
-
def
|
|
1057
|
-
|
|
1066
|
+
def _fov_2(**fov):
|
|
1067
|
+
# Half a field-of-view angle in C{degrees}.
|
|
1068
|
+
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
1069
|
+
if EPS < f < _90_0:
|
|
1070
|
+
return f
|
|
1071
|
+
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
1072
|
+
raise LocalError(txt=t, **fov)
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
|
|
1076
|
+
'''Convert an attitude pose into a (3-D) direction vector.
|
|
1058
1077
|
|
|
1059
1078
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees}), negative down
|
|
1060
1079
|
(clockwise rotation along and around the x-axis).
|
|
@@ -1062,17 +1081,28 @@ def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **Vector_kwds):
|
|
|
1062
1081
|
(counter-clockwise rotation along and around the z-axis).
|
|
1063
1082
|
@kwarg roll: Roll, bank (C{degrees}), positive to the right and down
|
|
1064
1083
|
(clockwise rotation along and around the y-axis).
|
|
1084
|
+
@kwarg Vector: Class to return the direction vector (C{Cartesian},
|
|
1085
|
+
L{Vector3d} or C{Vector3Tuple}) or C{None}.
|
|
1086
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
1087
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
1088
|
+
C{B{Vector} is None}.
|
|
1065
1089
|
|
|
1066
1090
|
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
1067
1091
|
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
1068
1092
|
|
|
1093
|
+
@raise AttitudeError: Invalid B{C{tilt}}, B{C{yaw}} or B{C{roll}}.
|
|
1094
|
+
|
|
1095
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
1096
|
+
|
|
1069
1097
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}
|
|
1070
|
-
and function L{pygeodesy.hartzell} argument C{los}.
|
|
1098
|
+
and function L{pygeodesy.hartzell} argument C{los}, Line-Of-Sight.
|
|
1071
1099
|
'''
|
|
1072
1100
|
d = Attitude4Tuple(_0_0, tilt, yaw, roll).tyr3d
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1101
|
+
if Vector is not type(d):
|
|
1102
|
+
n, kwds = _name2__(name_Vector_kwds, name__=tyr3d)
|
|
1103
|
+
d = Vector3Tuple(d.x, d.y, d.z, name=n) if Vector is None else \
|
|
1104
|
+
Vector(d.x, d.y, d.z, name=n, **kwds)
|
|
1105
|
+
return d
|
|
1076
1106
|
|
|
1077
1107
|
|
|
1078
1108
|
def _xLtp(ltp, *dflt):
|