pygeodesy 25.12.31__py2.py3-none-any.whl → 26.2.2__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.
@@ -36,31 +36,31 @@ from __future__ import division as _; del _ # noqa: E702 ;
36
36
 
37
37
  # from pygeodesy.angles import Ang, isAng # _MODS
38
38
  from pygeodesy.basics import map1, isscalar
39
- from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, _EPS2e4, INT0, NAN, PI2, PI_3, PI4, \
40
- _isfinite, float0_, _0_0, _1_0, _N_1_0, _4_0 # PYCHOK used!
41
- # from pygeodesy.ellipsoids import Ellipsoid # _MODS
42
- # from pygeodesy.elliptic import Elliptic # _MODS
43
- # from pygeodesy.errors import _ValueError, _xkwds # from .formy
39
+ from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, _EPS2e4, INT0, \
40
+ _isfinite, float0_, NAN, PI2, PI_3, PI4, \
41
+ _0_0, _1_0, _N_1_0, _4_0 # PYCHOK used!
42
+ # from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # _MODS
43
+ # from pygeodesy.elliptic import elliperim, Elliptic # _MODS
44
+ # from pygeodesy.errors import _ValueError, _xkwds # from .utily
44
45
  from pygeodesy.fmath import fmean_, hypot, norm2, sqrt0, fabs, sqrt
45
- from pygeodesy.formy import elliperim, _ValueError, _xkwds
46
46
  from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1f_
47
47
  # from pygeodesy.internals import typename # _MODS
48
48
  from pygeodesy.interns import _a_, _b_, _c_, _inside_, _not_, _NOTEQUAL_, _null_, \
49
49
  _outside_, _scale_, _SPACE_, _spherical_, _x_, _y_, _z_
50
50
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
51
- from pygeodesy.named import _NamedEnumItem, _NamedTuple, _Pass
51
+ from pygeodesy.named import _NamedEnum, _NamedEnumItem, _NamedTuple, _Pass # _MODS
52
52
  from pygeodesy.namedTuples import Vector4Tuple
53
53
  from pygeodesy.props import Property_RO, property_doc_, property_RO, property_ROver
54
54
  # from pygeodesy.streprs import Fmt # _MODS
55
55
  from pygeodesy.units import Degrees, Easting, Float, Height, Height_, Meter2, Meter3, \
56
56
  Northing, Radius_, Scalar
57
- from pygeodesy.utily import asin1
57
+ from pygeodesy.utily import asin1, km2m, m2km, _ValueError, _xkwds
58
58
  from pygeodesy.vector3d import _otherV3d, Vector3d
59
59
 
60
60
  # from math import fabs, sqrt # from .fmath
61
61
 
62
62
  __all__ = _ALL_LAZY.triaxials_bases
63
- __version__ = '25.12.31'
63
+ __version__ = '26.01.14'
64
64
 
65
65
  _bet_ = 'bet' # PYCHOK shared
66
66
  _llk_ = 'llk' # PYCHOK shared
@@ -348,13 +348,13 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
348
348
 
349
349
  @property_ROver
350
350
  def _Ellipsoid(self):
351
- '''(INTERNAL) Get class L{Ellipsoid}, I{once}.
351
+ '''(INTERNAL) Get class C{Ellipsoid}, I{once}.
352
352
  '''
353
353
  return _MODS.ellipsoids.Ellipsoid # overwrite property_ROver
354
354
 
355
355
  @property_ROver
356
356
  def _Elliptic(self):
357
- '''(INTERNAL) Get class L{Elliptic}, I{once}.
357
+ '''(INTERNAL) Get class C{Ellipsoid}, I{once}.
358
358
  '''
359
359
  return _MODS.elliptic.Elliptic # overwrite property_ROver
360
360
 
@@ -364,15 +364,14 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
364
364
 
365
365
  @see: Function L{hartzell4<triaxials.triaxial5.hartzell4>} for further details.
366
366
  '''
367
- return self._triaxials_triaxial5.hartzell4(pov, los=los, tri_biax=self, **name)
367
+ return _MODS.triaxials.hartzell4(pov, los=los, tri_biax=self, **name)
368
368
 
369
369
  def height4(self, x_xyz, y=None, z=None, normal=True, eps=EPS, **name):
370
370
  '''Compute the projection on and the height above or below this triaxial's surface.
371
371
 
372
372
  @see: Function L{height4<triaxials.triaxial5.height4>} for further details.
373
373
  '''
374
- m = self._triaxials_triaxial5
375
- return m.height4(x_xyz, y=y, z=z, tri_biax=self, normal=normal, eps=eps, **name)
374
+ return _MODS.triaxials.height4(x_xyz, y=y, z=z, tri_biax=self, normal=normal, eps=eps, **name)
376
375
 
377
376
  @Property_RO
378
377
  def isOrdered(self):
@@ -527,21 +526,21 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
527
526
  '''Get the C{ab} ellipse' perimeter (C{scalar}).
528
527
  '''
529
528
  a, b, _ = self._abc3
530
- return Float(perimeter4ab=elliperim(a, b))
529
+ return Float(perimeter4ab=_MODS.elliptic.elliperim(a, b))
531
530
 
532
531
  @Property_RO
533
532
  def perimeter4ac(self):
534
533
  '''Get the C{ac} ellipse' perimeter (C{scalar}).
535
534
  '''
536
535
  a, _, c = self._abc3
537
- return Float(perimeter4ac=elliperim(a, c))
536
+ return Float(perimeter4ac=_MODS.elliptic.elliperim(a, c))
538
537
 
539
538
  @Property_RO
540
539
  def perimeter4bc(self):
541
540
  '''Get the C{bc} ellipse' perimeter (C{scalar}).
