pygeodesy 24.10.24__py2.py3-none-any.whl → 24.12.12__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.
Files changed (118) hide show
  1. {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/METADATA +6 -6
  2. PyGeodesy-24.12.12.dist-info/RECORD +118 -0
  3. {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/WHEEL +1 -1
  4. pygeodesy/__init__.py +5 -5
  5. pygeodesy/__main__.py +1 -1
  6. pygeodesy/albers.py +5 -5
  7. pygeodesy/auxilats/_CX_4.py +1 -1
  8. pygeodesy/auxilats/_CX_6.py +1 -1
  9. pygeodesy/auxilats/_CX_8.py +1 -1
  10. pygeodesy/auxilats/_CX_Rs.py +1 -1
  11. pygeodesy/auxilats/__init__.py +1 -1
  12. pygeodesy/auxilats/__main__.py +1 -1
  13. pygeodesy/auxilats/auxAngle.py +5 -5
  14. pygeodesy/auxilats/auxDLat.py +6 -6
  15. pygeodesy/auxilats/auxDST.py +2 -2
  16. pygeodesy/auxilats/auxLat.py +5 -5
  17. pygeodesy/auxilats/auxily.py +2 -2
  18. pygeodesy/azimuthal.py +55 -65
  19. pygeodesy/basics.py +35 -34
  20. pygeodesy/booleans.py +37 -37
  21. pygeodesy/cartesianBase.py +26 -65
  22. pygeodesy/clipy.py +1 -1
  23. pygeodesy/constants.py +7 -7
  24. pygeodesy/css.py +8 -9
  25. pygeodesy/datums.py +1 -1
  26. pygeodesy/deprecated/__init__.py +2 -2
  27. pygeodesy/deprecated/bases.py +1 -1
  28. pygeodesy/deprecated/classes.py +10 -10
  29. pygeodesy/deprecated/consterns.py +1 -1
  30. pygeodesy/deprecated/datum.py +1 -1
  31. pygeodesy/deprecated/functions.py +23 -13
  32. pygeodesy/deprecated/nvector.py +1 -1
  33. pygeodesy/deprecated/rhumbBase.py +1 -1
  34. pygeodesy/deprecated/rhumbaux.py +1 -1
  35. pygeodesy/deprecated/rhumbsolve.py +1 -1
  36. pygeodesy/deprecated/rhumbx.py +1 -1
  37. pygeodesy/dms.py +1 -1
  38. pygeodesy/ecef.py +63 -69
  39. pygeodesy/elevations.py +1 -1
  40. pygeodesy/ellipsoidalBase.py +106 -121
  41. pygeodesy/ellipsoidalBaseDI.py +115 -119
  42. pygeodesy/ellipsoidalExact.py +36 -38
  43. pygeodesy/ellipsoidalGeodSolve.py +1 -1
  44. pygeodesy/ellipsoidalKarney.py +1 -1
  45. pygeodesy/ellipsoidalNvector.py +1 -1
  46. pygeodesy/ellipsoidalVincenty.py +6 -5
  47. pygeodesy/ellipsoids.py +7 -8
  48. pygeodesy/elliptic.py +6 -6
  49. pygeodesy/epsg.py +1 -1
  50. pygeodesy/errors.py +25 -25
  51. pygeodesy/etm.py +84 -76
  52. pygeodesy/fmath.py +54 -51
  53. pygeodesy/formy.py +74 -106
  54. pygeodesy/frechet.py +1 -1
  55. pygeodesy/fstats.py +1 -1
  56. pygeodesy/fsums.py +82 -72
  57. pygeodesy/gars.py +1 -1
  58. pygeodesy/geodesici.py +4 -4
  59. pygeodesy/geodesicw.py +16 -15
  60. pygeodesy/geodesicx/_C4_24.py +2 -2
  61. pygeodesy/geodesicx/_C4_27.py +2 -2
  62. pygeodesy/geodesicx/_C4_30.py +2 -2
  63. pygeodesy/geodesicx/__init__.py +3 -3
  64. pygeodesy/geodesicx/__main__.py +1 -1
  65. pygeodesy/geodesicx/gx.py +6 -5
  66. pygeodesy/geodesicx/gxarea.py +2 -2
  67. pygeodesy/geodesicx/gxbases.py +2 -2
  68. pygeodesy/geodesicx/gxline.py +16 -12
  69. pygeodesy/geodsolve.py +8 -17
  70. pygeodesy/geohash.py +1 -1
  71. pygeodesy/geoids.py +6 -6
  72. pygeodesy/hausdorff.py +1 -1
  73. pygeodesy/heights.py +3 -3
  74. pygeodesy/internals.py +64 -80
  75. pygeodesy/interns.py +2 -3
  76. pygeodesy/iters.py +1 -1
  77. pygeodesy/karney.py +4 -4
  78. pygeodesy/ktm.py +20 -21
  79. pygeodesy/latlonBase.py +296 -346
  80. pygeodesy/lazily.py +15 -15
  81. pygeodesy/lcc.py +5 -5
  82. pygeodesy/ltp.py +55 -59
  83. pygeodesy/ltpTuples.py +208 -192
  84. pygeodesy/mgrs.py +9 -10
  85. pygeodesy/named.py +153 -3
  86. pygeodesy/namedTuples.py +58 -7
  87. pygeodesy/nvectorBase.py +122 -105
  88. pygeodesy/osgr.py +10 -13
  89. pygeodesy/points.py +1 -1
  90. pygeodesy/props.py +3 -3
  91. pygeodesy/resections.py +26 -26
  92. pygeodesy/rhumb/__init__.py +2 -2
  93. pygeodesy/rhumb/aux_.py +2 -2
  94. pygeodesy/rhumb/bases.py +2 -2
  95. pygeodesy/rhumb/ekx.py +4 -4
  96. pygeodesy/rhumb/solve.py +4 -4
  97. pygeodesy/simplify.py +291 -403
  98. pygeodesy/solveBase.py +1 -1
  99. pygeodesy/sphericalBase.py +1 -1
  100. pygeodesy/sphericalNvector.py +84 -127
  101. pygeodesy/sphericalTrigonometry.py +66 -71
  102. pygeodesy/streprs.py +10 -5
  103. pygeodesy/trf.py +1 -1
  104. pygeodesy/triaxials.py +23 -16
  105. pygeodesy/units.py +17 -17
  106. pygeodesy/unitsBase.py +1 -1
  107. pygeodesy/ups.py +4 -4
  108. pygeodesy/utily.py +202 -145
  109. pygeodesy/utm.py +10 -10
  110. pygeodesy/utmups.py +1 -1
  111. pygeodesy/utmupsBase.py +1 -1
  112. pygeodesy/vector2d.py +17 -17
  113. pygeodesy/vector3d.py +32 -23
  114. pygeodesy/vector3dBase.py +22 -19
  115. pygeodesy/webmercator.py +5 -5
  116. pygeodesy/wgrs.py +5 -5
  117. PyGeodesy-24.10.24.dist-info/RECORD +0 -118
  118. {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/top_level.txt +0 -0
pygeodesy/ltpTuples.py CHANGED
@@ -16,12 +16,13 @@ from pygeodesy.constants import _0_0, _1_0, _90_0, _N_90_0
16
16
  # from pygeodesy.dms import F_D, toDMS # _MODS
17
17
  from pygeodesy.errors import _TypeError, _TypesError, _xattr, _xkwds, \
18
18
  _xkwds_item2
19
- from pygeodesy.fmath import hypot, hypot_
19
+ from pygeodesy.fmath import fdot_, hypot, hypot_
20
20
  from pygeodesy.interns import NN, _4_, _azimuth_, _center_, _COMMASPACE_, \
21
21
  _ecef_, _elevation_, _height_, _lat_, _lon_, \
22
22
  _ltp_, _M_, _name_, _up_, _X_, _x_, _xyz_, \
23
23
  _Y_, _y_, _z_
24
24
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
25
+ # from pygeodesy.ltp import Attitude, ChLV, ChLVa, ChLVe, _xLtp # _MODS
25
26
  from pygeodesy.named import _name__, _name1__, _name2__, _NamedBase, \
26
27
  _NamedTuple, _Pass, _xnamed
27
28
  from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
@@ -36,7 +37,7 @@ from pygeodesy.vector3d import Vector3d
36
37
  # from math import cos, radians # from .utily
37
38
 
38
39
  __all__ = _ALL_LAZY.ltpTuples
39
- __version__ = '24.08.18'
40
+ __version__ = '24.12.06'
40
41
 
41
42
  _aer_ = 'aer'
42
43
  _alt_ = 'alt'
@@ -44,7 +45,6 @@ _down_ = 'down'
44
45
  _east_ = 'east'
45
46
  _enu_ = 'enu'
46
47
  _h__ = 'h_'
47
- _ltp = _MODS.into(ltp=__name__)
48
48
  _ned_ = 'ned'
49
49
  _north_ = 'north'
50
50
  _local_ = 'local'
@@ -55,62 +55,6 @@ _uvw_ = 'uvw'
55
55
  _yaw_ = 'yaw'
56
56
 
57
57
 
58
- def _er2gr(e, r):
59
- '''(INTERNAL) Elevation and slant range to ground range.
60
- '''
61
- c = cos(radians(e))
62
- return Meter_(groundrange=r * c)
63
-
64
-
65
- def _init(inst, abc, ltp, name):
66
- '''(INTERNAL) Complete C{__init__}.
67
- '''
68
- if abc is None:
69
- n = _name__(**name)
70
- else:
71
- n = abc._name__(name)
72
- ltp = _xattr(abc, ltp=ltp)
73
- if ltp:
74
- inst._ltp = _ltp._xLtp(ltp)
75
- if n:
76
- inst.name = n
77
-
78
-
79
- def _toStr2(inst, prec=None, fmt=Fmt.SQUARE, sep=_COMMASPACE_):
80
- '''(INTERNAL) Get attribute name and value strings, joined and bracketed.
81
- '''
82
- a = inst._toStr # 'aer', 'enu', 'ned', 'xyz'
83
- t = getattr(inst, a + _4_, ())[:len(a)] or getattr(inst, a)
84
- t = strs(t, prec=3 if prec is None else prec)
85
- if sep:
86
- t = sep.join(t)
87
- if fmt:
88
- t = fmt(t)
89
- return a, t
90
-
91
-
92
- def _xyz2aer4(inst):
93
- '''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
94
- '''
95
- x, y, z, _ = inst.xyz4
96
- A = Azimuth(atan2b(x, y))
97
- E = Degrees(elevation=atan2d(z, hypot(x, y)))
98
- R = Meter(slantrange=hypot_(x, y, z))
99
- return Aer4Tuple(A, E, R, inst.ltp, name=inst.name)
100
-
101
-
102
- def _xyzLocal(*Types, **name_inst):
103
- '''(INTERNAL) Get C{inst} or C{inst.xyzLocal}.
104
- '''
105
- n, inst = _xkwds_item2(name_inst)
106
- if isinstance(inst, Types):
107
- return None
108
- try:
109
- return inst.xyzLocal
110
- except (AttributeError, TypeError):
111
- raise _TypeError(n, inst, txt_not_=_local_)
112
-
113
-
114
58
  class _AbcBase(_NamedBase):
115
59
  '''(INTERNAL) Base class for classes C{Aer} and C{Ned}.
116
60
  '''
@@ -126,12 +70,12 @@ class _AbcBase(_NamedBase):
126
70
  '''Get the I{local} I{Azimuth, Elevation, slant Range} (AER) components.
127
71
 
128
72
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
129
- @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optional,
130
- additional B{L{Aer}} keyword arguments, ignored if
131
- C{B{Aer} is None}.
73
+ @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
74
+ additional B{L{Aer}} keyword arguments, ignored if C{B{Aer}
75
+ is None}.
132
76
 
133
- @return: AER as an L{Aer} instance or if C{B{Aer} is None}, an
134
- L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
77
+ @return: An B{C{Aer}} instance or an L{Aer4Tuple}C{(azimuth, elevation,
78
+ slantrange, ltp)} if C{B{Aer} is None}.
135
79
 
136
80
  @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}}.
137
81
  '''
@@ -141,12 +85,12 @@ class _AbcBase(_NamedBase):
141
85
  '''Get the I{local} I{East, North, Up} (ENU) components.
142
86
 
143
87
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
144
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optional,
145
- additional B{L{Enu}} keyword arguments, ignored if
146
- C{B{Enu} is None}.
88
+ @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
89
+ additional B{L{Enu}} keyword arguments, ignored if C{B{Enu}
90
+ is None}.
147
91
 
148
- @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
149
- L{Enu4Tuple}C{(east, north, up, ltp)}.
92
+ @return: An B{C{Enu}} instance or an L{Enu4Tuple}C{(east, north, up,
93
+ ltp)} if C{B{Enu} is None}.
150
94
 
151
95
  @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}}.
152
96
  '''
@@ -156,12 +100,12 @@ class _AbcBase(_NamedBase):
156
100
  '''Get the I{local} I{North, East, Down} (NED) components.
157
101
 
158
102
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
159
- @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optional,
160
- additional B{L{Ned}} keyword arguments, ignored if
161
- C{B{Ned} is None}.
103
+ @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
104
+ additional B{L{Ned}} keyword arguments, ignored if C{B{Ned}
105
+ is None}.
162
106
 
163
- @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
164
- L{Ned4Tuple}C{(north, east, down, ltp)}.
107
+ @return: An B{C{Ned}} instance or an L{Ned4Tuple}C{(north, east, down,
108
+ ltp)} if C{B{Ned} is None}.
165
109
 
166
110
  @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}}.
167
111
  '''
@@ -172,12 +116,12 @@ class _AbcBase(_NamedBase):
172
116
 
173
117
  @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer})
174
118
  or C{None}.
175
- @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
176
- additional B{C{Xyz}} keyword arguments, ignored if
177
- C{B{Xyz} is None}.
119
+ @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
120
+ additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
121
+ is None}.
178
122
 
