pygeodesy 24.6.1__py2.py3-none-any.whl → 24.6.24__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 (89) hide show
  1. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.6.24.dist-info/RECORD +117 -0
  3. pygeodesy/__init__.py +33 -32
  4. pygeodesy/albers.py +2 -2
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/auxAngle.py +40 -39
  7. pygeodesy/auxilats/auxDLat.py +3 -2
  8. pygeodesy/auxilats/auxLat.py +16 -18
  9. pygeodesy/auxilats/auxily.py +1 -1
  10. pygeodesy/azimuthal.py +10 -10
  11. pygeodesy/basics.py +9 -1
  12. pygeodesy/booleans.py +53 -66
  13. pygeodesy/cartesianBase.py +143 -155
  14. pygeodesy/css.py +14 -18
  15. pygeodesy/datums.py +6 -6
  16. pygeodesy/deprecated/__init__.py +1 -1
  17. pygeodesy/deprecated/classes.py +16 -2
  18. pygeodesy/deprecated/datum.py +3 -3
  19. pygeodesy/deprecated/functions.py +6 -8
  20. pygeodesy/dms.py +23 -27
  21. pygeodesy/ecef.py +49 -55
  22. pygeodesy/elevations.py +4 -4
  23. pygeodesy/ellipsoidalBase.py +28 -70
  24. pygeodesy/ellipsoidalBaseDI.py +19 -23
  25. pygeodesy/ellipsoidalExact.py +3 -3
  26. pygeodesy/ellipsoidalGeodSolve.py +15 -23
  27. pygeodesy/ellipsoidalKarney.py +37 -60
  28. pygeodesy/ellipsoidalNvector.py +44 -50
  29. pygeodesy/ellipsoidalVincenty.py +11 -14
  30. pygeodesy/ellipsoids.py +107 -101
  31. pygeodesy/errors.py +101 -49
  32. pygeodesy/etm.py +32 -44
  33. pygeodesy/formy.py +55 -58
  34. pygeodesy/frechet.py +20 -23
  35. pygeodesy/fsums.py +4 -4
  36. pygeodesy/gars.py +3 -4
  37. pygeodesy/geodesici.py +909 -0
  38. pygeodesy/geodesicw.py +11 -13
  39. pygeodesy/geodesicx/__init__.py +4 -4
  40. pygeodesy/geodesicx/gx.py +18 -28
  41. pygeodesy/geodesicx/gxbases.py +20 -8
  42. pygeodesy/geodesicx/gxline.py +16 -22
  43. pygeodesy/geodsolve.py +102 -34
  44. pygeodesy/geohash.py +39 -60
  45. pygeodesy/geoids.py +28 -37
  46. pygeodesy/hausdorff.py +21 -23
  47. pygeodesy/heights.py +15 -28
  48. pygeodesy/internals.py +19 -12
  49. pygeodesy/interns.py +4 -10
  50. pygeodesy/iters.py +2 -2
  51. pygeodesy/karney.py +20 -4
  52. pygeodesy/ktm.py +13 -16
  53. pygeodesy/latlonBase.py +202 -191
  54. pygeodesy/lazily.py +96 -59
  55. pygeodesy/lcc.py +29 -32
  56. pygeodesy/ltp.py +43 -24
  57. pygeodesy/ltpTuples.py +190 -183
  58. pygeodesy/mgrs.py +35 -9
  59. pygeodesy/named.py +106 -72
  60. pygeodesy/namedTuples.py +43 -14
  61. pygeodesy/nvectorBase.py +23 -27
  62. pygeodesy/osgr.py +9 -9
  63. pygeodesy/points.py +7 -7
  64. pygeodesy/rhumb/__init__.py +1 -1
  65. pygeodesy/rhumb/aux_.py +5 -5
  66. pygeodesy/rhumb/bases.py +30 -31
  67. pygeodesy/rhumb/ekx.py +3 -4
  68. pygeodesy/rhumb/solve.py +8 -61
  69. pygeodesy/solveBase.py +22 -19
  70. pygeodesy/sphericalBase.py +26 -21
  71. pygeodesy/sphericalNvector.py +13 -13
  72. pygeodesy/sphericalTrigonometry.py +86 -97
  73. pygeodesy/streprs.py +8 -36
  74. pygeodesy/trf.py +3 -3
  75. pygeodesy/triaxials.py +117 -91
  76. pygeodesy/units.py +229 -321
  77. pygeodesy/unitsBase.py +116 -108
  78. pygeodesy/ups.py +26 -31
  79. pygeodesy/utily.py +12 -11
  80. pygeodesy/utm.py +35 -40
  81. pygeodesy/utmups.py +43 -46
  82. pygeodesy/utmupsBase.py +9 -10
  83. pygeodesy/vector3d.py +59 -62
  84. pygeodesy/vector3dBase.py +17 -15
  85. pygeodesy/webmercator.py +19 -21
  86. pygeodesy/wgrs.py +18 -20
  87. PyGeodesy-24.6.1.dist-info/RECORD +0 -116
  88. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/WHEEL +0 -0
  89. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/top_level.txt +0 -0
pygeodesy/ltpTuples.py CHANGED
@@ -11,11 +11,11 @@ L{ChLVYX2Tuple}, L{ChLVyx2Tuple} and L{Footprint5Tuple}.
11
11
  @see: References in module L{ltp}.