542
541
  '''
543
542
  _, b, c = self._abc3
544
- return Float(perimeter4bc=elliperim(b, c))
543
+ return Float(perimeter4bc=_MODS.elliptic.elliperim(b, c))
545
544
 
546
545
  def _radialTo3(self, sbeta, cbeta, somega, comega):
547
546
  '''(INTERNAL) I{Unordered} helper for C{.height4}.
@@ -625,42 +624,24 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
625
624
  @return: This C{Triaxial}'s attributes (C{str}).
626
625
  '''
627
626
  T = _UnOrderedTriaxialBase
628
- C = self._triaxials_triaxial3.Triaxial3B
627
+ m = _MODS.triaxials
628
+ C = m.Triaxial3B
629
629
  if isinstance(self, C):
630
- t = T.b, C.e2, C.k2, C.kp2
630
+ t = T.b, C.e2, C.k2, C.kp2
631
631
  else:
632
- t = T.a, # props
633
- C = self._triaxials_triaxial5.ConformalSphere
632
+ t = T.a, # props
633
+ C = m.ConformalSphere
634
634
  t += (C.ab, C.bc) if isinstance(self, C) else (T.b, T.c)
635
635
  C = _Triaxial3Base
636
636
  t += (C.k2, C.kp2) if isinstance(self, C) else \
637
637
  (T.e2ab, T.e2bc, T.e2ac)
638
- for C in (self._triaxials_triaxial5.Conformal,
639
- self._triaxials_conformal3.Conformal3):
638
+ for C in (m.Conformal, m.Conformal3):
640
639
  if isinstance(self, C):
641
640
  t += C.xyQ2,
642
641
  break
643
642
  t += T.volume, T.area
644
643
  return self._instr(area_p=self.area_p(), prec=prec, props=t, **name)
645
644
 
646
- @property_ROver
647
- def _triaxials_conformal3(self):
648
- '''(INTERNAL) Get module L{pygeodesy.triaxials.conformal3}, I{once}.
649
- '''
650
- return _MODS.triaxials.conformal3 # overwrite property_ROver
651
-
652
- @property_ROver
653
- def _triaxials_triaxial3(self):
654
- '''(INTERNAL) Get module L{pygeodesy.triaxials.triaxial3}, I{once}.
655
- '''
656
- return _MODS.triaxials.triaxial3 # overwrite property_ROver
657
-
658
- @property_ROver
659
- def _triaxials_triaxial5(self):
660
- '''(INTERNAL) Get module L{pygeodesy.triaxials.triaxial5}, I{once}.
661
- '''
662
- return _MODS.triaxials.triaxial5 # overwrite property_ROver
663
-
664
645
  @Property_RO
665
646
  def unOrdered(self):
666
647
  '''Is this triaxial I{un-ordered} and I{not spherical} (C{bool})?
@@ -723,7 +704,7 @@ class _OrderedTriaxialBase(_UnOrderedTriaxialBase):
723
704
  aE.fF(r) * c2 / s)
724
705
  a = Meter2(area=a * b * PI2)
725
706
  else: # a == b > c
726
- a = self._Ellipsoid(a, b=c).areax
707
+ a = self._Ellipsoid(a, b=c).areax
727
708
  return a
728
709
 
729
710
  @Property_RO
@@ -899,6 +880,47 @@ class TriaxialError(_ValueError):
899
880
  pass # ...
900
881
 
901
882
 
883
+ class _TriaxialsBase(_NamedEnum):
884
+ '''(INTERNAL) C{Triaxial*} registry, I{must} be a sub-class
885
+ to accommodate the L{_LazyNamedEnumItem} properties.
886
+ '''
887
+ _assert_kwds = {} # like propertyROnce
888
+ _Triaxial = None # must be overloaded
889
+
890
+ def _Lazy(self, *abc, **name):
891
+ '''(INTERNAL) Instantiate the C{self._Triaxial}.
892
+ '''
893
+ return self._Triaxial(*abc, **name)
894
+
895
+ def _assert(self): # PYCHOK signature
896
+ kwds = _TriaxialsBase._assert_kwds
897
+ if not kwds:
898
+ _lazy = _MODS.named._lazyNamedEnumItem
899
+ EWGS84 = _MODS.ellipsoids._EWGS84
900
+ abc84_35 = map1(m2km, EWGS84.a + 35, EWGS84.a - 35, EWGS84.b)
901
+ # <https://ArxIV.org/pdf/1909.06452.pdf> Table 1 Semi-axes in Km
902
+ # <https://www.JPS.NASA.gov/education/images/pdf/ss-moons.pdf>
903
+ # <https://link.Springer.com/article/10.1007/s00190-022-01650-9>
904
+ # <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Constants.html>
905
+ for n, abc in dict( # a (Km) b (Km) c (Km) planet
906
+ Amalthea= (125.0, 73.0, 64.0), # Jupiter
907
+ Ariel= (581.1, 577.9, 577.7), # Uranus
908
+ Earth= (6378.173435, 6378.1039, 6356.7544),
909
+ Enceladus=(256.6, 251.4, 248.3), # Saturn
910
+ Europa= (1564.13, 1561.23, 1560.93), # Jupiter
911
+ Io= (1829.4, 1819.3, 1815.7), # Jupiter
912
+ Mars= (3394.6, 3393.3, 3376.3),
913
+ Mimas= (207.4, 196.8, 190.6), # Saturn
914
+ Miranda= (240.4, 234.2, 232.9), # Uranus
915
+ Moon= (1735.55, 1735.324, 1734.898), # Earth
916
+ Tethys= (535.6, 528.2, 525.8), # Saturn
917
+ WGS84_3= (6378.17136, 6378.10161, 6356.75184), # C++
918
+ WGS84_3r=(6378.172, 6378.102, 6356.752), # C++, rounded
919
+ WGS84_35=abc84_35).items():
920
+ kwds[n] = _lazy(n, *map(km2m, abc))
921
+ _NamedEnum._assert(self, **kwds)
922
+
923
+
902
924
  def _getitems(items, *indices):