179
- @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None}, an
180
- L{Xyz4Tuple}C{(x, y, z, ltp)}.
123
+ @return: An B{C{Xyz}} instance or an L{Xyz4Tuple}C{(x, y, z, ltp)} if
124
+ C{B{Xyz} is None}.
181
125
 
182
126
  @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
183
127
  '''
@@ -439,7 +383,7 @@ class Attitude4Tuple(_NamedTuple):
439
383
  def tyr3d(self):
440
384
  '''Get this attitude's (3-D) directional vector (L{Vector3d}).
441
385
  '''
442
- return _ltp.Attitude(self).tyr3d
386
+ return _MODS.ltp.Attitude(self).tyr3d
443
387
 
444
388
 
445
389
  class Ned(_AbcBase):
@@ -787,7 +731,7 @@ class XyzLocal(_Vector3d):
787
731
  def _ltp_kwds_name3(self, ltp, kwds):
788
732
  '''(INTERNAL) Helper for methods C{toCartesian} and C{toLatLon}.
789
733
  '''
790
- ltp = _ltp._xLtp(ltp, self.ltp)
734
+ ltp = _xLtp(ltp, self.ltp)
791
735
  kwds = _name1__(kwds, _or_nameof=self)
792
736
  kwds = _name1__(kwds, _or_nameof=ltp)
793
737
  return ltp, kwds, kwds.get(_name_, NN)
@@ -814,40 +758,40 @@ class XyzLocal(_Vector3d):
814
758
  '''Get the local I{Azimuth, Elevation, slant Range} components.