12
12
  '''
13
13
 
14
- # from pygeodesy.basics import issubclassof # from .units
14
+ # from pygeodesy.basics import issubclassof # _MODS
15
15
  from pygeodesy.constants import _0_0, _1_0, _90_0, _N_90_0
16
- from pygeodesy.dms import F_D, toDMS
17
- from pygeodesy.errors import _TypeError, _TypesError, _xattr, \
18
- _xkwds, _xkwds_item2
16
+ # from pygeodesy.dms import F_D, toDMS # _MODS
17
+ from pygeodesy.errors import _TypeError, _TypesError, _xattr, _xkwds, \
18
+ _xkwds_item2
19
19
  from pygeodesy.fmath import hypot, hypot_
20
20
  from pygeodesy.interns import NN, _4_, _azimuth_, _center_, _COMMASPACE_, \
21
21
  _ecef_, _elevation_, _height_, _lat_, _lon_, \
@@ -29,14 +29,14 @@ from pygeodesy.props import deprecated_method, deprecated_Property_RO, \
29
29
  Property_RO, property_RO
30
30
  from pygeodesy.streprs import Fmt, fstr, strs, _xzipairs
31
31
  from pygeodesy.units import Bearing, Degrees, Degrees_, Height, _isDegrees, \
32
- _isMeter, Lat, Lon, Meter, Meter_, issubclassof
33
- from pygeodesy.utily import atan2d, atan2b, sincos2_, sincos2d_
32
+ _isMeter, Lat, Lon, Meter, Meter_
33
+ from pygeodesy.utily import atan2d, atan2b, sincos2_, sincos2d_, cos, radians
34
34
  from pygeodesy.vector3d import Vector3d
35
35
 
36
- from math import cos, radians
36
+ # from math import cos, radians # from .utily
37
37
 
38
38
  __all__ = _ALL_LAZY.ltpTuples
39
- __version__ = '24.05.31'
39
+ __version__ = '24.06.15'
40
40
 
41
41
  _aer_ = 'aer'
42
42
  _alt_ = 'alt'
@@ -44,6 +44,7 @@ _down_ = 'down'
44
44
  _east_ = 'east'
45
45
  _enu_ = 'enu'
46
46
  _h__ = 'h_'
47
+ _ltp = _MODS.into(ltp=__name__)
47
48
  _ned_ = 'ned'
48
49
  _north_ = 'north'
49
50
  _local_ = 'local'
@@ -61,6 +62,20 @@ def _er2gr(e, r):
61
62
  return Meter_(groundrange=r * c)
62
63
 
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
+
64
79
  def _toStr2(inst, prec=None, fmt=Fmt.SQUARE, sep=_COMMASPACE_):
65
80
  '''(INTERNAL) Get attribute name and value strings, joined and bracketed.
66
81
  '''
@@ -74,25 +89,6 @@ def _toStr2(inst, prec=None, fmt=Fmt.SQUARE, sep=_COMMASPACE_):
74
89
  return a, t
75
90
 
76
91
 
77
- def _4Tuple2Cls(inst, Cls, Cls_kwds):
78
- '''(INTERNAL) Convert 4-Tuple to C{Cls} instance.
79
- '''
80
- if Cls is None:
81
- return inst
82
- elif issubclassof(Cls, Aer):
83
- return inst.xyzLocal.toAer(Aer=Cls, **Cls_kwds)
84
- elif issubclassof(Cls, Enu): # PYCHOK no cover
85
- return inst.xyzLocal.toEnu(Enu=Cls, **Cls_kwds)
86
- elif issubclassof(Cls, Ned):
87
- return inst.xyzLocal.toNed(Ned=Cls, **Cls_kwds)
88
- elif issubclassof(Cls, XyzLocal): # PYCHOK no cover
89
- return inst.xyzLocal.toXyz(Xyz=Cls, **Cls_kwds)
90
- elif Cls is Local9Tuple: # PYCHOK no cover
91
- return inst.xyzLocal.toLocal9Tuple(**Cls_kwds)
92
- n = inst.__class__.__name__[:3] # PYCHOK no cover
93
- raise _TypesError(n, Cls, Aer, Enu, Ned, XyzLocal)
94
-
95
-
96
92
  def _xyz2aer4(inst):
97
93
  '''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
98
94
  '''
@@ -115,10 +111,10 @@ def _xyzLocal(*Types, **name_inst):
115
111
  raise _TypeError(n, inst, txt_not_=_local_)
116
112
 
117
113
 
118
- class _NamedAerNed(_NamedBase):
114
+ class _AbcBase(_NamedBase):
119
115
  '''(INTERNAL) Base class for classes C{Aer} and C{Ned}.
120
116
  '''
121
- _ltp = None # local tangent plane (C{Ltp}), origin
117
+ _ltp = None # local tangent plane (C{Ltp}), origin
122
118
 
123
119
  @Property_RO
124
120
  def ltp(self):
@@ -130,12 +126,12 @@ class _NamedAerNed(_NamedBase):
130
126
  '''Get the I{local} I{Azimuth, Elevation, slant Range} (AER) components.
131
127
 
132
128
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
133
- @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and
134
- optional, additional B{L{Aer}} keyword arguments,
135
- ignored if B{C{Aer}} is 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}.
136
132
 
137
- @return: AER as an L{Aer} instance or if C{B{Aer} is None},
138
- an L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
133
+ @return: AER as an L{Aer} instance or if C{B{Aer} is None}, an
134
+ L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
139
135
 
140
136
  @raise TypeError: Invalid B{C{Aer}} or B{C{name_Aer_kwds}}.
141
137
  '''
@@ -145,12 +141,12 @@ class _NamedAerNed(_NamedBase):
145
141
  '''Get the I{local} I{East, North, Up} (ENU) components.
