pygeodesy 25.4.25__py2.py3-none-any.whl → 25.5.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.
pygeodesy/latlonBase.py CHANGED
@@ -17,12 +17,13 @@ from pygeodesy.constants import EPS, EPS0, EPS1, EPS4, INT0, R_M, \
17
17
  from pygeodesy.datums import _spherical_datum
18
18
  from pygeodesy.dms import F_D, F_DMS, latDMS, lonDMS, parse3llh
19
19
  # from pygeodesy.ecef import EcefKarney # _MODS
20
+ from pygeodesy.ecefLocals import _EcefLocal
20
21
  from pygeodesy.errors import _AttributeError, IntersectionError, \
21
22
  _incompatible, _IsnotError, _TypeError, \
22
23
  _ValueError, _xattr, _xdatum, _xError, \
23
24
  _xkwds, _xkwds_get, _xkwds_item2, _xkwds_not
24
25
  # from pygeodesy.fmath import favg # _MODS
25
- # from pygeodesy import formy as _formy # .MODS.into
26
+ # from pygeodesy import formy as _formy # _MODS.into
26
27
  from pygeodesy.internals import _passarg, typename
27
28
  from pygeodesy.interns import NN, _COMMASPACE_, _concentric_, _height_, \
28
29
  _intersection_, _LatLon_, _m_, _negative_, \
@@ -30,7 +31,7 @@ from pygeodesy.interns import NN, _COMMASPACE_, _concentric_, _height_, \
30
31
  # from pygeodesy.iters import PointsIter, points2 # _MODS
31
32
  # from pygeodesy.karney import Caps # _MODS
32
33
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
33
- from pygeodesy.named import _name2__, _NamedBase, _NamedLocal, Fmt
34
+ from pygeodesy.named import _name2__, _NamedBase, Fmt
34
35
  from pygeodesy.namedTuples import Bounds2Tuple, LatLon2Tuple, PhiLam2Tuple, \
35
36
  Trilaterate5Tuple, Vector3Tuple
36
37
  # from pygeodesy.nvectorBase import _N_vector_ # _MODS
@@ -48,12 +49,12 @@ from contextlib import contextmanager
48
49
  from math import asin, cos, degrees, fabs, radians
49
50
 
50
51
  __all__ = _ALL_LAZY.latlonBase
51
- __version__ = '25.04.21'
52
+ __version__ = '25.04.28'
52
53
 
53
54
  _formy = _MODS.into(formy=__name__)
54
55
 
55
56
 
56
- class LatLonBase(_NamedBase, _NamedLocal):
57
+ class LatLonBase(_NamedBase, _EcefLocal):
57
58
  '''(INTERNAL) Base class for ellipsoidal and spherical C{satLon}s.
58
59
  '''
59
60
  _clipid = INT0 # polygonal clip, see .booleans
@@ -411,7 +412,7 @@ class LatLonBase(_NamedBase, _NamedLocal):
411
412
 
412
413
  @raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}} item.
413
414
  '''
414
- t = self._Ltp._local2ecef(delta, nine=True)
415
+ t = self._ltp._local2ecef(delta, nine=True) # _EcefLocal._ltp
415
416
  return t.toLatLon(LatLon=LatLon, **_xkwds(LatLon_kwds, name=self.name))
416
417
 
417
418
  def _distanceTo(self, func, other, radius=None, **kwds):
@@ -901,6 +902,8 @@ class LatLonBase(_NamedBase, _NamedLocal):
901
902
  _update_all(self)
902
903
  self._lon = lon
903
904
 
905
+ # _ltp = _EcefLocal._ltp(self)
906
+
904
907
  def nearestOn6(self, points, closed=False, height=None, wrap=False):
905
908
  '''Locate the point on a path or polygon closest to this point.
906
909
 
pygeodesy/lazily.py CHANGED
@@ -35,9 +35,9 @@ from pygeodesy.internals import _caller3, _envPYGEODESY, _headof, printf, _tailo
35
35
  # _MODS_Base, _MODS.sys_version_info2
36
36
  from pygeodesy.interns import _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, _DALL_, \
37
37
  _DMAIN_, _doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
38
- _immutable_, _line_, _module_, NN, _no_, _not_, _or_, \
38
+ _HASH_, _immutable_, _line_, _module_, NN, _no_, _not_, \
39
39
  _pygeodesy_, _pygeodesy_abspath_, _SPACE_, _SUB_PACKAGES, \
40
- _UNDER_, _version_, _sys, _intern # function, _1_, _HASH_
40
+ _or_, _UNDER_, _version_, _sys, _intern # function, _1_
41
41
  try:
42
42
  from importlib import import_module
43
43
  except ImportError as x: # Python 2.6-
@@ -47,6 +47,7 @@ except ImportError as x: # Python 2.6-
47
47
  _a0 = () # PYCHOK empty tuple
48
48
  _asSPACED_ = ' as '
49
49
  _FOR_DOCS = _envPYGEODESY('FOR_DOCS') # for epydoc ...
50
+ _imported_ = 'imported'
50
51
  _init__all__ = _FOR_DOCS or _envPYGEODESY('_init__all__', _DALL_) == _DALL_ # PYCHOK exported