815
759
 
816
760
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
817
- @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and
818
- optional, additional B{C{Aer}} keyword arguments,
819
- ignored if C{B{Aer} is None}.
761
+ @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
762
+ additional B{C{Aer}} keyword arguments, ignored if C{B{Aer}
763
+ is None}.
820
764
 
821
- @return: AER as an L{Aer} instance or if C{B{Aer} is None}, an
822
- L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
765
+ @return: An B{C{Aer}} instance or an L{Aer4Tuple}C{(azimuth, elevation,
766
+ slantrange, ltp)} if C{B{Aer} is None}.
823
767
 
824
- @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}}.
768
+ @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}} item.
825
769
  '''
826
770
  return self.aer4._toAer(Aer, name_Aer_kwds)
827
771
 
828
- def toCartesian(self, Cartesian=None, ltp=None, **name_Cartesian_kwds):
772
+ def toCartesian(self, Cartesian=None, ltp=None, **name_Cartesian_kwds): # PYCHOK signature
829
773
  '''Get the geocentric C{(x, y, z)} (ECEF) coordinates of this local.
830
774
 
831
775
  @kwarg Cartesian: Optional class to return C{(x, y, z)} (C{Cartesian})
832
776
  or C{None}.
833
777
  @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}), overriding
834
778
  this C{ltp}.