146
142
 
147
143
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
148
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and
149
- optional, additional B{L{Enu}} keyword arguments,
150
- ignored if C{B{Enu} is 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}.
151
147
 
152
- @return: ENU as an L{Enu} instance or if C{B{Enu} is None},
153
- an L{Enu4Tuple}C{(east, north, up, ltp)}.
148
+ @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
149
+ L{Enu4Tuple}C{(east, north, up, ltp)}.
154
150
 
155
151
  @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}}.
156
152
  '''
@@ -160,12 +156,12 @@ class _NamedAerNed(_NamedBase):
160
156
  '''Get the I{local} I{North, East, Down} (NED) components.
161
157
 
162
158
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
163
- @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and
164
- optional, additional B{L{Ned}} keyword arguments,
165
- ignored if B{C{Ned}} is 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}.
166
162
 
167
- @return: NED as an L{Ned} instance or if C{B{Ned} is None},
168
- an L{Ned4Tuple}C{(north, east, down, ltp)}.
163
+ @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
164
+ L{Ned4Tuple}C{(north, east, down, ltp)}.
169
165
 
170
166
  @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}}.
171
167
  '''
@@ -174,14 +170,14 @@ class _NamedAerNed(_NamedBase):
174
170
  def toXyz(self, Xyz=None, **name_Xyz_kwds):
175
171
  '''Get the local I{X, Y, Z} (XYZ) components.
176
172
 
177
- @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu},
178
- L{Ned}, L{Aer}) or C{None}.
179
- @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and
180
- optional, additional B{C{Xyz}} keyword arguments,
181
- ignored if C{B{Xyz} is None}.
173
+ @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer})
174
+ 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}.
182
178
 
183
- @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None},
184
- an L{Xyz4Tuple}C{(x, y, z, ltp)}.
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)}.
185
181
 
186
182
  @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
187
183
  '''
@@ -205,7 +201,42 @@ class _NamedAerNed(_NamedBase):
205
201
  return XyzLocal(self.xyz4, name=self.name)
206
202
 
207
203
 
208
- class Aer(_NamedAerNed):
204
+ class _Abc4Tuple(_NamedTuple):
205
+ '''(INTERNAL) Base class for C{Aer4Tuple}, C{Enu4Tuple},
206
+ C{Ned4Tuple} and C{Xyz4Tuple}.
207
+ '''
208
+ def _2Cls(self, Abc, Cls, Cls_kwds):
209
+ '''(INTERNAL) Convert 4-Tuple to C{Cls} instance.
210
+ '''
211
+ kwds = _name1__(Cls_kwds, _or_nameof=self)
212
+ _is = _MODS.basics.issubclassof
213
+ if Cls is None:
214
+ n, _ = _name2__(Cls_kwds)
215
+ r = self.copy(name=n) if n else self
216
+ elif _is(Cls, Abc):
217
+ r = Cls(*self, **kwds)
218
+ elif _is(Cls, Aer):
219
+ r = self.xyzLocal.toAer(**_xkwds(kwds, Aer=Cls))
220
+ elif _is(Cls, Enu): # PYCHOK no cover
221
+ r = self.xyzLocal.toEnu(**_xkwds(kwds, Enu=Cls))
222
+ elif _is(Cls, Ned):
223
+ r = self.xyzLocal.toNed(**_xkwds(kwds, Ned=Cls))
224
+ elif _is(Cls, XyzLocal): # PYCHOK no cover
225
+ r = self.xyzLocal.toXyz(**_xkwds(kwds, Xyz=Cls))
226
+ elif Cls is Local9Tuple: # PYCHOK no cover
227
+ r = self.xyzLocal.toLocal9Tuple(**kwds)
228
+ else: # PYCHOK no cover
229
+ n = Abc.__name__[:3]
230
+ raise _TypesError(n, Cls, Aer, Enu, Ned, XyzLocal)
231
+ return r
232
+
233
+ @property_RO
234
+ def xyzLocal(self): # PYCHOK no cover
235
+ '''I{Must be overloaded}.'''
236
+ self._notOverloaded()
237
+
238
+
239
+ class Aer(_AbcBase):
209
240
  '''Local C{Azimuth-Elevation-Range} (AER) in a I{local tangent plane}.
210
241
  '''
211
242
  _azimuth = _0_0 # bearing from North (C{degrees360})
@@ -236,22 +267,16 @@ class Aer(_NamedAerNed):
236
267
  or B{C{slantrange}}.
237
268
  '''
238
269
  if _isDegrees(azimuth_aer):
239
- self._azimuth = Bearing(azimuth=azimuth_aer)
240
- self._elevation = Degrees_(elevation=elevation, low=_N_90_0, high=_90_0)
241
- self._slantrange = Meter_(slantrange=slantrange)
242
- p, n = ltp, _name__(**name)
270
+ aer = None
271
+ t = (Bearing(azimuth=azimuth_aer),
272
+ Degrees_(elevation=elevation, low=_N_90_0, high=_90_0),
273
+ Meter_(slantrange=slantrange), ltp)
243
274
  else: # PYCHOK no cover
244
- p = _xyzLocal(Aer, Aer4Tuple, Ned, azimuth_aer=azimuth_aer)
245
- aer = p.toAer() if p else azimuth_aer
246
- self._azimuth, self._elevation, self._slantrange = \
247
- aer.azimuth, aer.elevation, aer.slantrange
248
- p = _xattr(aer, ltp=ltp)
249
- n = aer._name__(name)
250
-
251
- if p:
252
- self._ltp = _MODS.ltp._xLtp(p)
253
- if n:
254
- self.name = n
275
+ p = _xyzLocal(Aer, Aer4Tuple, Ned, azimuth_aer=azimuth_aer)
276
+ aer = p.toAer() if p else azimuth_aer
277
+ t = aer.aer4
278
+ self._azimuth, self._elevation, self._slantrange, _ = t
279
+ _init(self, aer, ltp, name)
255
280
 