903
925
  '''(INTERNAL) Get the C{items} at the given I{indices}.
904
926
 
@@ -12,6 +12,21 @@ GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Triaxial_1_1Ellipsoid
12
12
  Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2024-2025) and licensed under the MIT/X11
13
13
  License. For more information, see the U{GeographicLib 2.7 <https://GeographicLib.SourceForge.io/>}
14
14
  documentation.
15
+
16
+ @var Triaxial3s.Amalthea: Triaxial3(name='Amalthea', a=125000, b=73000, c=64000, k2=0.106947697, kp2=0.893052303, volume=2446253479595252, area=93239507787.490371704, area_p=93212299402.670425415)
17
+ @var Triaxial3s.Ariel: Triaxial3(name='Ariel', a=581100, b=577900, c=577700, k2=0.05866109, kp2=0.94133891, volume=812633172614203904, area=4211301462766.580078125, area_p=4211301574065.829589844)
18
+ @var Triaxial3s.Earth: Triaxial3(name='Earth', a=6378173.435, b=6378103.9, c=6356754.399999999, k2=0.996748146, kp2=0.003251854, volume=1083208241574987694080, area=510065911057441.0625, area_p=510065915922713.6875)
19
+ @var Triaxial3s.Enceladus: Triaxial3(name='Enceladus', a=256600, b=251400, c=248300, k2=0.369647336, kp2=0.630352664, volume=67094551514082248, area=798618496278.596679688, area_p=798619018175.109985352)
20
+ @var Triaxial3s.Europa: Triaxial3(name='Europa', a=1564130, b=1561230, c=1560930, k2=0.093663002, kp2=0.906336998, volume=15966575194402123776, area=30663773697323.515625, area_p=30663773794562.45703125)
21
+ @var Triaxial3s.Io: Triaxial3(name='Io', a=1829400, b=1819300, c=1815700, k2=0.262045618, kp2=0.737954382, volume=25313121117889765376, area=41691875849096.734375, area_p=41691877397441.2109375)
22
+ @var Triaxial3s.Mars: Triaxial3(name='Mars', a=3394600, b=3393300, c=3376300, k2=0.92878339, kp2=0.07121661, volume=162907283585817247744, area=144249140795107.4375, area_p=144249144150662.15625)
23
+ @var Triaxial3s.Mimas: Triaxial3(name='Mimas', a=207400, b=196800, c=190600, k2=0.359218713, kp2=0.640781287, volume=32587072869017956, area=493855762247.691833496, area_p=493857714107.9375)
24
+ @var Triaxial3s.Miranda: Triaxial3(name='Miranda', a=240400, b=234200, c=232900, k2=0.171062751, kp2=0.828937249, volume=54926187094835456, area=698880863325.757202148, area_p=698881306767.950317383)
25
+ @var Triaxial3s.Moon: Triaxial3(name='Moon', a=1735550, b=1735324, c=1734898, k2=0.653331685, kp2=0.346668315, volume=21886698675223740416, area=37838824729886.09375, area_p=37838824733332.21875)
26
+ @var Triaxial3s.Tethys: Triaxial3(name='Tethys', a=535600, b=528200, c=525800, k2=0.243190549, kp2=0.756809451, volume=623086233855821440, area=3528073490771.394042969, area_p=3528074261832.738769531)
27
+ @var Triaxial3s.WGS84_3: Triaxial3(name='WGS84_3', a=6378171.36, b=6378101.609999999, c=6356751.84, k2=0.996738165, kp2=0.003261835, volume=1083207064030173855744, area=510065541435967.375, area_p=510065546301413.5625)
28
+ @var Triaxial3s.WGS84_35: Triaxial3(name='WGS84_35', a=6378172, b=6378102, c=6356752.314245179, k2=0.996726499, kp2=0.003273501, volume=1083207319768789942272, area=510065621722018.25, area_p=510065626587483.3125)
29
+ @var Triaxial3s.WGS84_3r: Triaxial3(name='WGS84_3r', a=6378172, b=6378102, c=6356752, k2=0.996726547, kp2=0.003273453, volume=1083207266220584468480, area=510065604942135.8125, area_p=510065609807745.0)
15
30
  '''
16
31
  # make sure int/int division yields float quotient, see .basics
17
32
  from __future__ import division as _; del _ # noqa: E702 ;
@@ -19,34 +34,34 @@ from __future__ import division as _; del _ # noqa: E702 ;
19
34
  from pygeodesy.angles import Ang, Ang_, _Ang3Tuple, atan2, sincos2, _SinCos2
20
35
  from pygeodesy.basics import _copysign, map1
21
36
  from pygeodesy.constants import EPS, EPS_2, EPS02, EPS8, INT0, NAN, \
22
- _EPSqrt, _copysign_0_0, _copysign_1_0, \
37
+ _EPSqrt, _SQRT3, _copysign_0_0, _copysign_1_0, \
23
38
  _flipsign, _isfinite, _over, _1_over, _0_0, \
24
39
  _0_5, _N_1_0, _1_0, _2_0, _3_0, _4_0, _9_0
25
40
  from pygeodesy.errors import _xattr, _xkwds, _xkwds_get, _xkwds_pop2
26
41
  from pygeodesy.fmath import cbrt2, fdot, hypot, hypot2, norm2, fabs, sqrt
27
42
  from pygeodesy.fsums import Fsum, fsumf_, Fmt
28
- from pygeodesy.interns import NN, _h_, _lam_, _name_, _phi_
29
- from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
30
- from pygeodesy.named import _NamedDict, _Pass # _Named
31
- from pygeodesy.namedTuples import Vector4Tuple
32
- from pygeodesy.props import Property_RO, property_ROver
43
+ from pygeodesy.interns import NN, _DMAIN_, _h_, _lam_, _phi_
44
+ # from pygeodesy.lazily import _ALL_LAZY # from .vector3d
45
+ # from pygeodesy.named import _Pass # from .namedTuples
46
+ from pygeodesy.namedTuples import Vector4Tuple, _Pass
47
+ # from pygeodesy.props import Property_RO # from .units
33
48
  # from pygeodesy.streprs import Fmt # from .fsums