835
- @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optional,
779
+ @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
836
780
  additional B{C{Cartesian}} keyword arguments, ignored if
837
781
  C{B{Cartesian} is None}.
838
782
 
839
- @return: A B{C{Cartesian}} instance of if C{B{Cartesian} is None}, an
783
+ @return: A B{C{Cartesian}} instance or if C{B{Cartesian} is None}, an
840
784
  L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
841
785
  C{M=None}, always.
842
786
 
843
- @raise TypeError: Invalid B{C{ltp}}, B{C{Cartesian}} or B{C{name_Cartesian_kwds}}.
787
+ @raise TypeError: Invalid B{C{ltp}}, B{C{Cartesian}} or B{C{name_Cartesian_kwds}} item.
844
788
  '''
845
789
  ltp, kwds, n = self._ltp_kwds_name3(ltp, name_Cartesian_kwds)
846
790
  if Cartesian is None:
847
791
  t = ltp._local2ecef(self, nine=True)
848
792
  r = _xnamed(t, n) if n else t
849
793
  else:
850
- kwds = _xkwds(kwds, datum=ltp.datum)
794
+ kwds = _xkwds(kwds, datum=ltp.datum, name=n)
851
795
  xyz = ltp._local2ecef(self) # [:3]
852
796
  r = Cartesian(*xyz, **kwds)
853
797
  return r
@@ -856,14 +800,14 @@ class XyzLocal(_Vector3d):
856
800
  '''Get the local I{East, North, Up} (ENU) components.
857
801
 
858
802
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
859
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optional,
860
- additional B{C{Enu}} keyword arguments, ignored if
861
- C{B{Enu} is None}.
803
+ @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
804
+ additional B{C{Enu}} keyword arguments, ignored if C{B{Enu}
805
+ is None}.
862
806
 
863
- @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
864
- L{Enu4Tuple}C{(east, north, up, ltp)}.
807
+ @return: An B{C{Enu}} instance or an L{Enu4Tuple}C{(east, north, up,
808
+ ltp)} if C{B{Enu} is None}.
865
809
 
866
- @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}}.
810
+ @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}} item.
867
811
  '''
868
812
  return self.enu4._toEnu(Enu, name_Enu_kwds)
869
813
 
@@ -874,15 +818,14 @@ class XyzLocal(_Vector3d):
874
818
  C{None}.
875
819
  @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}), overriding
876
820
  this ENU/NED/AER/XYZ's LTP.
877
- @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optional,
878
- additional B{C{LatLon}} keyword arguments, ignored if
879
- C{B{LatLon} is None}.
821
+ @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
822
+ additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon}
823
+ is None}.
880
824
 
881
- @return: An B{C{LatLon}} instance of if C{B{LatLon} is None}, an
882
- L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
883
- C{M=None}, always.
825
+ @return: An B{C{LatLon}} instance or an L{Ecef9Tuple}C{(x, y, z, lat, lon,
826
+ height, C, M, datum)} if C{B{LatLon} is None}, with C{M=None}.
884
827
 
885
- @raise TypeError: Invalid B{C{LatLon}}, B{C{ltp}} or B{C{name_LatLon_kwds}}.
828
+ @raise TypeError: Invalid B{C{LatLon}}, B{C{ltp}} or B{C{name_LatLon_kwds}} item.
886
829
  '''
887
830
  ltp, kwds, n = self._ltp_kwds_name3(ltp, name_LatLon_kwds)
888
831
  t = ltp._local2ecef(self, nine=True)
@@ -913,14 +856,14 @@ class XyzLocal(_Vector3d):
913
856
  '''Get the local I{North, East, Down} (Ned) components.
914
857
 
915
858
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
916
- @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optional,
917
- additional B{C{Ned}} keyword arguments, ignored if
918
- C{B{Ned} is None}.
859
+ @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
860
+ additional B{C{Ned}} keyword arguments, ignored if C{B{Ned}
861
+ is None}.
919
862
 
920
- @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
921
- L{Ned4Tuple}C{(north, east, down, ltp)}.
863
+ @return: An B{C{Ned}} instance or an L{Ned4Tuple}C{(north, east, down,
864
+ ltp)} if C{B{Ned} is None}.
922
865
 
923
- @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}}.
866
+ @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}} item.
924
867
  '''
925
868
  return self.ned4._toNed(Ned, name_Ned_kwds)
926
869
 
@@ -929,14 +872,14 @@ class XyzLocal(_Vector3d):
929
872
 
930
873
  @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer})
931
874
  or C{None}.
932
- @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
933
- additional B{C{Xyz}} keyword arguments, ignored if
934
- C{B{Xyz} is None}.
875
+ @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
876
+ additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
877
+ is None}.
935
878
 
936
- @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None}, an
937
- L{Xyz4Tuple}C{(x, y, z, ltp)}.
879
+ @return: An B{C{Xyz}} instance or an L{Xyz4Tuple}C{(x, y, z, ltp)} if
880
+ C{B{Xyz} is None}.
938
881
 