256
281
  @Property_RO
257
282
  def aer4(self):
@@ -311,8 +336,9 @@ class Aer(_NamedAerNed):
311
336
 
312
337
  @return: This AER as "[A:degrees360, E:degrees90, R:meter]" (C{str}).
313
338
  '''
314
- t = (toDMS(self.azimuth, form=F_D, prec=prec, ddd=0),
315
- toDMS(self.elevation, form=F_D, prec=prec, ddd=0),
339
+ m = _MODS.dms
340
+ t = (m.toDMS(self.azimuth, form=m.F_D, prec=prec, ddd=0),
341
+ m.toDMS(self.elevation, form=m.F_D, prec=prec, ddd=0),
316
342
  fstr( self.slantrange, prec=3 if prec is None else prec))
317
343
  return _xzipairs(self._toStr.upper(), t, sep=sep, fmt=fmt)
318
344
 
@@ -364,7 +390,7 @@ class Aer(_NamedAerNed):
364
390
  return self.xyz4.z
365
391
 
366
392
 
367
- class Aer4Tuple(_NamedTuple):
393
+ class Aer4Tuple(_Abc4Tuple):
368
394
  '''4-Tuple C{(azimuth, elevation, slantrange, ltp)},
369
395
  all in C{meter} except C{ltp}.
370
396
  '''
@@ -374,10 +400,7 @@ class Aer4Tuple(_NamedTuple):
374
400
  def _toAer(self, Cls, Cls_kwds):
375
401
  '''(INTERNAL) Return C{Cls(..., **Cls_kwds)} instance.
376
402
  '''
377
- if issubclassof(Cls, Aer):
378
- return Cls(*self, **_xkwds(Cls_kwds, name=self.name))
379
- else:
380
- return _4Tuple2Cls(self, Cls, Cls_kwds)
403
+ return self._2Cls(Aer, Cls, Cls_kwds)
381
404
 
382
405
  @Property_RO
383
406
  def groundrange(self):
@@ -410,10 +433,10 @@ class Attitude4Tuple(_NamedTuple):
410
433
  def tyr3d(self):
411
434
  '''Get this attitude's (3-D) directional vector (L{Vector3d}).
412
435
  '''
413
- return _MODS.ltp.Attitude(self).tyr3d
436
+ return _ltp.Attitude(self).tyr3d
414
437
 
415
438
 
416
- class Ned(_NamedAerNed):
439
+ class Ned(_AbcBase):
417
440
  '''Local C{North-Eeast-Down} (NED) location in a I{local tangent plane}.
418
441
 
419
442
  @see: L{Enu} and L{Ltp}.
@@ -445,21 +468,16 @@ class Ned(_NamedAerNed):
445
468
  @raise UnitError: Invalid B{C{north_ned}}, B{C{east}} or B{C{down}}.
446
469
  '''
447
470
  if _isMeter(north_ned):
448
- self._north = Meter(north=north_ned or _0_0)
449
- self._east = Meter(east=east or _0_0)
450
- self._down = Meter(down=down or _0_0)
451
- p, n = ltp, _name__(**name)
471
+ ned = None
472
+ t = (Meter(north=north_ned or _0_0),
473
+ Meter(east=east or _0_0),
474
+ Meter(down=down or _0_0), ltp)
452
475
  else: # PYCHOK no cover
453
- p = _xyzLocal(Ned, Ned4Tuple, Aer, north_ned=north_ned)
454
- ned = p.toNed() if p else north_ned
455
- self._north, self._east, self._down = ned.north, ned.east, ned.down
456
- p = _xattr(ned, ltp=ltp)
457
- n = ned._name__(name)
458
-
459
- if p:
460
- self._ltp = _MODS.ltp._xLtp(p)
461
- if n:
462
- self.name = n
476
+ p = _xyzLocal(Ned, Ned4Tuple, Aer, north_ned=north_ned)
477
+ ned = p.toNed() if p else north_ned
478
+ t = ned.ned4
479
+ self._north, self._east, self._down, _ = t
480
+ _init(self, ned, ltp, name)
463
481
 
464
482
  @Property_RO
465
483
  def aer4(self):
@@ -597,7 +615,7 @@ class Ned(_NamedAerNed):
597
615
  return Meter(z=-self._down) # negated
598
616
 
599
617
 
600
- class Ned4Tuple(_NamedTuple):
618
+ class Ned4Tuple(_Abc4Tuple):
601
619
  '''4-Tuple C{(north, east, down, ltp)}, all in C{meter} except C{ltp}.
602
620
  '''
603
621
  _Names_ = (_north_, _east_, _down_, _ltp_)
@@ -606,10 +624,7 @@ class Ned4Tuple(_NamedTuple):
606
624
  def _toNed(self, Cls, Cls_kwds):
607
625
  '''(INTERNAL) Return C{Cls(..., **Cls_kwds)} instance.
