pygeodesy 24.11.11__py2.py3-none-any.whl → 25.1.5__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.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/METADATA +34 -35
  2. PyGeodesy-25.1.5.dist-info/RECORD +118 -0
  3. {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/WHEEL +1 -1
  4. pygeodesy/__init__.py +19 -19
  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 +5 -5
  19. pygeodesy/basics.py +60 -8
  20. pygeodesy/booleans.py +1 -1
  21. pygeodesy/cartesianBase.py +22 -61
  22. pygeodesy/clipy.py +1 -1
  23. pygeodesy/constants.py +5 -5
  24. pygeodesy/css.py +1 -1
  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 +86 -2
  29. pygeodesy/deprecated/consterns.py +1 -1
  30. pygeodesy/deprecated/datum.py +5 -5
  31. pygeodesy/deprecated/functions.py +42 -8
  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 +53 -56
  39. pygeodesy/elevations.py +1 -1
  40. pygeodesy/ellipsoidalBase.py +3 -3
  41. pygeodesy/ellipsoidalBaseDI.py +1 -1
  42. pygeodesy/ellipsoidalExact.py +1 -1
  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 +4 -5
  48. pygeodesy/elliptic.py +6 -6
  49. pygeodesy/epsg.py +1 -1
  50. pygeodesy/errors.py +1 -1
  51. pygeodesy/etm.py +5 -5
  52. pygeodesy/fmath.py +18 -17
  53. pygeodesy/formy.py +409 -555
  54. pygeodesy/frechet.py +29 -86
  55. pygeodesy/fstats.py +1 -1
  56. pygeodesy/fsums.py +32 -33
  57. pygeodesy/gars.py +1 -1
  58. pygeodesy/geodesici.py +7 -7
  59. pygeodesy/geodesicw.py +1 -1
  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 +2 -2
  64. pygeodesy/geodesicx/__main__.py +4 -5
  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 +1 -1
  70. pygeodesy/geohash.py +1 -1
  71. pygeodesy/geoids.py +277 -203
  72. pygeodesy/hausdorff.py +23 -81
  73. pygeodesy/heights.py +115 -150
  74. pygeodesy/internals.py +1 -1
  75. pygeodesy/interns.py +2 -3
  76. pygeodesy/iters.py +1 -1
  77. pygeodesy/karney.py +3 -3
  78. pygeodesy/ktm.py +16 -15
  79. pygeodesy/latlonBase.py +323 -409
  80. pygeodesy/lazily.py +53 -44
  81. pygeodesy/lcc.py +1 -1
  82. pygeodesy/ltp.py +46 -50
  83. pygeodesy/ltpTuples.py +147 -130
  84. pygeodesy/mgrs.py +1 -1
  85. pygeodesy/named.py +149 -3
  86. pygeodesy/namedTuples.py +58 -7
  87. pygeodesy/nvectorBase.py +122 -105
  88. pygeodesy/osgr.py +1 -1
  89. pygeodesy/points.py +1 -1
  90. pygeodesy/props.py +1 -1
  91. pygeodesy/resections.py +18 -17
  92. pygeodesy/rhumb/__init__.py +1 -1
  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 +1 -1
  97. pygeodesy/simplify.py +289 -401
  98. pygeodesy/solveBase.py +1 -1
  99. pygeodesy/sphericalBase.py +1 -1
  100. pygeodesy/sphericalNvector.py +5 -5
  101. pygeodesy/sphericalTrigonometry.py +7 -6
  102. pygeodesy/streprs.py +10 -5
  103. pygeodesy/trf.py +1 -1
  104. pygeodesy/triaxials.py +23 -16
  105. pygeodesy/units.py +16 -16
  106. pygeodesy/unitsBase.py +1 -1
  107. pygeodesy/ups.py +4 -4
  108. pygeodesy/utily.py +341 -211
  109. pygeodesy/utm.py +5 -5
  110. pygeodesy/utmups.py +1 -1
  111. pygeodesy/utmupsBase.py +1 -1
  112. pygeodesy/vector2d.py +5 -5
  113. pygeodesy/vector3d.py +14 -3
  114. pygeodesy/vector3dBase.py +5 -5
  115. pygeodesy/webmercator.py +1 -1
  116. pygeodesy/wgrs.py +1 -1
  117. PyGeodesy-24.11.11.dist-info/RECORD +0 -118
  118. {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/top_level.txt +0 -0
pygeodesy/ltpTuples.py CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  u'''Named, I{Local Tangent Plane} (LTP) tuples.
5
5
 
6
- Local coordinate classes L{XyzLocal}, L{Enu}, L{Ned} and L{Aer}
7
- and local coordinate tuples L{Local9Tuple}, L{Xyz4Tuple}, L{Enu4Tuple},
6
+ Local coordinate classes L{XyzLocal}, L{Enu}, L{Ned} and L{Aer} and
7
+ local coordinate tuples L{Local9Tuple}, L{Xyz4Tuple}, L{Enu4Tuple},
8
8
  L{Ned4Tuple}, L{Aer4Tuple}, L{ChLV9Tuple}, L{ChLVEN2Tuple},
9
9
  L{ChLVYX2Tuple}, L{ChLVyx2Tuple} and L{Footprint5Tuple}.
10
10
 
@@ -22,6 +22,7 @@ from pygeodesy.interns import NN, _4_, _azimuth_, _center_, _COMMASPACE_, \
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.11.07'
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
  '''
@@ -130,8 +74,8 @@ class _AbcBase(_NamedBase):
130
74
  additional B{L{Aer}} keyword arguments, ignored if C{B{Aer}
131
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
  '''
@@ -145,8 +89,8 @@ class _AbcBase(_NamedBase):
145
89
  additional B{L{Enu}} keyword arguments, ignored if C{B{Enu}
146
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
  '''
@@ -160,8 +104,8 @@ class _AbcBase(_NamedBase):
160
104
  additional B{L{Ned}} keyword arguments, ignored if C{B{Ned}
161
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
  '''
@@ -176,8 +120,8 @@ class _AbcBase(_NamedBase):
176
120
  additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
177
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)
@@ -818,14 +762,14 @@ class XyzLocal(_Vector3d):
818
762
  additional B{C{Aer}} keyword arguments, ignored if C{B{Aer}
819
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})
@@ -840,14 +784,14 @@ class XyzLocal(_Vector3d):
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
@@ -860,10 +804,10 @@ class XyzLocal(_Vector3d):
860
804
  additional B{C{Enu}} keyword arguments, ignored if C{B{Enu}
861
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
 
@@ -878,11 +822,10 @@ class XyzLocal(_Vector3d):
878
822
  additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon}
879
823
  is None}.
880
824
 
881
- @return: An B{C{LatLon}} instance or 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)
@@ -917,10 +860,10 @@ class XyzLocal(_Vector3d):
917
860
  additional B{C{Ned}} keyword arguments, ignored if C{B{Ned}
918
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
 
@@ -933,10 +876,10 @@ class XyzLocal(_Vector3d):
933
876
  additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
934
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
 
@@ -1046,10 +989,10 @@ class Enu(XyzLocal):
1046
989
  additional B{L{Uvw}} keyword arguments, ignored if C{B{Uvw}
1047
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
  '''
@@ -1189,26 +1132,26 @@ class Local9Tuple(_NamedTuple):
1189
1132
  additional B{L{Aer}} keyword arguments, ignored if C{B{Aer}
1190
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}.
1145
+ @kwarg Cartesian: Optional I{geocentric} class to return C{(x, y, z)}
1146
+ (C{Cartesian}) or C{None}.
1204
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
 
@@ -1223,23 +1166,23 @@ class Local9Tuple(_NamedTuple):
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
1178
  @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
1236
- additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon}
1237
- is None}.
1179
+ additional B{C{LatLon}} keyword arguments, ignored if
1180
+ C{B{LatLon} is None}.
1238
1181
 
1239
- @return: An instance of C{B{LatLon}(lat, lon, **B{LatLon_kwds})} or if
1240
- C{B{LatLon} is None}, a L{LatLon3Tuple}C{(lat, lon, height)}
1241
- respectively L{LatLon4Tuple}C{(lat, lon, height, datum)}
1242
- 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
  '''
@@ -1253,10 +1196,10 @@ class Local9Tuple(_NamedTuple):
1253
1196
  additional B{L{Ned}} keyword arguments, ignored if C{B{Ned}
1254
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
 
@@ -1268,10 +1211,10 @@ class Local9Tuple(_NamedTuple):
1268
1211
  additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz}
1269
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
 
@@ -1328,10 +1271,10 @@ class Uvw(_Vector3d):
1328
1271
  additional B{L{Enu}} keyword arguments, ignored if C{B{Enu}
1329
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
  '''
@@ -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,7 +1508,7 @@ 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}.
@@ -1579,11 +1522,11 @@ class Footprint5Tuple(_NamedTuple):
1579
1522
  height)}s respectively 5 L{LatLon4Tuple}C{(lat, lon, height, datum)}s