34
49
  from pygeodesy.triaxials.bases import _bet_, _HeightINT0, LLK, _llk_, \
35
50
  _MAXIT, _omg_, _otherV3d_, _sqrt0, \
36
- _Triaxial3Base, TriaxialError
37
- from pygeodesy.units import Degrees, Radians, Radius_
51
+ _Triaxial3Base, TriaxialError, \
52
+ _TriaxialsBase
53
+ from pygeodesy.units import Degrees, Radians, Radius_, Property_RO
38
54
  # from pygeodesy.utily import atan2, sincos2 # from .triaxials.angles
39
- from pygeodesy.vector3d import Vector3d
55
+ from pygeodesy.vector3d import Vector3d, _ALL_LAZY
40
56
 
41
57
  # from math import fabs, sqrt # from .fmath
42
58
  from random import random
43
59
 
44
60
  __all__ = _ALL_LAZY.triaxials_triaxial3
45
- __version__ = '25.12.14'
61
+ __version__ = '26.01.14'
46
62
 
47
63
  _alp_ = 'alp'
48
64
  _NAN3d = Vector3d(NAN, NAN, NAN)
49
- _SQRT3 = sqrt(_3_0)
50
65
  _TOL = cbrt2(EPS)
51
66
  _TOL2 = _TOL**2 # cbrt(EPS)**4
52
67
  _zet_ = 'zet'
@@ -801,38 +816,6 @@ class Triaxial3B(Triaxial3):
801
816
  self._init_abc3_e2_k2_kp2(Radius_(b=b), e2, k2, kp2, **name)
802
817
 
803
818
 
804
- class Triaxial3s(_NamedDict):
805
- '''(INTERNAL) L{Triaxial3} registry, I{must} be a sub-class
806
- to accommodate the L{_LazyNamedEnumItem} properties.
807
- '''
808
- def __getattr__(self, name):
809
- '''Get the value of an item by B{C{name}}.
810
- '''
811
- try:
812
- return self[name]
813
- except KeyError:
814
- if name == _name_:
815
- return _MODS.named._Named.name.fget(self)
816
- raise _NamedDict._AttributeError(self, self._DOT_(name))
817
-
818
- def __getitem__(self, key):
819
- '''Get the value of an item by B{C{key}}.
820
- '''
821
- T = self._Triaxials(key, None)
822
- if T is None or key == _name_:
823
- raise KeyError(key)
824
- return Triaxial3(T, name=key)
825
-
826
- @property_ROver
827
- def _Triaxials(self):
828
- '''(INTERNAL) Get the C{Triaxials.get}, I{once}.
829
- '''
830
- return _MODS.triaxials.triaxial5.Triaxials.get
831
-
832
- Triaxial3s = Triaxial3s() # PYCHOK singleton
833
- '''Some pre-defined L{Triaxial3}s, like L{Triaxials<triaxials.Triaxials>}.'''
834
-
835
-
836
819
  def _cubic(rs, rt, l0, l1): # Cartesian3.cubic