608
626
  '''
609
- if issubclassof(Cls, Ned):
610
- return Cls(*self, **_xkwds(Cls_kwds, name=self.name))
611
- else:
612
- return _4Tuple2Cls(self, Cls, Cls_kwds)
627
+ return self._2Cls(Ned, Cls, Cls_kwds)
613
628
 
614
629
  @Property_RO
615
630
  def xyzLocal(self):
@@ -679,20 +694,15 @@ class XyzLocal(_Vector3d):
679
694
  @raise UnitError: Invalid scalar B{C{x_xyz}}, B{C{y}} or B{C{z}}.
680
695
  '''
681
696
  if _isMeter(x_xyz):
682
- self._x = Meter(x=x_xyz or _0_0)
683
- self._y = Meter(y=y or _0_0)
684
- self._z = Meter(z=z or _0_0)
685
- p, n = ltp, _name__(**name)
697
+ xyz = None
698
+ t = (Meter(x=x_xyz or _0_0),
699
+ Meter(y=y or _0_0),
700
+ Meter(z=z or _0_0), ltp)
686
701
  else:
687
702
  xyz = _xyzLocal(XyzLocal, Xyz4Tuple, Local9Tuple, x_xyz=x_xyz) or x_xyz
688
- self._x, self._y, self._z = xyz.x, xyz.y, xyz.z
689
- p = _xattr(xyz, ltp=ltp)
690
- n = xyz._name__(name)
691
-
692
- if p:
693
- self._ltp = _MODS.ltp._xLtp(p)
694
- if n:
695
- self.name = n
703
+ t = xyz.xyz4 # xyz.x, xyz.y, xyz.z, xyz.ltp
704
+ self._x, self._y, self._z, _ = t
705
+ _init(self, xyz, ltp, name)
696
706
 
697
707
  def __str__(self):
698
708
  return self.toStr()
@@ -771,7 +781,7 @@ class XyzLocal(_Vector3d):
771
781
  def _ltp_kwds_name3(self, ltp, kwds):
772
782
  '''(INTERNAL) Helper for methods C{toCartesian} and C{toLatLon}.
773
783
  '''
774
- ltp = _MODS.ltp._xLtp(ltp, self.ltp)
784
+ ltp = _ltp._xLtp(ltp, self.ltp)
775
785
  kwds = _name1__(kwds, _or_nameof=self)
776
786
  kwds = _name1__(kwds, _or_nameof=ltp)
777
787
  return ltp, kwds, kwds.get(_name_, NN)
@@ -795,7 +805,7 @@ class XyzLocal(_Vector3d):
795
805
  return self.aer4.slantrange
796
806
 
797
807
  def toAer(self, Aer=None, **name_Aer_kwds):
798
- '''Get the local I{Azimuth, Elevation, slantRange} components.
808
+ '''Get the local I{Azimuth, Elevation, slant Range} components.
799
809
 
800
810
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
801
811
  @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and
@@ -814,39 +824,38 @@ class XyzLocal(_Vector3d):
814
824
 
815
825
  @kwarg Cartesian: Optional class to return C{(x, y, z)} (C{Cartesian})
816
826
  or C{None}.
817
- @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}),
818
- overriding this C{ltp}.
819
- @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and
820
- optional, additional B{C{Cartesian}} keyword arguments,
821
- ignored if C{B{Cartesian} is None}.
827
+ @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}), overriding
828
+ this C{ltp}.
829
+ @kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optional,
830
+ additional B{C{Cartesian}} keyword arguments, ignored if
831
+ C{B{Cartesian} is None}.
822
832
 
823
833
  @return: A B{C{Cartesian}} instance of if C{B{Cartesian} is None}, an
824
- L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
825
- with C{M=None}, always.
834
+ L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
835
+ C{M=None}, always.
826
836
 
827
- @raise TypeError: Invalid B{C{ltp}}, B{C{Cartesian}} or
828
- B{C{name_Cartesian_kwds}}.
837
+ @raise TypeError: Invalid B{C{ltp}}, B{C{Cartesian}} or B{C{name_Cartesian_kwds}}.
829
838
  '''
830
839
  ltp, kwds, n = self._ltp_kwds_name3(ltp, name_Cartesian_kwds)
831
840
  if Cartesian is None:
832
841
  t = ltp._local2ecef(self, nine=True)
833
842
  r = _xnamed(t, n) if n else t
834
843
  else:
835
- kwds = _xkwds(kwds, datum=ltp.datum)
836
- x, y, z = ltp._local2ecef(self)
837
- r = Cartesian(x, y, z, **kwds)
844
+ kwds = _xkwds(kwds, datum=ltp.datum)
845
+ xyz = ltp._local2ecef(self) # [:3]
846
+ r = Cartesian(*xyz, **kwds)
838
847
  return r
839
848
 
840
849
  def toEnu(self, Enu=None, **name_Enu_kwds):
841
850
  '''Get the local I{East, North, Up} (ENU) components.
842
851
 
843
852
  @kwarg Enu: Class to return ENU (L{Enu}) or C{None}.
844
- @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and
845
- optional, additional B{C{Enu}} keyword arguments,
846
- ignored if C{B{Enu} is None}.
853
+ @kwarg name_Enu_kwds: Optional C{B{name}=NN} (C{str}) and optional,
854
+ additional B{C{Enu}} keyword arguments, ignored if
855
+ C{B{Enu} is None}.
847
856
 
848
- @return: ENU as an L{Enu} instance or if C{B{Enu} is None},
849
- an L{Enu4Tuple}C{(east, north, up, ltp)}.
857
+ @return: ENU as an L{Enu} instance or if C{B{Enu} is None}, an
858
+ L{Enu4Tuple}C{(east, north, up, ltp)}.
850
859
 
851
860
  @raise TypeError: Invalid B{C{Enu}} or B{C{name_Enu_kwds}}.