939
- @raise TypeError: Invalid B{C{Xyz}} or B{C{name_EXyz_kwds}}.
882
+ @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}} item.
940
883
  '''
941
884
  return self.xyz4._toXyz(Xyz, name_Xyz_kwds)
942
885
 
@@ -1042,14 +985,14 @@ class Enu(XyzLocal):
1042
985
  @arg location: The geodetic (C{LatLon}) or geocentric (C{Cartesian},
1043
986
  L{Vector3d}) location, like a Point-Of-View.
1044
987
  @kwarg Uvw: Class to return UWV (L{Uvw}) or C{None}.
1045
- @kwarg name_Uvw_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1046
- additional B{L{Uvw}} keyword arguments, ignored if
1047
- C{B{Uvw} is None}.
988
+ @kwarg name_Uvw_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
989
+ additional B{L{Uvw}} keyword arguments, ignored if C{B{Uvw}
990
+ is None}.
1048
991
 
1049
- @return: UVW as a L{Uvw} instance or if C{B{Uvw} is None}, a
1050
- L{Uvw3Tuple}C{(u, v, w)}.
992
+ @return: A B{C{Uvw}} instance or a L{Uvw3Tuple}C{(u, v, w)} if C{B{Uvw}
993
+ is None}.
1051
994
 
1052
- @raise TypeError: Invalid B{C{location}} or B{C{name_Uvw_kwds}}.
995
+ @raise TypeError: Invalid B{C{location}} or B{C{name_Uvw_kwds}} item.
1053
996
 
1054
997
  @see: Function U{lookAtSpheroid<https://PyPI.org/project/pymap3d>}.
1055
998
  '''
@@ -1059,10 +1002,10 @@ class Enu(XyzLocal):
1059
1002
  raise _TypeError(location=location, cause=x)
1060
1003
  e, n, u, _ = self.enu4
1061
1004
 
1062
- t = ca * u - sa * n
1063
- U = cb * t - sb * e
1064
- V = cb * e + sb * t
1065
- W = ca * n + sa * u
1005
+ t = fdot_(ca, u, -sa, n)
1006
+ U = fdot_(cb, t, -sb, e)
1007
+ V = fdot_(cb, e, sb, t)
1008
+ W = fdot_(ca, n, sa, u)
1066
1009
 
1067
1010
  n, kwds = _name2__(name_Uvw_kwds, _or_nameof=self)
1068
1011
  return Uvw3Tuple(U, V, W, name=n) if Uvw is None else \
@@ -1185,30 +1128,30 @@ class Local9Tuple(_NamedTuple):
1185
1128
  '''Get the I{local} I{Azimuth, Elevation, slant Range} (AER) components.
1186
1129
 
1187
1130
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
1188
- @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1189
- additional B{L{Aer}} keyword arguments, ignored if
1190
- C{B{Aer} is None}.
1131
+ @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1132
+ additional B{L{Aer}} keyword arguments, ignored if C{B{Aer}
1133
+ is None}.
1191
1134
 
1192
- @return: AER as an L{Aer} instance or if C{B{Aer} is None}, an
1193
- L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
1135
+ @return: An B{C{Aer}} instance or an L{Aer4Tuple}C{(azimuth, elevation,
1136
+ slantrange, ltp)} if C{B{Aer} is None}.
1194
1137
 
1195
- @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}}.
1138
+ @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}} item.
1196
1139
  '''
1197
1140
  return self.xyzLocal.toAer(Aer=Aer, **name_Aer_kwds)
1198
1141
 
1199
1142
  def toCartesian(self, Cartesian=None, **name_Cartesian_kwds):
1200
1143
  '''Convert this I{local} to I{geocentric} C{(x, y, z)} (ECEF).
1201
1144
 
1202
- @kwarg Cartesian: Optional class to return C{(x, y, z)} (C{Cartesian})
1203
- or C{None}.
1204
- @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1145
+ @kwarg Cartesian: Optional I{geocentric} class to return C{(x, y, z)}
1146
+ (C{Cartesian}) or C{None}.
1147
+ @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1205
1148
  additional B{C{Cartesian}} keyword arguments, ignored if
1206
1149
  C{B{Cartesian} is None}.
1207
1150
 
1208
- @return: A C{B{Cartesian}(x, y, z, **B{Cartesian_kwds})} instance or
1209
- if C{B{Cartesian} is None}, a L{Vector4Tuple}C{(x, y, z, h)} .
1151
+ @return: A C{B{Cartesian}(x, y, z, **B{Cartesian_kwds})} instance or a
1152
+ L{Vector4Tuple}C{(x, y, z, h)} if C{B{Cartesian} is None}.
1210
1153
 
1211
- @raise TypeError: Invalid B{C{Cartesian}} or B{C{name_Cartesian_kwds}}.
1154
+ @raise TypeError: Invalid B{C{Cartesian}} or B{C{name_Cartesian_kwds}} item.
1212
1155
  '''
1213
1156
  return self.ecef.toCartesian(Cartesian=Cartesian, **name_Cartesian_kwds) # PYCHOK _Tuple
1214
1157
 
@@ -1216,30 +1159,30 @@ class Local9Tuple(_NamedTuple):
1216
1159
  '''Get the I{local} I{East, North, Up} (ENU) components.
1217
1160
 
1218
1161
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
1219
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1220
- additional B{L{Enu}} keyword arguments, ignored if
1221
- C{B{Enu} is None}.
1162
+ @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1163
+ additional B{L{Enu}} keyword arguments, ignored if C{B{Enu}
1164
+ is None}.
1222
1165
 
1223
1166
  @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
1224
1167
  L{Enu4Tuple}C{(east, north, up, ltp)}.
1225
1168
 
1226
- @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}}.
1169
+ @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}} item.
1227
1170
  '''
1228
1171
  return self.xyzLocal.toEnu(Enu=Enu, **name_Enu_kwds)