837
820
  '''(INTERNaL) Solve sum(R2[i]/(z + lq2[i]), i=0,1,2) - 1 = 0
838
821
  with lq2[2] = 0. This has three real roots with just one
@@ -945,6 +928,20 @@ def _v_h_llk_name_NOIDAL(x_ct, y, z, **h_llk_name):
945
928
  raise TriaxialError(h=h, llk=llk, **kwds)
946
929
  return v, h, (LLK.ELLIPSOIDAL if llk is None else llk), name
947
930
 
931
+
932
+ class Triaxial3s(_TriaxialsBase):
933
+ _Triaxial = Triaxial3
934
+
935
+ Triaxial3s = Triaxial3s(Triaxial3, Triaxial3B) # PYCHOK singleton
936
+ '''Some pre-defined L{Triaxial3}s, like L{Triaxials<triaxials.triaxial5.Triaxials>}.'''
937
+ Triaxial3s._assert()
938
+
939
+ if __name__ == _DMAIN_:
940
+ # __doc__ of this file, force all into registry
941
+ from pygeodesy.internals import _pregistry
942
+ _pregistry(Triaxial3s)
943
+
944
+
948
945
  # **) MIT License
949
946
  #
950
947
  # Copyright (C) 2025-2026 -- mrJean1 at Gmail -- All Rights Reserved.
@@ -37,9 +37,8 @@ from pygeodesy.angles import _SinCos2, Property_RO
37
37
  from pygeodesy.basics import _isin, isLatLon
38
38
  from pygeodesy.constants import EPS, EPS0, EPS02, _EPS2e4, INT0, \
39
39
  _isfinite, isnear1, _over, _SQRT2_2, \
40
- _0_0, _0_5, _1_0, _N_1_0, _64_0
41
- from pygeodesy.datums import Datum, _spherical_datum, _WGS84, _EWGS84, Fmt
42
- # from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # from .datums
40
+ _0_0, _0_5, _1_0, _N_1_0
41
+ from pygeodesy.datums import Datum, _spherical_datum, _WGS84, Fmt
43
42
  # from pygeodesy.elliptic import Elliptic # _MODS
44
43
  from pygeodesy.errors import _AssertionError, _ValueError, _xkwds_pop2
45
44
  from pygeodesy.fmath import Fdot, fdot, hypot, hypot_, fabs, sqrt
@@ -48,7 +47,7 @@ from pygeodesy.interns import NN, _beta_, _distant_, _DMAIN_, _finite_, _height_
48
47
  _inside_, _near_, _negative_, _not_, _null_, _opposite_, \
49
48
  _outside_, _too_, _x_, _y_
50
49
  from pygeodesy.lazily import _ALL_LAZY, _FOR_DOCS
51
- from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, _Pass
50
+ from pygeodesy.named import _name__, _Pass
52
51
  from pygeodesy.namedTuples import LatLon3Tuple, _NamedTupleTo, Vector2Tuple, \
53
52
  Vector3Tuple, Vector4Tuple
54
53
  # from pygeodesy.props import Property_RO # from .triaxials.angles
@@ -56,15 +55,15 @@ from pygeodesy.namedTuples import LatLon3Tuple, _NamedTupleTo, Vector2Tuple, \
56
55
  from pygeodesy.triaxials.bases import Conformal5Tuple, _HeightINT0, _hypot2_1, \
57
56
  _not_ordered_, _OrderedTriaxialBase, _over0, \
58
57
  _otherV3d_, _over02, _sqrt0, TriaxialError, \
59
- _Triaxial3Base, _UnOrderedTriaxialBase
58
+ _Triaxial3Base, _TriaxialsBase, _UnOrderedTriaxialBase
60
59
  from pygeodesy.units import Degrees, Height_, Lat, Lon, Meter, Radians, Radius_, Scalar_
61
- from pygeodesy.utily import atan2, atan2d, km2m, m2km
60
+ from pygeodesy.utily import atan2, atan2d
62
61
  from pygeodesy.vector3d import _otherV3d, Vector3d
63
62
 
64
63
  # from math import fabs, sqrt # from .fmath
65
64
 
66
65
  __all__ = _ALL_LAZY.triaxials_triaxial5
67
- __version__ = '25.11.29'
66
+ __version__ = '26.01.14'
68
67
 
69
68
  _omega_ = 'omega'
70
69
  _TRIPS = 359 # Eberly 1074?
@@ -757,41 +756,6 @@ class ConformalSphere(Conformal):
757
756
  return self.a
758
757
 
759
758
 
760
- class Triaxials(_NamedEnum):
761
- '''(INTERNAL) L{Triaxial} registry, I{must} be a sub-class
762
- to accommodate the L{_LazyNamedEnumItem} properties.
763
- '''
764
- def _Lazy(self, *abc, **name):
765
- '''(INTERNAL) Instantiate the C{Triaxial}.
766
- '''
767
- a, b, c = map(km2m, abc)
768
- return Triaxial(a, b, c, **name)
769
-
770
- Triaxials = Triaxials(Triaxial, Triaxial_) # PYCHOK singleton
771
- '''Some pre-defined L{Triaxial}s, all I{lazily} instantiated.'''
772
- # <https://ArxIV.org/pdf/1909.06452.pdf> Table 1 Semi-axes in Km
773
- # <https://www.JPS.NASA.gov/education/images/pdf/ss-moons.pdf>
774
- # <https://link.Springer.com/article/10.1007/s00190-022-01650-9>
775
- # <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Constants.html>
776
- _abc84_35 = (_EWGS84.a + 35), (_EWGS84.a - 35), _EWGS84.b
777
- Triaxials._assert( # a (Km) b (Km) c (Km) planet
778
- Amalthea = _lazy('Amalthea', 125.0, 73.0, _64_0), # Jupiter
779
- Ariel = _lazy('Ariel', 581.1, 577.9, 577.7), # Uranus
780
- Earth = _lazy('Earth', 6378.173435, 6378.1039, 6356.7544),
781
- Enceladus = _lazy('Enceladus', 256.6, 251.4, 248.3), # Saturn
782
- Europa = _lazy('Europa', 1564.13, 1561.23, 1560.93), # Jupiter
783
- Io = _lazy('Io', 1829.4, 1819.3, 1815.7), # Jupiter
784
- Mars = _lazy('Mars', 3394.6, 3393.3, 3376.3),
785
- Mimas = _lazy('Mimas', 207.4, 196.8, 190.6), # Saturn
786
- Miranda = _lazy('Miranda', 240.4, 234.2, 232.9), # Uranus
787
- Moon = _lazy('Moon', 1735.55, 1735.324, 1734.898), # Earth
788
- Tethys = _lazy('Tethys', 535.6, 528.2, 525.8), # Saturn
789
- WGS84_3 = _lazy('WGS84_3', 6378.17136, 6378.10161, 6356.75184), # C++
790
- WGS84_3r = _lazy('WGS84_3r', 6378.172, 6378.102, 6356.752), # C++, rounded
791
- WGS84_35 = _lazy('WGS84_35', *map(m2km, _abc84_35)))
792
- del _abc84_35, _EWGS84
793
-
794
-
795
759
  def _hartzell3(pov, los, Tun): # in .Ellipsoid.hartzell4, .formy.hartzell
796
760
  '''(INTERNAL) Hartzell's "Satellite Line-of-Sight Intersection ...",
797
761
  formula from a Point-Of-View to an I{un-/ordered} Triaxial.
@@ -1180,20 +1144,24 @@ def _validate(a, b, c, d, T, x, y, z, val):
1180
1144
  dot=e, eps=val)
1181
1145
 
1182
1146
 
1147
+ class Triaxials(_TriaxialsBase):
1148
+ _Triaxial = Triaxial
1149
+
1150
+ Triaxials = Triaxials(Triaxial, Triaxial_) # PYCHOK singleton
1151
+ '''Some pre-defined L{Triaxial}s, all I{lazily} instantiated.'''
1152
+ Triaxials._assert()
1153
+
1183
1154
  if __name__ == _DMAIN_:
1184
1155
 
1185
- from pygeodesy import printf
1186
- from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
1156
+ from pygeodesy.internals import _pregistry, printf
1187
1157
 
1188
1158
  T = Triaxial_(6378388.0, 6378318.0, 6356911.9461)
1189
1159
  t = T.height4(3909863.9271, 3909778.123, 3170932.5016)