852
861
  '''
@@ -855,20 +864,19 @@ class XyzLocal(_Vector3d):
855
864
  def toLatLon(self, LatLon=None, ltp=None, **name_LatLon_kwds):
856
865
  '''Get the geodetic C{(lat, lon, height)} coordinates if this local.
857
866
 
858
- @kwarg LatLon: Optional class to return C{(x, y, z)} (C{LatLon})
859
- or C{None}.
860
- @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}),
861
- overriding this ENU/NED/AER/XYZ's LTP.
862
- @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and
863
- optional, additional B{C{LatLon}} keyword arguments,
864
- ignored if C{B{LatLon} is None}.
867
+ @kwarg LatLon: Optional class to return C{(x, y, z)} (C{LatLon}) or
868
+ C{None}.
869
+ @kwarg ltp: Optional I{local tangent plane} (LTP) (L{Ltp}), overriding
870
+ this ENU/NED/AER/XYZ's LTP.
871
+ @kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optional,
872
+ additional B{C{LatLon}} keyword arguments, ignored if
873
+ C{B{LatLon} is None}.
865
874
 
866
875
  @return: An B{C{LatLon}} instance of if C{B{LatLon} is None}, an
867
- L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M,
868
- datum)} with C{M=None}, always.
876
+ L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
877
+ C{M=None}, always.
869
878
 
870
- @raise TypeError: Invalid B{C{ltp}}, B{C{LatLon}} or
871
- B{C{name_LatLon_kwds}}.
879
+ @raise TypeError: Invalid B{C{LatLon}}, B{C{ltp}} or B{C{name_LatLon_kwds}}.
872
880
  '''
873
881
  ltp, kwds, n = self._ltp_kwds_name3(ltp, name_LatLon_kwds)
874
882
  t = ltp._local2ecef(self, nine=True)
@@ -876,7 +884,7 @@ class XyzLocal(_Vector3d):
876
884
  r = _xnamed(t, n) if n else t
877
885
  else:
878
886
  kwds = _xkwds(kwds, height=t.height, datum=t.datum)
879
- r = LatLon(t.lat, t.lon, **kwds) # XXX ltp?
887
+ r = LatLon(t.lat, t.lon, **kwds) # XXX ltp?
880
888
  return r
881
889
 
882
890
  def toLocal9Tuple(self, M=False, **name):
@@ -885,25 +893,26 @@ class XyzLocal(_Vector3d):
885
893
  @kwarg M: Optionally include the rotation matrix (C{bool}).
886
894
  @kwarg name: Optional C{B{name}=NN} (C{str}).
887
895
 
888
- @return: L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp,
889
- ecef, M)} with C{ltp} this C{Ltp}, C{ecef} an
890
- L{Ecef9Tuple} and C{M} L{EcefMatrix} or C{None}.
896
+ @return: L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)}
897
+ with C{ltp} this C{Ltp}, C{ecef} an L{Ecef9Tuple} and C{M}
898
+ an L{EcefMatrix} or C{None}.
891
899
  '''
892
900
  ltp = self.ltp # see C{self.toLatLon}
893
901
  t = ltp._local2ecef(self, nine=True, M=M)
894
- return Local9Tuple(self.x, self.y, self.z, t.lat, t.lon, t.height,
895
- ltp, t, t.M, name=t._name__(name))
902
+ return Local9Tuple(self.x, self.y, self.z,
903
+ t.lat, t.lon, t.height,
904
+ ltp, t, t.M, name=t._name__(name))
896
905
 
897
906
  def toNed(self, Ned=None, **name_Ned_kwds):
898
907
  '''Get the local I{North, East, Down} (Ned) components.
899
908
 
900
909
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
901
- @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and
902
- optional, additional B{C{Ned}} keyword arguments,
903
- ignored if C{B{Ned} is None}.
910
+ @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optional,
911
+ additional B{C{Ned}} keyword arguments, ignored if
912
+ C{B{Ned} is None}.
904
913
 
905
- @return: NED as an L{Ned} instance or if C{B{Ned} is None},
906
- an L{Ned4Tuple}C{(north, east, down, ltp)}.
914
+ @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
915
+ L{Ned4Tuple}C{(north, east, down, ltp)}.
907
916
 
908
917
  @raise TypeError: Invalid B{C{Ned}} or B{C{name_Ned_kwds}}.
909
918
  '''
@@ -912,14 +921,14 @@ class XyzLocal(_Vector3d):
912
921
  def toXyz(self, Xyz=None, **name_Xyz_kwds):
913
922
  '''Get the local I{X, Y, Z} (XYZ) components.
914
923
 
915
- @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu},
916
- L{Ned}, L{Aer}) or C{None}.
917
- @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and
918
- optional, additional B{C{Xyz}} keyword arguments,
919
- ignored if C{B{Xyz} is None}.
924
+ @kwarg Xyz: Class to return XYZ (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer})
925
+ or C{None}.
926
+ @kwarg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
927
+ additional B{C{Xyz}} keyword arguments, ignored if
928
+ C{B{Xyz} is None}.
920
929
 
921
- @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None},
922
- an L{Xyz4Tuple}C{(x, y, z, ltp)}.
930
+ @return: XYZ as an B{C{Xyz}} instance or if C{B{Xyz} is None}, an
931
+ L{Xyz4Tuple}C{(x, y, z, ltp)}.
923
932
 
924
933
  @raise TypeError: Invalid B{C{Xyz}} or B{C{name_EXyz_kwds}}.
925
934
  '''