51
52
  _lazily_ = 'lazily'
52
53
  _PYTHON_X_DEV = getattr(_sys.flags, 'dev_mode', False) # PYCHOK Python 3.2+
@@ -215,6 +216,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
215
216
  'parseDDDMMSS', 'parseDMS', 'parseDMS2', 'parse3llh', 'parseRad', 'precision', 'toDMS'),
216
217
  ecef=_a('EcefError', 'EcefFarrell21', 'EcefFarrell22', 'EcefKarney', 'EcefMatrix',
217
218
  'EcefSudano', 'Ecef9Tuple', 'EcefVeness', 'EcefYou'),
219
+ ecefLocals=_a(), # module only
218
220
  elevations=_a('Elevation2Tuple', 'GeoidHeight2Tuple',
219
221
  'elevation2', 'geoidHeight2'),
220
222
  ellipsoidalBase=_a(), # module only
@@ -239,7 +241,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
239
241
  'crosserrors', 'exception_chaining', 'isError', 'limiterrors', 'rangerrors'),
240
242
  etm=_a('Etm', 'ETMError', 'ExactTransverseMercator',
241
243
  'parseETM5', 'toEtm8'),
242
- fmath=_a('Fdot', 'Fhorner', 'Fhypot', 'Fpolynomial', 'Fpowers', 'Fcbrt', 'Froot', 'Fsqrt',
244
+ fmath=_a('Fdot', 'Fdot_', 'Fhorner', 'Fhypot', 'Fpolynomial', 'Fpowers', 'Fcbrt', 'Froot', 'Fsqrt',
243
245
  'bqrt', 'cbrt', 'cbrt2', 'euclid', 'euclid_',
244
246
  'facos1', 'fasin1', 'fatan', 'fatan1', 'fatan2', 'favg',
245
247
  'fdot', 'fdot_', 'fdot3', 'fma', 'fmean', 'fmean_', 'fhorner', 'fidw', 'f2mul_',
@@ -477,19 +479,17 @@ class _ALL_MODS(_internals._MODS_Base):
477
479
  return _sys.modules.get(name, None)
478
480
 
479
481
  def into(self, **mod_DNAME):
480
- '''Lazily import module C{mod} into module C{_DNAME_}
481
- and set C{_DNAME_._mod} to module C{mod}, I{once}.
482
+ '''Deferred import of module C{mod} into module C{_DNAME_}
483
+ and overwrite C{_DNAME_._mod} to module C{mod}, I{once}
484
+ at the first access of an attribute of module C{mod}.
482
485
  '''
486
+ # assert len(mod_DNAME) == 1
487
+ # mod, dun = mod_DNAME.popitem()
488
+
483
489
  class _Into(object):
484
490
 
485
491
  def __getattr__(unused, name):
486
- mod, dun = self.errors._xkwds_item2(mod_DNAME)
487
- _mod = _UNDER_(NN, mod)
488
- d = self.getmodule(dun) # '__main__' OK
489
- i = _getmodattr(d, _mod, dun)
490
- assert isinstance(i, _Into)
491
- m = self.getmodule(mod)
492
- setattr(d, _mod, m) # overwrite C{d._mod}
492
+ m = _getmodinto(mod_DNAME, _Into)
493
493
  return getattr(m, name)
494
494
 
495
495
  return _Into()
@@ -510,7 +510,7 @@ class _ALL_MODS(_internals._MODS_Base):
510
510
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
511
511
 
512
512
  __all__ = _ALL_LAZY.lazily
513
- __version__ = '25.04.21'
513
+ __version__ = '25.04.30'
514
514
 
515
515
 
516
516
  def _ALL_OTHER(*objs):
@@ -599,11 +599,29 @@ def _getmodattr(m, name, mod=_pygeodesy_):
599
599
  try:
600
600
  return getattr(m, name)
601
601
  except AttributeError:
602
- name = _DOT_(mod, name)
602
+ name = _DOT_(typename(m, mod), name)
603
603
  # <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
604
604
  raise LazyAttributeError(_no_(_attribute_), txt=name)
605
605
 
606
606
 
607
+ def _getmodinto(mod_DNAME, *Intos):
608
+ '''(INTERNAL) Core of C{_ALL_MODS.into}.
609
+ '''
610
+ _MODS = _ALL_MODS
611
+ mod, dun = _MODS.errors._xkwds_item2(mod_DNAME)
612
+ _mod = _UNDER_(NN, mod)
613
+ d = _MODS.getmodule(dun) # '__main__' OK
614
+ i = _getmodattr(d, _mod, dun)
615
+ assert isinstance(i, Intos)
616
+ m = _MODS.getmodule(mod)
617
+ setattr(d, _mod, m) # overwrite C{d._mod}
618
+ if isLazy > 1:
619
+ t = _SPACE_(_HASH_, _imported_, m.__name__) # typename(m)
620
+ _hash_imported(t, _MODS.into.__name__)
621
+ assert getattr(d, _mod, None) is m
622
+ return m
623
+
624
+
607
625
  def _getmodule(name, *parent):
608
626
  '''(INTERNAL) Wrapper for C{import_module}.
609
627
  '''
@@ -614,6 +632,18 @@ def _getmodule(name, *parent):
614
632
  raise LazyImportError(_no_(_module_), txt=name)
615
633
 
616
634
 
635
+ def _hash_imported(t, by_into, up=3):
636
+ '''(INTERNAL) Helper for C{_lazy_import2} and C{_ALL_MODS.into}.
637
+ '''
638
+ if isLazy > 2:
639
+ try: # see C{internals._caller3}
640
+ _, f, s = _caller3(up)
641
+ t = _SPACE_(t, by_into, f, _line_, s)
642
+ except ValueError:
643
+ pass
644
+ printf(t) # XXX print
645
+
646
+
617
647
  # def _lazy_attributes(DUNDER_name):
618
648
  # '''(INTERNAL) Return a function to C{B{__name__}.__getattr__(attr)}
619
649
  # on lazily imported modules and sub-modules.
@@ -666,7 +696,7 @@ def _lazy_import2(pack): # MCCABE 14
666
696
  package, parent = _lazy_init2(pack) # _pygeodesy_
667
697
 
668
698
  _DPACKAGE_ = '__package__'
669
- _lazily_imported_ = _SPACE_(_interns._HASH_, _lazily_, 'imported', parent)
699
+ _lazily_imported_ = _SPACE_(_HASH_, _lazily_, _imported_, parent)
670
700
 
671
701
  sub_packages = set((parent, NN) + tuple(
672
702
  _DOT_(parent, s) for s in _SUB_PACKAGES))
@@ -703,13 +733,7 @@ def _lazy_import2(pack): # MCCABE 14
703
733
  t = _DOT_(_lazily_imported_, name)
704
734
  if mod and _tailof(mod) != name:
705
735
  t = _SPACE_(t, _from_, _DOT_(NN, mod))
706
- if isLazy > 2:
707
- try: # see C{_caller3}
708
- _, f, s = _caller3(2)
709
- t = _SPACE_(t, _by_, f, _line_, s)
710
- except ValueError:
711
- pass
712
- printf(t) # XXX print
736
+ _hash_imported(t, _by_)
713
737
 
714
738
  return v # __getattr__
715
739
 
pygeodesy/ltp.py CHANGED
@@ -23,7 +23,7 @@ from pygeodesy.ecef import _EcefBase, EcefKarney, Ecef9Tuple, _llhn4, \
23
23
  _xyzn4, _WGS84
24
24
  from pygeodesy.errors import _NotImplementedError, _ValueError, _xattr, \
25
25
  _xkwds, _xkwds_get, _xkwds_pop2
26
- from pygeodesy.fmath import fabs, fdot, fdot_, Fhorner
26
+ from pygeodesy.fmath import fabs, fdot, Fdot_, fdot_, Fhorner
27
27
  from pygeodesy.fsums import _floor, fsumf_
28
28
  # from pygeodesy.internals import typename # from .basics
29
29
  from pygeodesy.interns import _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, _M_, \
@@ -45,7 +45,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
45
45
  # from math import fabs, floor as _floor # from .fmath, .fsums
46
46
 
47
47
  __all__ = _ALL_LAZY.ltp
48
- __version__ = '25.04.14'
48
+ __version__ = '25.05.01'
49
49
 
50
50
  _height0_ = _height_ + _0_
51
51
  _narrow_ = 'narrow'
@@ -63,15 +63,18 @@ class Attitude(_NamedBase):
63
63
  def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, **name):
64
64
  '''New L{Attitude}.
65
65
 
66
- @kwarg alt_attitude: Altitude (C{meter}) above earth or previous attitude
66
+ @kwarg alt_attitude: Altitude (C{meter}) above earth or a previous attitude
67
67
  (L{Attitude} or L{Attitude4Tuple}) with the C{B{alt}itude},
68
68
  B{C{tilt}}, B{C{yaw}} and B{C{roll}}.
69
69
  @kwarg tilt: Pitch, elevation from horizontal (C{degrees180}), negative down
70
- (clockwise rotation along and around the x- or East axis).
70
+ (clockwise rotation along and around the x- or East axis), iff
71
+ B{C{alt_attitude}} is C{meter}, ignored otherwise.
71
72
  @kwarg yaw: Bearing, heading (compass C{degrees360}), clockwise from North
72
- (counter-clockwise rotation along and around the z- or Up axis).
73
+ (counter-clockwise rotation along and around the z- or Up axis)
74
+ iff B{C{alt_attitude}} is C{meter}, ignored otherwise.
73
75
  @kwarg roll: Roll, bank (C{degrees180}), positive to the right and down
74
- (clockwise rotation along and around the y- or North axis).
76
+ (clockwise rotation along and around the y- or North axis), iff
77
+ B{C{alt_attitude}} is C{meter}, ignored otherwise.
75
78
  @kwarg name: Optional C{B{name}=NN} C{str}).
76
79
 
77
80
  @raise AttitudeError: Invalid B{C{alt_attitude}}, B{C{tilt}}, B{C{yaw}} or
@@ -146,8 +149,10 @@ class Attitude(_NamedBase):
146
149
 
147
150
  @arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Cartesian},
148
151
  L{Vector3d} or L{Vector3Tuple}).
149
- @kwarg y: Y component of vector (C{scalar}), same units as B{C{x}}.
150
- @kwarg z: Z component of vector (C{scalar}), same units as B{C{x}}.
152
+ @kwarg y: Y component of vector (C{scalar}), same units as C{scalar} B{C{x}},
153
+ ignored otherwise.
154
+ @kwarg z: Z component of vector (C{scalar}), same units as C{sclar} B{C{x}},
155
+ ignored otherwise.
151
156
  @kwarg Vector: Class to return transformed point (C{Cartesian}, L{Vector3d}
152
157
  or C{Vector3Tuple}) or C{None}.
153
158
  @kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
@@ -223,7 +228,7 @@ class Attitude(_NamedBase):
223
228
  _update_all(self)
224
229
  self._yaw = y
225
230
 
226
- bearing = heading = yaw
231
+ bearing = heading = yaw # azimuth
227
232
 
228
233
 
229
234
  class AttitudeError(_ValueError):
@@ -271,11 +276,14 @@ class Frustum(_NamedBase):
271
276
  an attitude (L{Attitude} or L{Attitude4Tuple}) with the
272
277
  C{B{alt}itude}, B{C{tilt}}, B{C{yaw}} and B{C{roll}}.
273
278
  @kwarg tilt: Pitch, elevation from horizontal (C{degrees}), negative down
274
- (clockwise rotation along and around the x- or East axis).
279
+ (clockwise rotation along and around the x- or East axis) iff
280
+ B{C{alt_attitude}} is C{meter}, ignored otherwise.
275
281
  @kwarg yaw: Bearing, heading (compass C{degrees}), clockwise from North
276
- (counter-clockwise rotation along and around the z- or Up axis).
282
+ (counter-clockwise rotation along and around the z- or Up axis)
283
+ iff B{C{alt_attitude}} is C{meter}, ignored otherwise.
277
284
  @kwarg roll: Roll, bank (C{degrees}), positive to the right and down
278
- (clockwise rotation along and around the y- or North axis).
285
+ (clockwise rotation along and around the y- or North axis) iff
286
+ B{C{alt_attitude}} is C{meter}, ignored otherwise.
279
287
  @kwarg z: Optional height of the footprint (C{meter}) above I{local tangent plane}.
280
288
  @kwarg ltp: The I{local tangent plane} (L{Ltp}), overriding this
281
289
  frustum's C{ltp}.
@@ -463,7 +471,7 @@ class LocalCartesian(_NamedBase):
463
471
  '''
464
472
  return self._ecef
465
473
 
466
- def _ecef2local(self, ecef, Xyz, name_Xyz_kwds):
474
+ def _ecef2local(self, ecef, Xyz, name_Xyz_kwds): # in _EcefLocal._Ltp_ecef2local
467
475
  '''(INTERNAL) Convert geocentric/geodetic to local, like I{forward}.
468
476
 
469
477
  @arg ecef: Geocentric (and geodetic) (L{Ecef9Tuple}).
@@ -504,10 +512,11 @@ class LocalCartesian(_NamedBase):
504
512
 
505
513
  @arg latlonh: Either a C{LatLon}, L{Ltp}, L{Ecef9Tuple} or C{scalar}
506
514
  (geodetic) latitude (C{degrees}).
507
- @kwarg lon: Optional C{scalar} (geodetic) longitude for C{scalar}
508
- B{C{latlonh}} (C{degrees}).
515
+ @kwarg lon: Optional C{scalar} (geodetic) longitude (C{degrees}) iff
516
+ B{C{latlonh}} is C{scalar}, ignored otherwise.
509
517
  @kwarg height: Optional height (C{meter}, conventionally) perpendicular
510
- to and above (or below) the ellipsoid's surface.
518
+ to and above (or below) the ellipsoid's surface, iff
519
+ B{C{latlonh}} is C{scalar}, ignored othewrise.
511
520
  @kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix},
512
521
  iff available (C{bool}).
513
522
  @kwarg name: Optional C{B{name}=NN} (C{str}).
@@ -591,7 +600,7 @@ class LocalCartesian(_NamedBase):
591
600
  return self._t0.M
592
601
 
593
602
  def reset(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
594
- '''Reset this converter, see L{LocalCartesian.__init__} for more details.
603
+ '''Reset this converter, see L{LocalCartesian.__init__} for further details.
595
604
  '''
596
605
  _, name = _xkwds_pop2(lon00_name, lon00=None) # PYCHOK get **name
597
606
  if isinstance(latlonh0, LocalCartesian):
@@ -621,8 +630,10 @@ class LocalCartesian(_NamedBase):
621
630
 
622
631
  @arg xyz: A I{local} (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer}, L{Local9Tuple}) or