1229
1172
 
1230
1173
  def toLatLon(self, LatLon=None, **name_LatLon_kwds):
1231
1174
  '''Convert this I{local} to I{geodetic} C{(lat, lon, height)}.
1232
1175
 
1233
- @kwarg LatLon: Optional class to return C{(lat, lon, height)}
1176
+ @kwarg LatLon: Optional I{geodetic} class to return C{(lat, lon, height)}
1234
1177
  (C{LatLon}) or C{None}.
1235
- @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1178
+ @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1236
1179
  additional B{C{LatLon}} keyword arguments, ignored if
1237
1180
  C{B{LatLon} is None}.
1238
1181
 
1239
- @return: An instance of C{B{LatLon}(lat, lon, **B{LatLon_kwds})}
1240
- or if C{B{LatLon} is None}, a L{LatLon3Tuple}C{(lat, lon,
1241
- height)} respectively L{LatLon4Tuple}C{(lat, lon, height,
1242
- datum)} depending on whether C{datum} is un-/specified.
1182
+ @return: An C{B{LatLon}(lat, lon, **B{LatLon_kwds})} instance or if
1183
+ C{B{LatLon} is None}, a L{LatLon4Tuple}C{(lat, lon, height,
1184
+ datum)} or L{LatLon3Tuple}C{(lat, lon, height)} if C{datum}
1185
+ is specified or not.
1243
1186
 
1244
1187
  @raise TypeError: Invalid B{C{LatLon}} or B{C{name_LatLon_kwds}}.
1245
1188
  '''
@@ -1249,14 +1192,14 @@ class Local9Tuple(_NamedTuple):
1249
1192
  '''Get the I{local} I{North, East, Down} (NED) components.
1250
1193
 
1251
1194
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
1252
- @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1253
- additional B{L{Ned}} keyword arguments, ignored if
1254
- C{B{Ned} is None}.
1195
+ @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1196
+ additional B{L{Ned}} keyword arguments, ignored if C{B{Ned}
1197
+ is None}.
1255
1198
 
1256
- @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
1257
- L{Ned4Tuple}C{(north, east, down, ltp)}.
1199
+ @return: An B{C{Ned}} instance or an L{Ned4Tuple}C{(north, east, down,
1200
+ ltp)} if C{B{Ned} is None}.
1258
1201
 
1259
- @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}}.
1202
+ @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}} item.
1260
1203
  '''
1261
1204
  return self.xyzLocal.toNed(Ned=Ned, **name_Ned_kwds)
1262
1205
 
@@ -1264,14 +1207,14 @@ class Local9Tuple(_NamedTuple):
1264
1207
  '''Get the I{local} I{X, Y, Z} (XYZ) components.
1265
1208
 
1266
1209
  @kwarg Xyz: Class to return XYZ (L{XyzLocal}) or C{None}.
1267
- @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1268
- additional B{C{Xyz}} keyword arguments, ignored if
1269
- C{B{Xyz} is None}.
1210
+ @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1211
+ additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
1212
+ is None}.
1270
1213
 
1271
- @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None},
1272
- an L{Xyz4Tuple}C{(x, y, z, ltp)}.
1214
+ @return: An B{C{Xyz}} instance or an L{Xyz4Tuple}C{(x, y, z, ltp)} if
1215
+ C{B{Xyz} is None}.
1273
1216
 
1274
- @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
1217
+ @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}} item.
1275
1218
  '''
1276
1219
  return self.xyzLocal.toXyz(Xyz=Xyz, **name_Xyz_kwds)
1277
1220
 
@@ -1324,14 +1267,14 @@ class Uvw(_Vector3d):
1324
1267
  @arg location: The geodetic (C{LatLon}) or geocentric (C{Cartesian},
1325
1268
  L{Vector3d}) location from where to cast the L{Los}.
1326
1269
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
1327
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1328
- additional B{L{Enu}} keyword arguments, ignored if
1329
- C{B{Enu} is None}.
1270
+ @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1271
+ additional B{L{Enu}} keyword arguments, ignored if C{B{Enu}
1272
+ is None}.
1330
1273
 
1331
- @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
1332
- L{Enu4Tuple}C{(east, north, up, ltp)} with C{ltp=None}.
1274
+ @return: An B{C{Enu}} instance or an L{Enu4Tuple}C{(east, north, up, ltp)}
1275
+ with C{ltp=None} if C{B{Enu} is None}.
1333
1276
 
1334
- @raise TypeError: Invalid B{C{location}} or B{C{name_Enu_kwds}}.
1277
+ @raise TypeError: Invalid B{C{location}}, B{C{Enu}} or B{C{name_Enu_kwds}} item.
1335
1278
 