@@ -968,7 +977,7 @@ class XyzLocal(_Vector3d):
968
977
  # return self._z
969
978
 
970
979
 
971
- class Xyz4Tuple(_NamedTuple):
980
+ class Xyz4Tuple(_Abc4Tuple):
972
981
  '''4-Tuple C{(x, y, z, ltp)}, all in C{meter} except C{ltp}.
973
982
  '''
974
983
  _Names_ = (_x_, _y_, _z_, _ltp_)
@@ -977,11 +986,13 @@ class Xyz4Tuple(_NamedTuple):
977
986
  def _toXyz(self, Cls, Cls_kwds):
978
987
  '''(INTERNAL) Return C{Cls(..., **Cls_kwds)} instance.
979
988
  '''
980
- kwds = _name1__(Cls_kwds, _or_nameof=self)
981
- if issubclassof(Cls, XyzLocal):
982
- return Cls(*self, **kwds)
983
- else:
984
- return _4Tuple2Cls(self, Cls, kwds)
989
+ return self._2Cls(XyzLocal, Cls, Cls_kwds)
990
+
991
+ @property_RO
992
+ def xyz4(self):
993
+ '''Get the C{(x, y, z, ltp)} components (L{Xyz4Tuple}).
994
+ '''
995
+ return self
985
996
 
986
997
  @Property_RO
987
998
  def xyzLocal(self):
@@ -1049,7 +1060,7 @@ class Enu(XyzLocal):
1049
1060
 
1050
1061
  n, kwds = _name2__(name_Uvw_kwds, _or_nameof=self)
1051
1062
  return Uvw3Tuple(U, V, W, name=n) if Uvw is None else \
1052
- Uvw( U, V, W, name=n, **kwds)
1063
+ Uvw(U, V, W, name=n, **kwds)
1053
1064
 
1054
1065
  @Property_RO
1055
1066
  def xyzLocal(self):
@@ -1058,7 +1069,7 @@ class Enu(XyzLocal):
1058
1069
  return XyzLocal(*self.xyz4, name=self.name)
1059
1070
 
1060
1071
 
1061
- class Enu4Tuple(_NamedTuple):
1072
+ class Enu4Tuple(_Abc4Tuple):
1062
1073
  '''4-Tuple C{(east, north, up, ltp)}, in C{meter} except C{ltp}.
1063
1074
  '''
1064
1075
  _Names_ = (_east_, _north_, _up_, _ltp_)
@@ -1067,11 +1078,7 @@ class Enu4Tuple(_NamedTuple):
1067
1078
  def _toEnu(self, Cls, Cls_kwds):
1068
1079
  '''(INTERNAL) Return C{Cls(..., **Cls_kwds)} instance.
1069
1080
  '''
1070
- kwds = _name1__(Cls_kwds, _or_nameof=self)
1071
- if issubclassof(Cls, XyzLocal):
1072
- return Cls(*self, **kwds)
1073
- else:
1074
- return _4Tuple2Cls(self, Cls, kwds)
1081
+ return self._2Cls(Enu, Cls, Cls_kwds)
1075
1082
 
1076
1083
  @Property_RO
1077
1084
  def xyzLocal(self):
@@ -1174,7 +1181,7 @@ class Local9Tuple(_NamedTuple):
1174
1181
  @kwarg Aer: Class to return AER (L{Aer}) or C{None}.
1175
1182
  @kwarg name_Aer_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1176
1183
  additional B{L{Aer}} keyword arguments, ignored if
1177
- B{C{Aer}} is C{None}.
1184
+ C{B{Aer} is None}.
1178
1185
 
1179
1186
  @return: AER as an L{Aer} instance or if C{B{Aer} is None}, an
1180
1187
  L{Aer4Tuple}C{(azimuth, elevation, slantrange, ltp)}.
@@ -1238,7 +1245,7 @@ class Local9Tuple(_NamedTuple):
1238
1245
  @kwarg Ned: Class to return NED (L{Ned}) or C{None}.
1239
1246
  @kwarg name_Ned_kwds: Optional C{B{name}=NN} (C{str}) and optional,
1240
1247
  additional B{L{Ned}} keyword arguments, ignored if
1241
- B{C{Ned}} is C{None}.
1248
+ C{B{Ned} is None}.
1242
1249
 
1243
1250
  @return: NED as an L{Ned} instance or if C{B{Ned} is None}, an
1244
1251
  L{Ned4Tuple}C{(north, east, down, ltp)}.
@@ -1335,7 +1342,7 @@ class Uvw(_Vector3d):
1335
1342
 
1336
1343
  n, kwds = _name2__(name_Enu_kwds, _or_nameof=self)
1337
1344
  return Enu4Tuple(E, N, U, name=n) if Enu is None else \
1338
- Enu( E, N, U, name=n, **kwds)
1345
+ Enu(E, N, U, name=n, **kwds)
1339
1346
 
1340
1347
  u = Vector3d.x
1341
1348
 
@@ -1382,7 +1389,7 @@ class Los(Aer):
1382
1389
  '''Get this LOS' I{target} (UVW) components from a location.
1383
1390
 
1384
1391
  @arg location: The geodetic (C{LatLon}) or geocentric (C{Cartesian},
1385
- L{Vector3d}) location from where to cast the L{Los}.
1392
+ L{Vector3d}) location from where to cast this LOS.
1386
1393
 
1387
1394
  @see: Method L{Enu.toUvw} for further details.
1388
1395
  '''
@@ -1414,7 +1421,7 @@ class ChLV9Tuple(Local9Tuple):
1414
1421
  def EN2_LV95(self):