623
632
  local C{x} coordinate (C{scalar}).
624
- @kwarg y: Local C{y} coordinate for C{scalar} B{C{xyz}} and B{C{z}} (C{meter}).
625
- @kwarg z: Local C{z} coordinate for C{scalar} B{C{xyz}} and B{C{y}} (C{meter}).
633
+ @kwarg y: Local C{y} coordinate (C{meter}), iff B{C{xyz}} is C{scalar},
634
+ ignored otherwise.
635
+ @kwarg z: Local C{z} coordinate (C{meter}), iff B{C{xyz}} is C{scalar},
636
+ ignored otherwise.
626
637
  @kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix}, iff
627
638
  available (C{bool}).
628
639
  @kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
@@ -734,18 +745,18 @@ class _ChLV(object):
734
745
  '''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
735
746
 
736
747
  @arg latlonh: Either a C{LatLon}, L{Ltp} or C{scalar} (geodetic) latitude (C{degrees}).
737
- @kwarg lon: Optional, C{scalar} (geodetic) longitude for C{scalar} B{C{latlonh}} (C{degrees}).
748
+ @kwarg lon: Optional, C{scalar} (geodetic) longitude (C{degrees}) iff B{C{latlonh}} is
749
+ C{scalar}, ignored otherwise.
738
750
  @kwarg height: Optional, height, vertically above (or below) the surface of the ellipsoid
739
- (C{meter}) for C{scalar} B{C{latlonh}} and B{C{lon}}.
751
+ (C{meter}) iff B{C{latlonh}} and B{C{lon}} are C{scalar}, ignored otherwise.
740
752
  @kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
741
- for C{ChLV} only, C{None} otherwise (C{bool}).
753
+ and for C{ChLV} only, C{None} otherwise (C{bool}).
742
754
  @kwarg name: Optional C{B{name}=NN} (C{str}).
743
755
 
744
756
  @return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
745
757
  I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
746
- C{lon} and C{height}, this C{ChLV*} instance and C{ecef} (L{Ecef9Tuple}) at
747
- I{Bern, Ch} and rotation matrix C{M}. The returned C{ltp} is this C{ChLV},
748
- C{ChLVa} or C{ChLVe} instance.
758
+ C{lon} and C{height}, C{ecef} (L{Ecef9Tuple}) at I{Bern, Ch}, rotation matrix
759
+ C{M} and C{ltp} this C{ChLV}, C{ChLVa} or C{ChLVe} instance.
749
760
 
750
761
  @raise LocalError: Invalid or non-C{scalar} B{C{latlonh}}, B{C{lon}} or B{C{height}}.
751
762
  '''