1336
1279
  @see: Function U{lookAtSpheroid<https://PyPI.org/project/pymap3d>}.
1337
1280
  '''
@@ -1341,10 +1284,10 @@ class Uvw(_Vector3d):
1341
1284
  raise _TypeError(location=location, cause=x)
1342
1285
  u, v, w = self.uvw
1343
1286
 
1344
- t = cb * u + sb * v
1345
- E = cb * v - sb * u
1346
- N = ca * w - sa * t
1347
- U = ca * t + sa * w
1287
+ t = fdot_(cb, u, sb, v)
1288
+ E = fdot_(cb, v, -sb, u)
1289
+ N = fdot_(ca, w, -sa, t)
1290
+ U = fdot_(ca, t, sa, w)
1348
1291
 
1349
1292
  n, kwds = _name2__(name_Enu_kwds, _or_nameof=self)
1350
1293
  return Enu4Tuple(E, N, U, name=n) if Enu is None else \
@@ -1427,7 +1370,7 @@ class ChLV9Tuple(Local9Tuple):
1427
1370
  def EN2_LV95(self):
1428
1371
  '''Get the I{falsed Swiss (E_LV95, N_LV95)} easting and northing (L{ChLVEN2Tuple}).
1429
1372
  '''
1430
- return ChLVEN2Tuple(*_ltp.ChLV.false2(self.Y, self.X, True), name=self.name)
1373
+ return ChLVEN2Tuple(*_ChLV_false2(*self.YX, LV95=True), name=self.name)
1431
1374
 
1432
1375
  @Property_RO
1433
1376
  def h_LV03(self):
@@ -1445,19 +1388,19 @@ class ChLV9Tuple(Local9Tuple):
1445
1388
  def isChLV(self):
1446
1389
  '''Is this a L{ChLV}-generated L{ChLV9Tuple}?.
1447
1390
  '''
1448
- return self.ltp.__class__ is _ltp.ChLV
1391
+ return self.ltp.__class__ is _MODS.ltp.ChLV
1449
1392
 
1450
1393
  @property_RO
1451
1394
  def isChLVa(self):
1452
1395
  '''Is this a L{ChLVa}-generated L{ChLV9Tuple}?.
1453
1396
  '''
1454
- return self.ltp.__class__ is _ltp.ChLVa
1397
+ return self.ltp.__class__ is _MODS.ltp.ChLVa
1455
1398
 
1456
1399
  @property_RO
1457
1400
  def isChLVe(self):
1458
1401
  '''Is this a L{ChLVe}-generated L{ChLV9Tuple}?.
1459
1402
  '''
1460
- return self.ltp.__class__ is _ltp.ChLVe
1403
+ return self.ltp.__class__ is _MODS.ltp.ChLVe
1461
1404
 
1462
1405
  @Property_RO
1463
1406
  def N_LV95(self):
@@ -1499,7 +1442,7 @@ class ChLV9Tuple(Local9Tuple):
1499
1442
  def yx2_LV03(self):
1500
1443
  '''Get the B{falsed} I{Swiss (y_LV03, x_LV03)} easting and northing (L{ChLVyx2Tuple}).
1501
1444
  '''
1502
- return ChLVyx2Tuple(*_ltp.ChLV.false2(self.Y, self.X, False), name=self.name)
1445
+ return ChLVyx2Tuple(*_ChLV_false2(*self.YX, LV95=False), name=self.name)
1503
1446
 
1504
1447
  @Property_RO
1505
1448
  def z(self):
@@ -1520,7 +1463,7 @@ class ChLVYX2Tuple(_NamedTuple):
1520
1463
 
1521
1464
  @see: Function L{ChLV.false2} for more information.
1522
1465
  '''
1523
- return _ltp.ChLV.false2(*self, LV95=LV95, name=self.name)
1466
+ return _ChLV_false2(*self, LV95=LV95, name=self.name)
1524
1467
 
1525
1468
 
1526
1469
  class ChLVEN2Tuple(_NamedTuple):
@@ -1535,7 +1478,7 @@ class ChLVEN2Tuple(_NamedTuple):
1535
1478
 
1536
1479
  @see: Function L{ChLV.unfalse2} for more information.
1537
1480
  '''
1538
- return _ltp.ChLV.unfalse2(*self, LV95=True, name=self.name)
1481
+ return _ChLV_unfalse2(*self, LV95=True, name=self.name)
1539
1482
 
1540
1483
 
1541
1484
  class ChLVyx2Tuple(_NamedTuple):
@@ -1550,7 +1493,7 @@ class ChLVyx2Tuple(_NamedTuple):
1550
1493
 
1551
1494
  @see: Function L{ChLV.unfalse2} for more information.
1552
1495
  '''
1553
- return _ltp.ChLV.unfalse2(*self, LV95=False, name=self.name)
1496
+ return _ChLV_unfalse2(*self, LV95=False, name=self.name)
1554
1497
 
1555
1498
 
1556
1499
  class Footprint5Tuple(_NamedTuple):
@@ -1565,26 +1508,25 @@ class Footprint5Tuple(_NamedTuple):
1565
1508
 
1566
1509
  def toLatLon5(self, ltp=None, LatLon=None, **name_LatLon_kwds):
1567
1510
  '''Convert this footprint's C{center} and 4 corners to I{geodetic}
1568
- C{LatLon(lat, lon, height)}s or C{LatLon3-} or C{-4Tuple}s.
1511
+ C{LatLon(lat, lon, height)}s, C{LatLon3Tuple}s or C{LatLon4Tuple}s.
1569
1512
 
1570
1513
  @kwarg ltp: The I{local tangent plane} (L{Ltp}), overriding this
1571
1514
  footprint's C{center} or C{frustrum} C{ltp}.
1572
1515
  @kwarg LatLon: Optional I{geodetic} class (C{LatLon}) or C{None}.
1573
- @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1574
- additional B{C{LatLon}} keyword arguments, ignored if
1575
- C{B{LatLon} is None}.
1516
+ @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1517
+ additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon}
1518
+ is None}.
1576
1519
 
1577
- @return: A L{Footprint5Tuple} of 5 C{B{LatLon}(lat, lon,
1578
- **B{name_LatLon_kwds})} instances or if C{B{LatLon} is None},
1579
- 5 L{LatLon3Tuple}C{(lat, lon, height)}s respectively
1580
- 5 L{LatLon4Tuple}C{(lat, lon, height, datum)}s depending
1581
- on whether keyword argument C{datum} is un-/specified.
1520
+ @return: A L{Footprint5Tuple} of 5 C{B{LatLon}(lat, lon, **B{name_LatLon_kwds})}
1521
+ instances or if C{B{LatLon} is None}, 5 L{LatLon3Tuple}C{(lat, lon,
1522
+ height)}s respectively 5 L{LatLon4Tuple}C{(lat, lon, height, datum)}s
1523
+ depending on whether keyword argument C{datum} is un-/specified.
1582
1524
 
1583
- @raise TypeError: Invalid B{C{ltp}}, B{C{LatLon}} or B{C{name_LatLon_kwds}}.
1525
+ @raise TypeError: Invalid B{C{ltp}}, B{C{LatLon}} or B{C{name_LatLon_kwds}} item.
1584
1526
 
1585
1527
  @see: Methods L{XyzLocal.toLatLon} and L{Footprint5Tuple.xyzLocal5}.
1586
1528
  '''
1587
- ltp = _ltp._xLtp(ltp, self.center.ltp) # PYCHOK .center
1529
+ ltp = _xLtp(ltp, self.center.ltp) # PYCHOK .center
1588
1530
  kwds = _name1__(name_LatLon_kwds, _or_nameof=self)
1589
1531
  kwds = _xkwds(kwds, ltp=ltp, LatLon=LatLon)
1590
1532
  return Footprint5Tuple(t.toLatLon(**kwds) for t in self.xyzLocal5())
@@ -1602,16 +1544,90 @@ class Footprint5Tuple(_NamedTuple):
1602
1544
  if ltp is None:
1603
1545
  p = self
1604
1546
  else:
1605
- p = _ltp._xLtp(ltp)
1547
+ p = _xLtp(ltp)
1606
1548
  p = tuple(Xyz4Tuple(t.x, t.y, t.z, p) for t in self)
1607
1549
  return Footprint5Tuple(t.xyzLocal for t in p)
1608
1550
 
1609
1551
 
1552
+ def _ChLV_false2(Y, X, **LV95_name):
1553
+ '''(INTERNAL) Invoke static method C{ltp.ChLV.false2}.
1554
+ '''
1555
+ return _MODS.ltp.ChLV.false2(Y, X, **LV95_name)
1556
+
1557
+
1558
+ def _ChLV_unfalse2(e, n, **LV95_name):
1559
+ '''(INTERNAL) Invoke static method C{ltp.ChLV.unfalse2}.
1560
+ '''
1561
+ return _MODS.ltp.ChLV.unfalse2(e, n, **LV95_name)
1562
+
1563
+
1564
+ def _er2gr(e, r):
1565
+ '''(INTERNAL) Elevation and slant range to ground range.
1566
+ '''
1567
+ c = cos(radians(e))
1568
+ return Meter_(groundrange=r * c)
1569
+
1570
+
1571
+ def _init(inst, abc, ltp, name):
1572
+ '''(INTERNAL) Complete C{__init__}.
1573
+ '''
1574
+ if abc is None:
1575
+ n = _name__(**name)
1576
+ else:
1577
+ n = abc._name__(name)
1578
+ ltp = _xattr(abc, ltp=ltp)
1579
+ if ltp:
1580
+ inst._ltp = _xLtp(ltp)
1581
+ if n:
1582
+ inst.name = n
1583
+
1584
+
1585
+ def _toStr2(inst, prec=None, fmt=Fmt.SQUARE, sep=_COMMASPACE_):
1586
+ '''(INTERNAL) Get attribute name and value strings, joined and bracketed.
1587
+ '''
1588
+ a = inst._toStr # 'aer', 'enu', 'ned', 'xyz'
1589
+ t = getattr(inst, a + _4_, ())[:len(a)] or getattr(inst, a)
1590
+ t = strs(t, prec=3 if prec is None else prec)
1591
+ if sep:
1592
+ t = sep.join(t)
1593
+ if fmt:
1594
+ t = fmt(t)
1595
+ return a, t
1596
+
1597
+
1598
+ def _xLtp(ltp, *dflt):
1599
+ '''(INTERNAL) Invoke C{ltp._xLtp}.
1600
+ '''
1601
+ return _MODS.ltp._xLtp(ltp, *dflt)
1602
+
1603
+
1604
+ def _xyz2aer4(inst):
1605
+ '''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
1606
+ '''
1607
+ x, y, z, _ = inst.xyz4
1608
+ A = Azimuth(atan2b(x, y))
1609
+ E = Degrees(elevation=atan2d(z, hypot(x, y)))
1610
+ R = Meter(slantrange=hypot_(x, y, z))
1611
+ return Aer4Tuple(A, E, R, inst.ltp, name=inst.name)
1612
+
1613
+
1614
+ def _xyzLocal(*Types, **name_inst):
1615
+ '''(INTERNAL) Get C{inst} or C{inst.xyzLocal}.
1616
+ '''
1617
+ n, inst = _xkwds_item2(name_inst)
1618
+ if isinstance(inst, Types):
1619
+ return None
1620
+ try:
1621
+ return inst.xyzLocal
1622
+ except (AttributeError, TypeError):
1623
+ raise _TypeError(n, inst, txt_not_=_local_)
1624
+
1625
+
1610
1626
  __all__ += _ALL_DOCS(_AbcBase)
1611
1627
 
1612
1628
  # **) MIT License
1613
1629
  #
1614
- # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
1630
+ # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1615
1631
  #
1616
1632
  # Permission is hereby granted, free of charge, to any person obtaining a
1617
1633
  # copy of this software and associated documentation files (the "Software"),