1415
1422
  '''Get the I{falsed Swiss (E_LV95, N_LV95)} easting and northing (L{ChLVEN2Tuple}).
1416
1423
  '''
1417
- return ChLVEN2Tuple(*_MODS.ltp.ChLV.false2(self.Y, self.X, True), name=self.name)
1424
+ return ChLVEN2Tuple(*_ltp.ChLV.false2(self.Y, self.X, True), name=self.name)
1418
1425
 
1419
1426
  @Property_RO
1420
1427
  def h_LV03(self):
@@ -1432,19 +1439,19 @@ class ChLV9Tuple(Local9Tuple):
1432
1439
  def isChLV(self):
1433
1440
  '''Is this a L{ChLV}-generated L{ChLV9Tuple}?.
1434
1441
  '''
1435
- return self.ltp.__class__ is _MODS.ltp.ChLV
1442
+ return self.ltp.__class__ is _ltp.ChLV
1436
1443
 
1437
1444
  @property_RO
1438
1445
  def isChLVa(self):
1439
1446
  '''Is this a L{ChLVa}-generated L{ChLV9Tuple}?.
1440
1447
  '''
1441
- return self.ltp.__class__ is _MODS.ltp.ChLVa
1448
+ return self.ltp.__class__ is _ltp.ChLVa
1442
1449
 
1443
1450
  @property_RO
1444
1451
  def isChLVe(self):
1445
1452
  '''Is this a L{ChLVe}-generated L{ChLV9Tuple}?.
1446
1453
  '''
1447
- return self.ltp.__class__ is _MODS.ltp.ChLVe
1454
+ return self.ltp.__class__ is _ltp.ChLVe
1448
1455
 
1449
1456
  @Property_RO
1450
1457
  def N_LV95(self):
@@ -1486,7 +1493,7 @@ class ChLV9Tuple(Local9Tuple):
1486
1493
  def yx2_LV03(self):
1487
1494
  '''Get the B{falsed} I{Swiss (y_LV03, x_LV03)} easting and northing (L{ChLVyx2Tuple}).
1488
1495
  '''
1489
- return ChLVyx2Tuple(*_MODS.ltp.ChLV.false2(self.Y, self.X, False), name=self.name)
1496
+ return ChLVyx2Tuple(*_ltp.ChLV.false2(self.Y, self.X, False), name=self.name)
1490
1497
 
1491
1498
  @Property_RO
1492
1499
  def z(self):
@@ -1507,7 +1514,7 @@ class ChLVYX2Tuple(_NamedTuple):
1507
1514
 
1508
1515
  @see: Function L{ChLV.false2} for more information.
1509
1516
  '''
1510
- return _MODS.ltp.ChLV.false2(*self, LV95=LV95, name=self.name)
1517
+ return _ltp.ChLV.false2(*self, LV95=LV95, name=self.name)
1511
1518
 
1512
1519
 
1513
1520
  class ChLVEN2Tuple(_NamedTuple):
@@ -1522,7 +1529,7 @@ class ChLVEN2Tuple(_NamedTuple):
1522
1529
 
1523
1530
  @see: Function L{ChLV.unfalse2} for more information.
1524
1531
  '''
1525
- return _MODS.ltp.ChLV.unfalse2(*self, LV95=True, name=self.name)
1532
+ return _ltp.ChLV.unfalse2(*self, LV95=True, name=self.name)
1526
1533
 
1527
1534
 
1528
1535
  class ChLVyx2Tuple(_NamedTuple):
@@ -1537,7 +1544,7 @@ class ChLVyx2Tuple(_NamedTuple):
1537
1544
 
1538
1545
  @see: Function L{ChLV.unfalse2} for more information.
1539
1546
  '''
1540
- return _MODS.ltp.ChLV.unfalse2(*self, LV95=False, name=self.name)
1547
+ return _ltp.ChLV.unfalse2(*self, LV95=False, name=self.name)
1541
1548
 
1542
1549
 
1543
1550
  class Footprint5Tuple(_NamedTuple):
@@ -1571,7 +1578,7 @@ class Footprint5Tuple(_NamedTuple):
1571
1578
 
1572
1579
  @see: Methods L{XyzLocal.toLatLon} and L{Footprint5Tuple.xyzLocal5}.
1573
1580
  '''
1574
- ltp = _MODS.ltp._xLtp(ltp, self.center.ltp) # PYCHOK .center
1581
+ ltp = _ltp._xLtp(ltp, self.center.ltp) # PYCHOK .center
1575
1582
  kwds = _name1__(name_LatLon_kwds, _or_nameof=self)
1576
1583
  kwds = _xkwds(kwds, ltp=ltp, LatLon=LatLon)
1577
1584
  return Footprint5Tuple(t.toLatLon(**kwds) for t in self.xyzLocal5())
@@ -1589,12 +1596,12 @@ class Footprint5Tuple(_NamedTuple):
1589
1596
  if ltp is None:
1590
1597
  p = self
1591
1598
  else:
1592
- p = _MODS.ltp._xLtp(ltp)
1599
+ p = _ltp._xLtp(ltp)
1593
1600
  p = tuple(Xyz4Tuple(t.x, t.y, t.z, p) for t in self)
1594
1601
  return Footprint5Tuple(t.xyzLocal for t in p)
1595
1602
 
1596
1603
 
1597
- __all__ += _ALL_DOCS(_NamedAerNed)
1604
+ __all__ += _ALL_DOCS(_AbcBase)
1598
1605
 
1599
1606
  # **) MIT License
1600
1607
  #