1190
1160
  printf('# Bektas: %r', t)
1161
+ # __doc__ of this file, force all into registry
1162
+ _pregistry(Triaxials)
1191
1163
 
1192
- # __doc__ of this file, force all into registery
1193
- t = [NN] + Triaxials.toRepr(all=True, asorted=True).split(_NL_)
1194
- printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
1195
-
1196
- # % python3 -m pygeodesy.triaxials
1164
+ # % python3 -m pygeodesy.triaxials.triaxial5
1197
1165
  #
1198
1166
  # Bektas: height4(x=3909251.554667, y=3909165.750567, z=3170432.501602, h=999.999996)
1199
1167
 
pygeodesy/utily.py CHANGED
@@ -13,7 +13,8 @@ from __future__ import division as _; del _ # noqa: E702 ;
13
13
 
14
14
  from pygeodesy.basics import _copysign, isinstanceof, isint, isstr
15
15
  from pygeodesy.constants import EPS, EPS0, NAN, PI, PI2, PI_2, PI_4, PI_6, R_M, \
16
- _M_KM, _M_NM, _M_SM, _0_0, _0_5, _1_0, _N_1_0, \
16
+ _M_KM, _M_NM, _M_SM, _SQRT2_2 as _COS_45, \
17
+ _SQRT3_2 as _COS_30, _0_0, _0_5, _1_0, _N_1_0, \
17
18
  _10_0, _90_0, _180_0, _360_0, _copysign_0_0, \
18
19
  _copysignINF, _float, _isfinite, isnan, isnear0, \
19
20
  _over_1, _umod_360, _umod_PI2, OVERFLOW
@@ -28,11 +29,10 @@ from math import acos, asin, asinh, atan2 as _atan2, cos, degrees, fabs, \
28
29
  radians, sin, sinh, tan as _tan # pow
29
30
 
30
31
  __all__ = _ALL_LAZY.utily
31
- __version__ = '25.11.09'
32
+ __version__ = '26.01.14'
32
33
 
33
- # sqrt(3) <https://WikiPedia.org/wiki/Square_root_of_3>
34
- _COS_30, _SIN_30 = 0.86602540378443864676, _0_5 # sqrt(3) / 2
35
- _COS_45 = _SIN_45 = 0.70710678118654752440 # sqrt(2) / 2
34
+ _SIN_30 = _0_5
35
+ _SIN_45 = _COS_45
36
36
 