1580
1523
  depending on whether keyword argument C{datum} is un-/specified.
1581
1524
 
1582
- @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.
1583
1526
 
1584
1527
  @see: Methods L{XyzLocal.toLatLon} and L{Footprint5Tuple.xyzLocal5}.
1585
1528
  '''
1586
- ltp = _ltp._xLtp(ltp, self.center.ltp) # PYCHOK .center
1529
+ ltp = _xLtp(ltp, self.center.ltp) # PYCHOK .center
1587
1530
  kwds = _name1__(name_LatLon_kwds, _or_nameof=self)
1588
1531
  kwds = _xkwds(kwds, ltp=ltp, LatLon=LatLon)
1589
1532
  return Footprint5Tuple(t.toLatLon(**kwds) for t in self.xyzLocal5())
@@ -1601,16 +1544,90 @@ class Footprint5Tuple(_NamedTuple):
1601
1544
  if ltp is None:
1602
1545
  p = self
1603
1546
  else:
1604
- p = _ltp._xLtp(ltp)
1547
+ p = _xLtp(ltp)
1605
1548
  p = tuple(Xyz4Tuple(t.x, t.y, t.z, p) for t in self)
1606
1549
  return Footprint5Tuple(t.xyzLocal for t in p)
1607
1550
 
1608
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
+
1609
1626
  __all__ += _ALL_DOCS(_AbcBase)
1610
1627
 
1611
1628
  # **) MIT License
1612
1629
  #
1613
- # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
1630
+ # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1614
1631
  #
1615
1632
  # Permission is hereby granted, free of charge, to any person obtaining a
1616
1633
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/mgrs.py CHANGED
@@ -731,7 +731,7 @@ if __name__ == '__main__':
731
731
 
732
732
  # **) MIT License
733
733
  #
734
- # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
734
+ # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
735
735
  #
736
736
  # Permission is hereby granted, free of charge, to any person obtaining a
737
737
  # copy of this software and associated documentation files (the "Software"),