@@ -756,18 +767,18 @@ class _ChLV(object):
756
767
 
757
768
  @arg enh_: A Swiss projection (L{ChLV9Tuple}) or the C{scalar}, falsed I{Swiss E_LV95}
758
769
  or I{y_LV03} easting (C{meter}).
759
- @kwarg n: Falsed I{Swiss N_LV85} or I{x_LV03} northing for C{scalar} B{C{enh_}} and
760
- B{C{h_}} (C{meter}).
761
- @kwarg h_: I{Swiss h'} height for C{scalar} B{C{enh_}} and B{C{n}} (C{meter}).
770
+ @kwarg n: Falsed I{Swiss N_LV85} or I{x_LV03} northing (C{meter}) iff B{C{enh_}} is
771
+ C{scalar}, ignored otherwise.
772
+ @kwarg h_: I{Swiss h'} height (C{meter}) iff B{C{enh_}} and B{C{n}} are C{scalar},
773
+ ignored otherwise.
762
774
  @kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
763
- for C{ChLV} only, C{None} otherwise (C{bool}).
775
+ and for C{ChLV} only, C{None} otherwise (C{bool}).
764
776
  @kwarg name: Optional C{B{name}=NN} (C{str}).
765
777
 
766
778
  @return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
767
779
  I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
768
- C{lon} and C{height}, this C{ChLV*} instance and C{ecef} (L{Ecef9Tuple}) at
769
- I{Bern, Ch} and rotation matrix C{M}. The returned C{ltp} is this C{ChLV},
770
- C{ChLVa} or C{ChLVe} instance.
780
+ C{lon} and C{height}, C{ecef} (L{Ecef9Tuple}) at I{Bern, Ch}, rotation matrix
781
+ C{M} and C{ltp} this C{ChLV}, C{ChLVa} or C{ChLVe} instance.
771
782
 
772
783
  @raise LocalError: Invalid or non-C{scalar} B{C{enh_}}, B{C{n}} or B{C{h_}}.
773
784
  '''
@@ -818,7 +829,7 @@ class _ChLV(object):
818
829
  def _YXh_n4(self, enh_, n, h_, **name):
819
830
  '''(INTERNAL) Helper for C{ChLV*.reverse}.
820
831
  '''
821
- Y, X, h_, name = _xyzn4(enh_, n, h_, ChLV9Tuple,
832
+ Y, X, h_, name = _xyzn4(enh_, n, h_, (ChLV9Tuple,),
822
833
  _xyz_y_z_names=self._enh_n_h, **name)
823
834
  if isinstance(enh_, ChLV9Tuple):
824
835
  Y, X = enh_.Y, enh_.X
@@ -974,15 +985,15 @@ class ChLVa(_ChLV, LocalCartesian):
974
985
  a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
975
986
  ab_d, a2, b2 = ChLV._ab_d, a**2, b**2
976
987
 
977
- lat = fdot_(3.238272, b,
988
+ lat = Fdot_(3.238272, b,
978
989
  -0.270978, a2,
979
990
  -0.002528, b2,
980
991
  -0.0447, a2 * b,
981
- -0.014, b2 * b, start=16.9023892) / ab_d
982
- lon = fdot_(4.728982, a,
992
+ -0.014, b2 * b, start=16.9023892).fover(ab_d)
993
+ lon = Fdot_(4.728982, a,
983
994
  0.791484, a * b,
984
995
  0.1306, a * b2,
985
- -0.0436, a * a2, start=2.6779094) / ab_d
996
+ -0.0436, a * a2, start=2.6779094).fover(ab_d)
986
997
  return self._ChLV9Tuple(False, M, n, Y, X, h_, lat, lon, h)
987
998
 
988
999
 
@@ -997,8 +1008,8 @@ class ChLVe(_ChLV, LocalCartesian):
997
1008
  argument C{B{gamma}=False} to approximate the I{meridian convergence}.
998
1009
  If C{B{gamma}=True} a 2-tuple C{(t, gamma)} is returned with C{t} the
999
1010
  usual result (C{ChLV9Tuple}) and C{gamma}, the I{meridian convergence}
1000
- (decimal C{degrees}). To convert C{gamma} to C{grades} or C{gons},
1001
- use function L{pygeodesy.degrees2grades}.
1011
+ (decimal C{degrees}). To convert C{gamma} to C{grades} or C{gons}, use
1012
+ function L{pygeodesy.degrees2grades}.
1002
1013
 
1003
1014
  @see: Older U{references<https://GitHub.com/alphasldiallo/Swisstopo-WGS84-LV03>}.
1004
1015
  '''
@@ -1070,20 +1081,6 @@ def _fov_2(**fov):
1070
1081
  raise LocalError(txt=t, **fov)
1071
1082
 
1072
1083
 
1073
- def _toLocal(inst, ltp, Xyz, Xyz_kwds):
1074
- '''(INTERNAL) Helper for C{CartesianBase.toAer}, C{CartesianBase.toEnu},
1075
- C{CartesianBase.toLocal}, C{CartesianBase.toNed} and C{latLonBase.toLocal}.
1076
- '''
1077
- return _xLtp(ltp, inst._Ltp)._ecef2local(inst._ecef9, Xyz, Xyz_kwds)
1078
-
1079
-
1080
- def _toLtp(inst, Ecef, ecef9, name):
1081
- '''(INTERNAL) Helper for C{CartesianBase.toLtp}, C{ecef.toLtp} and C{latLonBase.toLtp}.
1082
- '''
1083
- return inst._Ltp if (not name) and _isin(Ecef, None, inst.Ecef) else \
1084
- Ltp(ecef9, ecef=Ecef(inst.datum), name=inst._name__(name))
1085
-
1086
-
1087
1084
  def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
1088
1085
  '''Convert an attitude pose into a (3-D) direction vector.
1089
1086
 
pygeodesy/ltpTuples.py CHANGED
@@ -11,12 +11,13 @@ 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 # _MODS
14
+ from pygeodesy.basics import issubclassof, typename
15
15
  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
19
  from pygeodesy.fmath import fdot_, hypot, hypot_
20
+ # rom pygeodesy.internals import typename # from .basics
20
21
  from pygeodesy.interns import NN, _4_, _azimuth_, _center_, _COMMASPACE_, \
21
22
  _ecef_, _elevation_, _height_, _lat_, _lon_, \
22
23
  _ltp_, _M_, _name_, _up_, _X_, _x_, _xyz_, \
@@ -37,7 +38,7 @@ from pygeodesy.vector3d import Vector3d
37
38
  # from math import cos, radians # from .utily
38
39
 
39
40
  __all__ = _ALL_LAZY.ltpTuples
40
- __version__ = '24.12.06'
41
+ __version__ = '25.05.01'
41
42
 
42
43
  _aer_ = 'aer'
43
44
  _alt_ = 'alt'
@@ -48,6 +49,7 @@ _h__ = 'h_'
48
49
  _ned_ = 'ned'
49
50
  _north_ = 'north'
50
51
  _local_ = 'local'
52
+ _ltp = _MODS.into(ltp=__name__)
51
53
  _roll_ = 'roll'
52
54
  _slantrange_ = 'slantrange'
53
55
  _tilt_ = 'tilt'
@@ -158,25 +160,25 @@ class _Abc4Tuple(_NamedTuple):
158
160
  def _2Cls(self, Abc, Cls, Cls_kwds):
159
161
  '''(INTERNAL) Convert 4-Tuple to C{Cls} instance.
160
162
  '''
163
+ _isc = issubclassof
161
164
  kwds = _name1__(Cls_kwds, _or_nameof=self)
162
- _is = _MODS.basics.issubclassof
163
165
  if Cls is None:
164
166
  n, _ = _name2__(Cls_kwds)
165
167
  r = self.copy(name=n) if n else self
166
- elif _is(Cls, Abc):
168
+ elif _isc(Cls, Abc):
167
169
  r = Cls(*self, **kwds)
168
- elif _is(Cls, Aer):
170
+ elif _isc(Cls, Aer):
169
171
  r = self.xyzLocal.toAer(**_xkwds(kwds, Aer=Cls))
170
- elif _is(Cls, Enu): # PYCHOK no cover
172
+ elif _isc(Cls, Enu): # PYCHOK no cover
171
173
  r = self.xyzLocal.toEnu(**_xkwds(kwds, Enu=Cls))
172
- elif _is(Cls, Ned):
174
+ elif _isc(Cls, Ned):
173
175
  r = self.xyzLocal.toNed(**_xkwds(kwds, Ned=Cls))
174
- elif _is(Cls, XyzLocal): # PYCHOK no cover
176
+ elif _isc(Cls, XyzLocal): # PYCHOK no cover
175
177
  r = self.xyzLocal.toXyz(**_xkwds(kwds, Xyz=Cls))
176
178
  elif Cls is Local9Tuple: # PYCHOK no cover
177
179
  r = self.xyzLocal.toLocal9Tuple(**kwds)
178
180
  else: # PYCHOK no cover
179
- n = Abc.__name__[:3] # typename
181
+ n = typename(Abc)[:3]
180
182
  raise _TypesError(n, Cls, Aer, Enu, Ned, XyzLocal)
181
183
  return r
182
184
 
@@ -383,7 +385,7 @@ class Attitude4Tuple(_NamedTuple):
383
385
  def tyr3d(self):
384
386
  '''Get this attitude's (3-D) directional vector (L{Vector3d}).
385
387
  '''
386
- return _MODS.ltp.Attitude(self).tyr3d
388
+ return _ltp.Attitude(self).tyr3d
387
389
 
388
390
 
389
391
  class Ned(_AbcBase):
@@ -731,7 +733,7 @@ class XyzLocal(_Vector3d):
731
733
  def _ltp_kwds_name3(self, ltp, kwds):
732
734
  '''(INTERNAL) Helper for methods C{toCartesian} and C{toLatLon}.
733
735
  '''
734
- ltp = _xLtp(ltp, self.ltp)
736
+ ltp = _ltp._xLtp(ltp, self.ltp)
735
737
  kwds = _name1__(kwds, _or_nameof=self)
736
738
  kwds = _name1__(kwds, _or_nameof=ltp)
737
739
  return ltp, kwds, kwds.get(_name_, NN)
@@ -965,10 +967,11 @@ class Enu(XyzLocal):
965
967
  I{local} instance (L{Enu}, L{Enu4Tuple}, L{Aer},
966
968
  L{Aer4Tuple}, L{Local9Tuple}, L{Ned}, L{Ned4Tuple},
967
969
  L{XyzLocal} or L{Xyz4Tuple}).
968
- @kwarg north: Scalar North component (C{meter}) only used with
969
- scalar B{C{east_enu}}.
970
- @kwarg up: Scalar Up component only used with scalar B{C{east_enu}},
971
- normal from the surface of the ellipsoid or sphere (C{meter}).
970
+ @kwarg north: Scalar North component (C{meter}), iff B{C{east_enu}}
971
+ is C{meter}, ignored otherwise.
972
+ @kwarg up: Scalar Up component (C{meter}, normal from the surface
973
+ of the ellipsoid or sphere), iff B{C{east_enu}} is
974
+ C{meter}, ignored otherwise.
972
975
  @kwarg ltp: The I{local tangent plane}, (geodetic) origin (L{Ltp},
973
976
  L{LocalCartesian}).
974
977
  @kwarg name: Optional C{B{name}=NN} (C{str}).
@@ -1249,10 +1252,12 @@ class Uvw(_Vector3d):
1249
1252
  def __init__(self, u_uvw, v=0, w=0, **name):
1250
1253
  '''New L{Uvw}.
1251
1254
 
1252
- @arg u_uvw: Scalar U component (C{meter}) or a previous instance
1253
- (L{Uvw}, L{Uvw3Tuple}, L{Vector3d}).
1254
- @kwarg v: V component (C{meter}) only used with scalar B{C{u_uvw}}.
1255
- @kwarg w: W component (C{meter}) only used with scalar B{C{u_uvw}}.
1255
+ @arg u_uvw: Scalar U component (C{meter}) or a previous instance (L{Uvw},
1256
+ L{Uvw3Tuple}, L{Vector3d}).
1257
+ @kwarg v: V component (C{meter}), iff B{C{u_uvw}} is C{meter}, ignored
1258
+ otherwise.
1259
+ @kwarg w: W component (C{meter}), iff B{C{u_uvw}} is C{meter}, ignored
1260
+ otherwise.
1256
1261
  @kwarg name: Optional C{B{name}=NN} (C{str}).
1257
1262
 
1258
1263
  @raise TypeError: Invalid B{C{east_enu}}.
@@ -1323,8 +1328,8 @@ class Los(Aer):
1323
1328
  or a previous instance (L{Aer}, L{Aer4Tuple}, L{Enu},
1324
1329
  L{Enu4Tuple} or L{Los}).
1325
1330
  @kwarg elevation: Scalar angle I{above} the horizon (C{degrees}, horizon
1326
- is 0, zenith +90, nadir -90), only used with scalar
1327
- B{C{azimuth_aer}}.
1331
+ is 0, zenith +90, nadir -90), if B{C{azimuth_aer}} is
1332
+ C{degrees}, ignored otherwise.
1328
1333
  @kwarg name: Optional C{B{name}=NN} (C{str}).
1329
1334
 
1330
1335
  @raise TypeError: Invalid B{C{azimuth_aer}}.
@@ -1388,19 +1393,19 @@ class ChLV9Tuple(Local9Tuple):
1388
1393
  def isChLV(self):
1389
1394
  '''Is this a L{ChLV}-generated L{ChLV9Tuple}?.
1390
1395
  '''
1391
- return self.ltp.__class__ is _MODS.ltp.ChLV
1396
+ return self.ltp.__class__ is _ltp.ChLV
1392
1397
 
1393
1398
  @property_RO
1394
1399
  def isChLVa(self):
1395
1400
  '''Is this a L{ChLVa}-generated L{ChLV9Tuple}?.
1396
1401
  '''
1397
- return self.ltp.__class__ is _MODS.ltp.ChLVa
1402
+ return self.ltp.__class__ is _ltp.ChLVa
1398
1403
 
1399
1404
  @property_RO
1400
1405
  def isChLVe(self):
1401
1406
  '''Is this a L{ChLVe}-generated L{ChLV9Tuple}?.
1402
1407
  '''
1403
- return self.ltp.__class__ is _MODS.ltp.ChLVe
1408
+ return self.ltp.__class__ is _ltp.ChLVe
1404
1409
 
1405
1410
  @Property_RO
1406
1411
  def N_LV95(self):
@@ -1526,7 +1531,7 @@ class Footprint5Tuple(_NamedTuple):
1526
1531
 
1527
1532
  @see: Methods L{XyzLocal.toLatLon} and L{Footprint5Tuple.xyzLocal5}.
1528
1533
  '''
1529
- ltp = _xLtp(ltp, self.center.ltp) # PYCHOK .center
1534
+ ltp = _ltp._xLtp(ltp, self.center.ltp) # PYCHOK .center
1530
1535
  kwds = _name1__(name_LatLon_kwds, _or_nameof=self)
1531
1536
  kwds = _xkwds(kwds, ltp=ltp, LatLon=LatLon)
1532
1537
  return Footprint5Tuple(t.toLatLon(**kwds) for t in self.xyzLocal5())
@@ -1544,7 +1549,7 @@ class Footprint5Tuple(_NamedTuple):
1544
1549
  if ltp is None:
1545
1550
  p = self
1546
1551
  else:
1547
- p = _xLtp(ltp)
1552
+ p = _ltp._xLtp(ltp)
1548
1553
  p = tuple(Xyz4Tuple(t.x, t.y, t.z, p) for t in self)
1549
1554
  return Footprint5Tuple(t.xyzLocal for t in p)
1550
1555
 
@@ -1552,13 +1557,13 @@ class Footprint5Tuple(_NamedTuple):
1552
1557
  def _ChLV_false2(Y, X, **LV95_name):
1553
1558
  '''(INTERNAL) Invoke static method C{ltp.ChLV.false2}.
1554
1559
  '''
1555
- return _MODS.ltp.ChLV.false2(Y, X, **LV95_name)
1560
+ return _ltp.ChLV.false2(Y, X, **LV95_name)
1556
1561
 
1557
1562
 
1558
1563
  def _ChLV_unfalse2(e, n, **LV95_name):
1559
1564
  '''(INTERNAL) Invoke static method C{ltp.ChLV.unfalse2}.
1560
1565
  '''
1561
- return _MODS.ltp.ChLV.unfalse2(e, n, **LV95_name)
1566
+ return _ltp.ChLV.unfalse2(e, n, **LV95_name)
1562
1567
 
1563
1568
 
1564
1569
  def _er2gr(e, r):
@@ -1577,7 +1582,7 @@ def _init(inst, abc, ltp, name):
1577
1582
  n = abc._name__(name)
1578
1583
  ltp = _xattr(abc, ltp=ltp)
1579
1584
  if ltp:
1580
- inst._ltp = _xLtp(ltp)
1585
+ inst._ltp = _ltp._xLtp(ltp)
1581
1586
  if n:
1582
1587
  inst.name = n
1583
1588
 
@@ -1595,12 +1600,6 @@ def _toStr2(inst, prec=None, fmt=Fmt.SQUARE, sep=_COMMASPACE_):
1595
1600
  return a, t
1596
1601
 
1597
1602
 
1598
- def _xLtp(ltp, *dflt):
1599
- '''(INTERNAL) Invoke C{ltp._xLtp}.
1600
- '''
1601
- return _MODS.ltp._xLtp(ltp, *dflt)
1602
-
1603
-
1604
1603
  def _xyz2aer4(inst):
1605
1604
  '''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
1606
1605
  '''