37
37
  _G = _Enum( # grades per ...
38
38
  DEG = _float( 400.0 / _360_0), # degree
@@ -42,7 +42,7 @@ _M = _Enum( # meter per ...
42
42
  ACRE = _float( 4046.8564224), # acre, chain2m(1) * furlong2m(1), squared
43
43
  CHAIN = _float( 20.1168), # yard2m(1) * 22
44
44
  FATHOM = _float( 1.8288), # yard2m(1) * 2 or _M.NM * 1e-3
45
- FOOT = _float( 0.3048), # Int'l foot, 1 / 3.280_839_895_0131 = 10_000 / (254 * 12)
45
+ FOOT = _float( 0.3048), # Int'l foot, 1 / 3.280_839_895_0131 == (254 * 12) / 10_000
46
46
  FOOT_GE = _float( 0.31608), # German Fuss, 1 / 3.163_756_011_1364
47
47
  FOOT_FR = _float( 0.3248406), # French Pied-du-Roi or pied, 1 / 3.078_432_929_8739
48
48
  FOOT_US = _float( 0.3048006096012192), # US Survey foot, 1_200 / 3_937
@@ -56,7 +56,7 @@ _M = _Enum( # meter per ...
56
56
 
57
57
 
58
58
  def _abs1nan(x):
59
- '''(INTERNAL) Bracket C{x}.
59
+ '''(INTERNAL) Bracket C{-1 < x < 1 or isnan(x)}.
60
60
  '''
61
61
  return _N_1_0 < x < _1_0 or isnan(x)
62
62
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pygeodesy
3
- Version: 25.12.31
3
+ Version: 26.2.2
4
4
  Summary: Pure Python geodesy tools
5
5
  Home-page: https://GitHub.com/mrJean1/PyGeodesy
6
6
  Author: Jean M. Brouwers
@@ -8,7 +8,7 @@ Author-email: mrJean1@Gmail.com
8
8
  Maintainer: Jean M. Brouwers
9
9
  Maintainer-email: mrJean1@Gmail.com
10
10
  License: MIT
11
- Keywords: AER AGM Albers altitude Andoyer annulus antipode area Arithmetic-Geometric-Mean attitude Authalic auxiliary azimuth azimuthal azimuth-elevation-range bearing bank Barsky Barth beta bi-quadratic boolean cached Cagnoli cartesian Cassini Cassini-Soldner chord circle-intersections circumcenter circumcircle circumradius clip Cohen Cohen-Sutherland Collins composite conformal conformal-sphere conic constants contact-triangle Cook Correia cosines-law coverage curvature cylindrical datum deprecation deficit development discrete distance Douglas earth east-north-up eccentricity ECEF elevation ellipsoid ellipsoidal-latitude-beta ellipsoidal-longitude-omega elliptic ENU EPSG equal-area equidistant equirectangular ETM ETRF Euclidean even-odd-rule ExactTM excess Farrell Farrell-Barth Ferrari-solution Field-Of-View flattening fma fmath footpoint footprint Forster Forster-Hormann-Popa Forsythe FOV fractional Frechet Fréchet frustum Fsum fused-multiply-add GARS Gauss-Kummer geocentric GeoConvert GeodesicExact geodesy geodetic GeodSolve Geod3Solve GeodTest geographiclib Geohash geoid geoidHeight GeoidHeights georef Girard gnomonic gons grades gradians Greiner Greiner-Hormann Hartzell Hausdorff Haversine heading hectare height Heikkinen Heron Hodgman horizon Hormann Hubeny IDW incenter incirle infix_@_operator inradius intermediate interpolate intersect intersection intersection3d intersections IntersectTool Inverse-Distance-Weighting Isometric ITRF Jacobi Jacobi-Conformal Jarque-Bera Jekel Karney Krueger Krüger kurtosis Lambert latitude law-of-cosines least-squares Lesh L_Huilier LHuilier Liang Liang-Barsky Linderholm-Segal linearize Line-Of-Sight LocalCartesian local-tangent-plane local-x-y-z longitude LOS loxodrome lstsq LTP lune LV03 LV95 mean memoize memoized Mercator Meeus MGRS nearest NED Niemeyer non-finite normalize Norrdine north-east-down numpy n-vector Nvector oblate omega orthographic orthometric-height OSGB OSGR overlap parallel parallel-of-latitude Parametric path-intersection perimeter Peucker Pierlot pitch plumb Point-Of-View polar Popa POV precision-cubic-root precision-hypotenuse precision-powers precision-running-summation precision-square-root precision-summation prolate Pseudo-Mercator pygeodesy PyInstaller PyPy quartic radical radii radius Ramanujan Ramer Ramer-Douglas-Peucker Rectifying Reduced resect resection Rey-Jer Reumann Reumann-Witkam rho-theta-phi rhumb RhumbSolve running-linear-regression running-statistics running-stats running-summation scipy secant semi-perimeter sexagecimal simplify skewness Snellius Snellius-Pothenot Snyder Soddy Soddy-circles Soldner sphere sphere-intersections spherical-deficit spherical-excess spherical-polar spherical-triangle squared-quartic standard-deviation stereographic Sudano surface-area Sutherland Sutherland-Hodgman tangent-circles Terrestrial-Reference-Frame Thomas Tienstra tilt TMcoords TMExact toise transverse TransverseMercatorExact TRF triangle triangulate triaxial triaxial-ellipsoid trigonometry trilaterate trilaterate-2d trilaterate-3d TwoProduct TwoSum umbilic-point unit unroll UPS UTM UTM/UPS variance velocities Veness Vermeille viewing-frustum Vincenty Visvalingam Visvalingam-Whyatt volume volumetric Web-Mercator Welford WGRS WGS Whyatt Wildberger Witkam winding-number XYZ yaw You zenzi-cubic zenzi-quartic
11
+ Keywords: AER AGM Albers altitude Andoyer annulus antipode area Arithmetic-Geometric-Mean attitude Authalic auxiliary azimuth azimuthal azimuth-elevation-range bearing bank Barsky Barth beta bi-quadratic boolean cached Cagnoli cartesian Cassini Cassini-Soldner chord circle-intersections circumcenter circumcircle circumradius clip Cohen Cohen-Sutherland Collins composite conformal conformal-sphere conic constants contact-triangle Cook Correia cosines-law coverage curvature cylindrical datum deprecation deficit development discrete distance Douglas earth east-north-up eccentricity ECEF elevation ellipse ellipsoid ellipsoidal-latitude-beta ellipsoidal-longitude-omega elliptic ENU EPSG equal-area equidistant equirectangular ETM ETRF Euclidean even-odd-rule ExactTM excess Farrell Farrell-Barth Ferrari-solution Field-Of-View flattening fma fmath footpoint footprint Forster Forster-Hormann-Popa Forsythe FOV fractional Frechet Fréchet frustum Fsum fused-multiply-add GARS Gauss-Kummer geocentric GeoConvert GeodesicExact geodesy geodetic GeodSolve Geod3Solve GeodTest geographiclib Geohash geoid geoidHeight GeoidHeights georef Girard gnomonic gons grades gradians Greiner Greiner-Hormann Hartzell Hausdorff Haversine heading hectare height Heikkinen Heron Hodgman horizon Hormann Hubeny IDW incenter incirle infix_@_operator inradius intermediate interpolate intersect intersection intersection3d intersections IntersectTool Inverse-Distance-Weighting Isometric ITRF Jacobi Jacobi-Conformal Jarque-Bera Jekel Karney Krueger Krüger kurtosis Lambert latitude law-of-cosines least-squares Lesh L_Huilier LHuilier Liang Liang-Barsky Linderholm-Segal linearize Line-Of-Sight LocalCartesian local-tangent-plane local-x-y-z longitude LOS loxodrome lstsq LTP lune LV03 LV95 mean memoize memoized Mercator Meeus MGRS nearest NED Niemeyer non-finite normalize Norrdine north-east-down numpy n-vector Nvector oblate omega orthographic orthometric-height OSGB OSGR overlap parallel parallel-of-latitude Parametric path-intersection perimeter Peucker Pierlot pitch plumb Point-Of-View polar Popa POV precision-cubic-root precision-hypotenuse precision-powers precision-running-summation precision-square-root precision-summation prolate Pseudo-Mercator pygeodesy PyInstaller PyPy quartic radical radii radius Ramanujan Ramer Ramer-Douglas-Peucker Rectifying Reduced resect resection Rey-Jer Reumann Reumann-Witkam rho-theta-phi rhumb RhumbSolve running-linear-regression running-statistics running-stats running-summation scipy secant semi-perimeter sexagecimal simplify skewness Snellius Snellius-Pothenot Snyder Soddy Soddy-circles Soldner sphere sphere-intersections spherical-deficit spherical-excess spherical-polar spherical-triangle squared-quartic standard-deviation stereographic Sudano surface-area Sutherland Sutherland-Hodgman tangent-circles Terrestrial-Reference-Frame Thomas Tienstra tilt TMcoords TMExact toise transverse TransverseMercatorExact TRF triangle triangulate triaxial triaxial-ellipsoid trigonometry trilaterate trilaterate-2d trilaterate-3d TwoProduct TwoSum umbilic-point unit unroll UPS UTM UTM/UPS variance velocities Veness Vermeille viewing-frustum Vincenty Visvalingam Visvalingam-Whyatt volume volumetric Web-Mercator Welford WGRS WGS Whyatt Wildberger Witkam winding-number XYZ yaw You zenzi-cubic zenzi-quartic
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Environment :: Console
14
14
  Classifier: Intended Audience :: Developers
@@ -126,10 +126,10 @@ test results (on macOS only) and the complete documentation_ generated by Epydoc
126
126
  Tests
127
127
  =====
128
128
 
129
- The tests ran with Python 3.14.2 (with geographiclib_ 2.1), Python 3.13.9 (with geographiclib_ 2.1,
130
- numpy_ 2.3.3, scipy_ 1.16.2, GeoConvert_ 2.7, GeodSolve_ 2.7 and Geod3Solve_ 2.7), Python 3.12.7 (with
129
+ The tests ran with Python 3.14.2 (with geographiclib_ 2.1), Python 3.13.11 (with geographiclib_ 2.1,
130
+ numpy_ 2.3.3, scipy_ 1.16.2, GeoConvert_ 2.7, GeodSolve_ 2.7 and Geod3Solve_ 2.7), Python 3.12.10 (with
131
131
  geographiclib_ 2.0, numpy_ 2.1.0, scipy_ 1.14.1, GeodSolve_ 2.7, Geod3Solve_ 2.7, IntersectTool_ 2.7
132
- and RhumbSolve_ 2.7), Python 3.11.5 (with geographiclib_ 2.0, numpy_ 1.24.2 and scipy_ 1.10.1) and with
132
+ and RhumbSolve_ 2.7), Python 3.11.9 (with geographiclib_ 2.0, numpy_ 1.24.2 and scipy_ 1.10.1) and with
133
133
  Python 2.7.18 (with geographiclib_ 1.50, numpy_ 1.16.6, scipy_ 1.2.2, GeoConvert_ 2.7, GeodSolve_ 2.7,
134
134
  Geod3Solve_ 2.7, IntersectTool_ 2.7 and RhumbSolve_ 2.7), all on macOS 26.2 Tahoe in 64-bit.
135
135
 
@@ -137,10 +137,10 @@ All tests ran with and without ``lazy import`` for Python 3 and with command lin
137
137
  and env variable ``PYGEODESY_WARNINGS=on`` for all Python versions. The results of those tests are
138
138
  included in the distribution files.
139
139
 
140
- Python 3.14.2, 3.13.9, 3.12.7 and 3.11.5 run on Apple M4 Si (``arm64``), *natively*. Python 2.7.18 runs
140
+ Python 3.14.2, 3.13.11, 3.12.10 and 3.11.9 run on Apple M4 Si (``arm64``), *natively*. Python 2.7.18 runs
141
141
  on Intel (``x86_64``) or Intel *emulation* (\"``arm64_x86_64``\", see function `pygeodesy.machine`_).
142
142
 
143
- Test coverage has been measured with coverage_ 7.10.7 using Python 3.14.2, 3.13.9 and 3.12.7. The
143
+ Test coverage has been measured with coverage_ 7.10.7 using Python 3.14.2, 3.13.11 and 3.12.10. The
144
144
  complete coverage report in HTML and a PDF summary are included in the distribution files.
145
145
 
146
146
  The tests also ran with Python 3.14.2 (and geographiclib_ 2.1) on `Debian 12`_ in 64-bit only and with
@@ -150,7 +150,7 @@ Python 3.13.8 (and geographiclib_ 2.0) on `Windows 2019Server`_ in 64-bit only a
150
150
  A single-File and single-Directory application with ``pygeodesy`` has been bundled using PyInstaller_ 3.4
151
151
  and 64-bit Python 3.7.4 and 3.7.3 on macOS 10.13.6 High Sierra.
152
152
 
153
- Previously, the tests were run with Python 3.13.0-7, 3.12.0-6, 3.11.2-4, 3.10.1-7, 3.9.1, 3.8.7, 3.7.1, 2.7.15,
153
+ Previously, the tests were run with Python 3.13.0-9, 3.12.0-7, 3.11.2-5, 3.10.1-7, 3.9.1, 3.8.7, 3.7.1, 2.7.15,
154
154
  PyPy_ 7.3.12 (Python 3.10.12), 7.3.1 (Python 3.6.9) and PyPy_ 7.1.1 (Python 2.7.13) (and geographiclib_ 1.52,
155
155
  numpy_ 1.16.3, 1.16.4, 1.16.6, 1.19.0, 1.19.4, 1.19.5 or 1.22.4 and scipy_ 1.2.1, 1.4.1, 1.5.2 or 1.8.1) on
156
156
  Ubuntu 16.04, with Python 3.10.0-1, 3.9.0-5, 3.8.0-6, 3.7.2-6, 3.7.0, 3.6.2-5, 3.5.3, 2.7.13-17, 2.7.10
@@ -166,12 +166,12 @@ Server 2012R2, Windows 10 Pro and 32-bit Python 2.6.6 on Windows XP SP3.
166
166
  Notes
167
167
  =====
168
168
 
169
- All Python source code has been statically checked_ with Ruff_ using Python 3.13.9 and with PyChecker_, PyFlakes_,
169
+ All Python source code has been statically checked_ with Ruff_ using Python 3.13.11 and with PyChecker_, PyFlakes_,
170
170
  PyCodeStyle_ (formerly Pep8) and McCabe_ using Python 2.7.18, both in 64-bit on macOS 26.2 Tahoe only.
171
171
 
172
172
  For a summary of all *Karney*-based functionality in ``pygeodesy``, see module karney_.
173
173
 
174
- *Last updated: Dec 31, 2025.*
174
+ *Last updated: Feb 02, 2026.*
175
175
 
176
176
  License
177
177
  =======