pygeodesy 25.12.12__py2.py3-none-any.whl → 26.1.16__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/__init__.py +33 -25
- pygeodesy/albers.py +5 -5
- pygeodesy/cartesianBase.py +2 -2
- pygeodesy/constants.py +8 -1
- pygeodesy/datums.py +5 -8
- pygeodesy/ellipsoids.py +32 -19
- pygeodesy/elliptic.py +532 -139
- pygeodesy/fmath.py +6 -8
- pygeodesy/formy.py +6 -106
- pygeodesy/fsums.py +48 -30
- pygeodesy/geod3solve.py +26 -10
- pygeodesy/geodesici.py +5 -4
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/gxarea.py +53 -23
- pygeodesy/geodsolve.py +4 -3
- pygeodesy/internals.py +10 -3
- pygeodesy/karney.py +21 -36
- pygeodesy/lazily.py +12 -5
- pygeodesy/lcc.py +3 -7
- pygeodesy/named.py +14 -10
- pygeodesy/props.py +5 -3
- pygeodesy/trf.py +2 -4
- pygeodesy/triaxials/bases.py +111 -58
- pygeodesy/triaxials/triaxial3.py +50 -54
- pygeodesy/triaxials/triaxial5.py +17 -49
- pygeodesy/utily.py +7 -7
- {pygeodesy-25.12.12.dist-info → pygeodesy-26.1.16.dist-info}/METADATA +26 -19
- {pygeodesy-25.12.12.dist-info → pygeodesy-26.1.16.dist-info}/RECORD +30 -30
- {pygeodesy-25.12.12.dist-info → pygeodesy-26.1.16.dist-info}/WHEEL +0 -0
- {pygeodesy-25.12.12.dist-info → pygeodesy-26.1.16.dist-info}/top_level.txt +0 -0
pygeodesy/internals.py
CHANGED
|
@@ -6,8 +6,8 @@ u'''Mostly INTERNAL functions, except L{machine}, L{print_} and L{printf}.
|
|
|
6
6
|
# from pygeodesy.basics import isiterablen, ubstr # _MODS
|
|
7
7
|
# from pygeodesy.errors import _AttributeError, _error_init, _ImmutableError, _UnexpectedError, _xError2 # _MODS
|
|
8
8
|
from pygeodesy.interns import _BAR_, _COLON_, _DASH_, _DMAIN_, _DOT_, _ELLIPSIS_, _NL_, NN, \
|
|
9
|
-
_pygeodesy_, _PyPy__, _python_, _QUOTE1_, _QUOTE2_,
|
|
10
|
-
_SPACE_, _UNDER_
|
|
9
|
+
_NLATvar_, _pygeodesy_, _PyPy__, _python_, _QUOTE1_, _QUOTE2_, \
|
|
10
|
+
_s_, _sys, _SPACE_, _UNDER_
|
|
11
11
|
from pygeodesy.interns import _COMMA_, _Python_ # PYCHOK used!
|
|
12
12
|
# from pygeodesy.streprs import anstr, pairs, unstr # _MODS
|
|
13
13
|
|
|
@@ -459,6 +459,13 @@ def _popen2(cmd, stdin=None): # in .mgrs, .solveBase, .testMgrs
|
|
|
459
459
|
return _MODS.basics.ub2str(r).strip(), p.returncode
|
|
460
460
|
|
|
461
461
|
|
|
462
|
+
def _pregistry(registry):
|
|
463
|
+
'''(INTERNAL) Print all items of a C{registry}.
|
|
464
|
+
'''
|
|
465
|
+
t = [NN] + registry.toRepr(all=True, asorted=True).split(_NL_)
|
|
466
|
+
printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
|
|
467
|
+
|
|
468
|
+
|
|
462
469
|
def print_(*args, **nl_nt_prec_prefix__end_file_flush_sep__kwds): # PYCHOK no cover
|
|
463
470
|
'''Python 3+ C{print}-like formatting and printing.
|
|
464
471
|
|
|
@@ -709,7 +716,7 @@ def _versions(sep=_SPACE_):
|
|
|
709
716
|
|
|
710
717
|
|
|
711
718
|
__all__ = tuple(map(typename, (machine, print_, printf, typename)))
|
|
712
|
-
__version__ = '
|
|
719
|
+
__version__ = '26.01.13'
|
|
713
720
|
|
|
714
721
|
if __name__ == _DMAIN_:
|
|
715
722
|
|
pygeodesy/karney.py
CHANGED
|
@@ -153,14 +153,14 @@ in C{pygeodesy} are based on I{Karney}'s post U{Area of a spherical polygon
|
|
|
153
153
|
# make sure int/int division yields float quotient, see .basics
|
|
154
154
|
from __future__ import division as _; del _ # noqa: E702 ;
|
|
155
155
|
|
|
156
|
-
from pygeodesy.basics import _copysign, _isin, isint, neg,
|
|
157
|
-
_xgeographiclib, _zip
|
|
156
|
+
from pygeodesy.basics import _copysign, _isin, isint, neg, _xgeographiclib, _zip
|
|
158
157
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, \
|
|
159
158
|
_0_0, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
160
159
|
# from pygeodesy.deprecated.classes import Rhumb7Tuple # _MODS
|
|
161
160
|
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds
|
|
162
161
|
# from pygeodesy.geod3Solve import Geod3Solve8Tuple # _MODS
|
|
163
|
-
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
162
|
+
from pygeodesy.fmath import cbrt, fhorner, fremainder, norm2
|
|
163
|
+
from pygeodesy.fsums import _Ksum
|
|
164
164
|
from pygeodesy.internals import _getenv, _popen2, _PYGEODESY_ENV, typename, \
|
|
165
165
|
_version_info
|
|
166
166
|
from pygeodesy.interns import NN, _a12_, _area_, _azi2_, _azi12_, _composite_, \
|
|
@@ -177,7 +177,7 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
177
177
|
# from math import fabs # from .utily
|
|
178
178
|
|
|
179
179
|
__all__ = _ALL_LAZY.karney
|
|
180
|
-
__version__ = '25.12.
|
|
180
|
+
__version__ = '25.12.23'
|
|
181
181
|
|
|
182
182
|
_1_16th = _1_0 / 16
|
|
183
183
|
_2_4_ = '2.4'
|
|
@@ -913,20 +913,18 @@ try:
|
|
|
913
913
|
|
|
914
914
|
except ImportError: # Python 3.12-
|
|
915
915
|
|
|
916
|
-
def _poly_fma(x,
|
|
917
|
-
|
|
918
|
-
for c in cs:
|
|
919
|
-
s, t, _ = _sum3(s * x, t * x, c)
|
|
920
|
-
return s + t
|
|
916
|
+
def _poly_fma(x, *cs): # PYCHOK redef
|
|
917
|
+
return fhorner(x, *cs, incx=False)
|
|
921
918
|
|
|
922
919
|
# def _poly_fma(x, s, *cs):
|
|
923
|
-
#
|
|
924
|
-
#
|
|
925
|
-
#
|
|
920
|
+
# t = _0_0
|
|
921
|
+
# for c in cs:
|
|
922
|
+
# s, t, _ = _sum3(s * x, t * x, c)
|
|
923
|
+
# return s + t
|
|
926
924
|
|
|
927
925
|
def _polynomial(x, cs, i, j): # PYCHOK shared
|
|
928
|
-
'''(INTERNAL) Like C++ C{GeographicLib.Math.hpp.polyval} but
|
|
929
|
-
signature and cascaded summation
|
|
926
|
+
'''(INTERNAL) Like C++ C{GeographicLib.Math.hpp.polyval} but
|
|
927
|
+
with a different signature and cascaded summation.
|
|
930
928
|
|
|
931
929
|
@return: M{sum(x**(j - k - 1) * cs[k] for k in range(i, j)}
|
|
932
930
|
'''
|
|
@@ -1007,18 +1005,18 @@ def _sum2(a, b): # mimick geomath.Math.sum, actually sum2
|
|
|
1007
1005
|
r = s - b
|
|
1008
1006
|
t = s - r
|
|
1009
1007
|
# elif C_CPP: # Math::sum C/C++
|
|
1010
|
-
# r -= a; t -= b; t += r; t = -t
|
|
1011
|
-
# else:
|
|
1012
|
-
t = (a - r) + (b - t)
|
|
1008
|
+
# r -= a; t -= b; t += r; t = (-t) if s else s
|
|
1009
|
+
# else: # if s == 0: t = _copysign_0_0(s)
|
|
1010
|
+
t = ((a - r) + (b - t)) if s else s
|
|
1013
1011
|
# assert fabs(s) >= fabs(t)
|
|
1014
1012
|
return s, t
|
|
1015
1013
|
|
|
1016
1014
|
|
|
1017
1015
|
def _sum3(s, t, *xs):
|
|
1018
|
-
'''Accumulate
|
|
1016
|
+
'''Accumulate all B{C{xs}} scalars into a previous C{_sum2(s, t)}.
|
|
1019
1017
|
|
|
1020
1018
|
@return: 3-Tuple C{(s, t, n)} where C{s} is the sum of B{s}, B{t} and all
|
|
1021
|
-
B{xs}, C{t} the residual and C{n} the number of zero C{xs}.
|
|
1019
|
+
B{xs}, C{t} the residual and C{n} the number of non-zero C{xs}.
|
|
1022
1020
|
|
|
1023
1021
|
@see: I{Karney's} C++ U{Accumulator<https://GeographicLib.SourceForge.io/
|
|
1024
1022
|
C++/doc/Accumulator_8hpp_source.html>} comments for more details and
|
|
@@ -1026,23 +1024,10 @@ def _sum3(s, t, *xs):
|
|
|
1026
1024
|
|
|
1027
1025
|
@note: Not "error-free", see C{pygeodesy.test/testKarney.py}.
|
|
1028
1026
|
'''
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
if s:
|
|
1034
|
-
s, t = _sum2(s, t) # -significant end
|
|
1035
|
-
if s:
|
|
1036
|
-
t += r # accumulate r into t
|
|
1037
|
-
else:
|
|
1038
|
-
# assert t == 0 # s == 0 implies t == 0
|
|
1039
|
-
s = unsigned0(r) # result is r, t = 0
|
|
1040
|
-
else:
|
|
1041
|
-
s, t = unsigned0(t), r
|
|
1042
|
-
else:
|
|
1043
|
-
z += 1
|
|
1044
|
-
# assert fabs(s) >= fabs(t)
|
|
1045
|
-
return s, t, z
|
|
1027
|
+
return _Ksum(s, t, *xs)._s_t_n3 if xs else (s, t, 0)
|
|
1028
|
+
# previous _sum3 in .geodesicx.gxarea._Accumulator.Add
|
|
1029
|
+
# which fails .fmath.frandoms tests, but does pass
|
|
1030
|
+
# _sum3(1e20, 1, 2, 100, 5000, -1e20) ... 5103.0, 0.0, 4
|
|
1046
1031
|
|
|
1047
1032
|
|
|
1048
1033
|
def _tand(x):
|
pygeodesy/lazily.py
CHANGED
|
@@ -30,8 +30,8 @@ and line number.
|
|
|
30
30
|
from pygeodesy import internals as _internals, interns as _interns, \
|
|
31
31
|
_isfrozen # DON'T _lazy_import2
|
|
32
32
|
# from pygeodesy.errors import _error_init, _ImmutableError, _xkwds_item2 # _ALL_MODS
|
|
33
|
-
from pygeodesy.internals import _caller3, _envPYGEODESY, _headof, printf,
|
|
34
|
-
|
|
33
|
+
from pygeodesy.internals import _caller3, _envPYGEODESY, _headof, printf, _Property_RO, \
|
|
34
|
+
_tailof, typename, _versions # _getenv, _PYGEODESY_ENV, \
|
|
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_, \
|
|
@@ -234,7 +234,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
234
234
|
'a_f2b', 'a_f_2b', 'b_f2a', 'b_f_2a',
|
|
235
235
|
'e2f', 'e22f',
|
|
236
236
|
'f2e2', 'f2e22', 'f2e32', 'f_2f', 'f2f_', 'f2f2', 'f2n', 'n2e2', 'n2f', 'n2f_'),
|
|
237
|
-
elliptic=_a('Elliptic', 'EllipticError', 'Elliptic3Tuple'
|
|
237
|
+
elliptic=_a('Elliperim', 'Elliptic', 'EllipticError', 'Elliptic3Tuple',
|
|
238
|
+
'elliperim', 'elliperim_'),
|
|
238
239
|
epsg=_a('Epsg', 'EPSGError'),
|
|
239
240
|
errors=_a('AuxError', 'ClipError', 'CrossError', 'GeodesicError', 'IntersectionError',
|
|
240
241
|
'NumPyError', 'LenError', 'LimitError', 'MGRSError',
|
|
@@ -253,7 +254,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
253
254
|
formy=_a('Radical2Tuple',
|
|
254
255
|
'angle2chord', 'antipode', 'antipode_', 'bearing', 'bearing_',
|
|
255
256
|
'chord2angle', 'compassAngle', 'cosineLaw', 'cosineLaw_',
|
|
256
|
-
'
|
|
257
|
+
'equirectangular', 'equirectangular4', 'euclidean', 'euclidean_',
|
|
257
258
|
'excessAbc_', 'excessCagnoli_', 'excessGirard_', 'excessLHuilier_',
|
|
258
259
|
'excessKarney', 'excessKarney_', 'excessQuad', 'excessQuad_',
|
|
259
260
|
'flatLocal', 'flatLocal_', 'flatPolar', 'flatPolar_',
|
|
@@ -517,10 +518,16 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
517
518
|
if _headof(n) == _pygeodesy_:
|
|
518
519
|
yield n, m
|
|
519
520
|
|
|
521
|
+
@_Property_RO
|
|
522
|
+
def _triaxials_triaxial5(self):
|
|
523
|
+
'''(INTERNAL) Get module C{triaxial.triaxials}.
|
|
524
|
+
'''
|
|
525
|
+
return self.triaxials.triaxial5
|
|
526
|
+
|
|
520
527
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
521
528
|
|
|
522
529
|
__all__ = _ALL_LAZY.lazily
|
|
523
|
-
__version__ = '
|
|
530
|
+
__version__ = '26.01.06'
|
|
524
531
|
|
|
525
532
|
|
|
526
533
|
def _ALL_OTHER(*objs):
|
pygeodesy/lcc.py
CHANGED
|
@@ -651,13 +651,9 @@ def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc,
|
|
|
651
651
|
|
|
652
652
|
|
|
653
653
|
if __name__ == _DMAIN_:
|
|
654
|
-
|
|
655
|
-
from pygeodesy.
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
# __doc__ of this file, force all into registery
|
|
659
|
-
t = _NL_ + Conics.toRepr(all=True, asorted=True)
|
|
660
|
-
printf(_NLATvar_.join(t.split(_NL_)))
|
|
654
|
+
# __doc__ of this file, force all into registry
|
|
655
|
+
from pygeodesy.internals import _pregistry
|
|
656
|
+
_pregistry(Conics)
|
|
661
657
|
|
|
662
658
|
# **) MIT License
|
|
663
659
|
#
|
pygeodesy/named.py
CHANGED
|
@@ -35,7 +35,7 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
|
|
|
35
35
|
# from pygeodesy.units import _toUnit # _MODS
|
|
36
36
|
|
|
37
37
|
__all__ = _ALL_LAZY.named
|
|
38
|
-
__version__ = '
|
|
38
|
+
__version__ = '26.01.14'
|
|
39
39
|
|
|
40
40
|
_COMMANL_ = _COMMA_ + _NL_
|
|
41
41
|
_COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
|
|
@@ -658,18 +658,24 @@ class _NamedEnum(_NamedDict):
|
|
|
658
658
|
'''(INTERNAL) Check attribute name against given, registered name.
|
|
659
659
|
'''
|
|
660
660
|
pypy = _isPyPy()
|
|
661
|
-
_isa = isinstance
|
|
662
661
|
for n, v in kwds.items():
|
|
663
|
-
if
|
|
662
|
+
if isinstance(v, _LazyNamedEnumItem): # property
|
|
664
663
|
assert (n == v.name) if pypy else (n is v.name)
|
|
665
664
|
# assert not hasattr(self.__class__, n)
|
|
666
665
|
setattr(self.__class__, n, v)
|
|
667
|
-
elif
|
|
666
|
+
elif isinstance(v, self._item_Classes): # PYCHOK no cover
|
|
668
667
|
assert self[n] is v and getattr(self, n) \
|
|
669
668
|
and self.find(v) == n
|
|
670
669
|
else:
|
|
671
670
|
raise _TypeError(v, name=n)
|
|
672
671
|
|
|
672
|
+
def _asserts(self): # in .triaxials.triaxial3
|
|
673
|
+
'''(INTERNAL) Yield all asserted items.
|
|
674
|
+
'''
|
|
675
|
+
for n, p in tuple(type(self).__dict__.items()):
|
|
676
|
+
if isinstance(p, _LazyNamedEnumItem):
|
|
677
|
+
yield n, p
|
|
678
|
+
|
|
673
679
|
def find(self, item, dflt=None, all=False):
|
|
674
680
|
'''Find a registered item.
|
|
675
681
|
|
|
@@ -707,10 +713,8 @@ class _NamedEnum(_NamedDict):
|
|
|
707
713
|
case-insensitive} order (C{bool}).
|
|
708
714
|
'''
|
|
709
715
|
if all: # instantiate any remaining L{_LazyNamedEnumItem}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if _isa(p, _LazyNamedEnumItem):
|
|
713
|
-
_ = getattr(self, n)
|
|
716
|
+
for n, _ in self._asserts():
|
|
717
|
+
_ = getattr(self, n)
|
|
714
718
|
return itemsorted(self) if asorted else ADict.items(self)
|
|
715
719
|
|
|
716
720
|
def keys(self, **all_asorted):
|
|
@@ -857,7 +861,7 @@ def _lazyNamedEnumItem(name, *args, **kwds):
|
|
|
857
861
|
|
|
858
862
|
|
|
859
863
|
class _NamedEnumItem(_NamedBase):
|
|
860
|
-
'''(INTERNAL) Base class for items in a C{_NamedEnum}
|
|
864
|
+
'''(INTERNAL) Base class for items in a C{_NamedEnum} registry.
|
|
861
865
|
'''
|
|
862
866
|
_enum = None
|
|
863
867
|
|
|
@@ -1188,7 +1192,7 @@ def callername(up=1, dflt=NN, source=False, underOK=False):
|
|
|
1188
1192
|
|
|
1189
1193
|
@return: The callable name (C{str}) or B{C{dflt}} if none found.
|
|
1190
1194
|
'''
|
|
1191
|
-
try: # see .
|
|
1195
|
+
try: # see .internals._caller3
|
|
1192
1196
|
for u in range(up, up + 32):
|
|
1193
1197
|
n, f, s = _caller3(u)
|
|
1194
1198
|
if n and (underOK or n.startswith(_DUNDER_) or
|
pygeodesy/props.py
CHANGED
|
@@ -26,7 +26,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
|
26
26
|
from functools import wraps as _wraps
|
|
27
27
|
|
|
28
28
|
__all__ = _ALL_LAZY.props
|
|
29
|
-
__version__ = '25.
|
|
29
|
+
__version__ = '25.12.31'
|
|
30
30
|
|
|
31
31
|
_class_ = 'class'
|
|
32
32
|
_DNL_ = _NL_ * 2 # PYCHOK used!
|
|
@@ -696,8 +696,10 @@ class DeprecationWarnings(object):
|
|
|
696
696
|
'''
|
|
697
697
|
return self._Warnings if _WARNINGS_X_DEV else None
|
|
698
698
|
|
|
699
|
-
|
|
700
|
-
|
|
699
|
+
if not _FOR_DOCS: # PYCHOK force epydoc
|
|
700
|
+
DeprecationWarnings = DeprecationWarnings() # singleton
|
|
701
|
+
_throwarning = DeprecationWarnings.throw
|
|
702
|
+
# del _FOR_DOCS
|
|
701
703
|
|
|
702
704
|
# **) MIT License
|
|
703
705
|
#
|
pygeodesy/trf.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
u'''I{Veness}' Terrestrial Reference Frames (TRF).
|
|
5
|
-
|
|
6
|
-
Classes L{RefFrame}, registry L{RefFrames} and L{TRFError}.
|
|
4
|
+
u'''I{Veness}' Terrestrial Reference Frames (TRF), classes L{RefFrame}, registry L{RefFrames} and L{TRFError}.
|
|
7
5
|
|
|
8
6
|
Transcoded from I{Chris Veness'} (C) 2006-2024 JavaScript originals U{latlon-ellipsoidal-referenceframe.js
|
|
9
7
|
<https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-ellipsoidal-referenceframe.js>} and
|
|
@@ -1756,7 +1754,7 @@ if __name__ == _DMAIN_:
|
|
|
1756
1754
|
t = '%d,%3d,%3d' % t
|
|
1757
1755
|
printf('# %s = %s = %s %s', f, e, t, x)
|
|
1758
1756
|
|
|
1759
|
-
# __doc__ of this file, force all into
|
|
1757
|
+
# __doc__ of this file, force all into registry
|
|
1760
1758
|
def _RFs():
|
|
1761
1759
|
yield NN
|
|
1762
1760
|
for t in RefFrames.toRepr(all=True).split(_NL_):
|
pygeodesy/triaxials/bases.py
CHANGED
|
@@ -36,29 +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,
|
|
40
|
-
_isfinite, float0_,
|
|
41
|
-
|
|
42
|
-
# from pygeodesy.
|
|
43
|
-
# from pygeodesy.
|
|
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
|
+
# from pygeodesy.internals import typename # _MODS
|
|
47
48
|
from pygeodesy.interns import _a_, _b_, _c_, _inside_, _not_, _NOTEQUAL_, _null_, \
|
|
48
49
|
_outside_, _scale_, _SPACE_, _spherical_, _x_, _y_, _z_
|
|
49
|
-
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
50
|
-
from pygeodesy.named import _NamedEnumItem, _NamedTuple, _Pass
|
|
50
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
|
|
51
|
+
from pygeodesy.named import _NamedEnum, _NamedEnumItem, _NamedTuple, _Pass # _MODS
|
|
51
52
|
from pygeodesy.namedTuples import Vector4Tuple
|
|
52
53
|
from pygeodesy.props import Property_RO, property_doc_, property_RO, property_ROver
|
|
54
|
+
# from pygeodesy.streprs import Fmt # _MODS
|
|
53
55
|
from pygeodesy.units import Degrees, Easting, Float, Height, Height_, Meter2, Meter3, \
|
|
54
56
|
Northing, Radius_, Scalar
|
|
55
|
-
from pygeodesy.utily import asin1
|
|
57
|
+
from pygeodesy.utily import asin1, km2m, m2km, _ValueError, _xkwds
|
|
56
58
|
from pygeodesy.vector3d import _otherV3d, Vector3d
|
|
57
59
|
|
|
58
60
|
# from math import fabs, sqrt # from .fmath
|
|
59
61
|
|
|
60
62
|
__all__ = _ALL_LAZY.triaxials_bases
|
|
61
|
-
__version__ = '
|
|
63
|
+
__version__ = '26.01.14'
|
|
62
64
|
|
|
63
65
|
_bet_ = 'bet' # PYCHOK shared
|
|
64
66
|
_llk_ = 'llk' # PYCHOK shared
|
|
@@ -112,21 +114,42 @@ class LLK(object):
|
|
|
112
114
|
_NOIDAL = (None, ELLIPSOIDAL)
|
|
113
115
|
# _XCLUDE = (CONFORMAL, GEOGRAPHIC, PLANETOCENTRIC, PLANETODETIC)
|
|
114
116
|
|
|
117
|
+
def __getitem__(self, name):
|
|
118
|
+
llk = self.get(name, None)
|
|
119
|
+
if llk is None:
|
|
120
|
+
t = _MODS.internals.typename(self)
|
|
121
|
+
t = _MODS.streprs.Fmt.SQUARE(t, name)
|
|
122
|
+
raise _ValueError(t, name)
|
|
123
|
+
return llk
|
|
124
|
+
|
|
125
|
+
def get(self, name, dflt=None):
|
|
126
|
+
'''Get an C{LLK} by C{name}.
|
|
127
|
+
'''
|
|
128
|
+
llk = getattr(self, name, None)
|
|
129
|
+
return llk if isinstance(llk, _LLK) else dflt
|
|
130
|
+
|
|
115
131
|
def items(self):
|
|
132
|
+
'''Yield all C{LLK (name, value)} pairs.
|
|
133
|
+
'''
|
|
116
134
|
for n, llk in LLK.__class__.__dict__.items():
|
|
117
135
|
if isinstance(llk, _LLK):
|
|
118
136
|
yield n, llk
|
|
119
137
|
|
|
120
138
|
def keys(self):
|
|
139
|
+
'''Yield all C{LLK} names.
|
|
140
|
+
'''
|
|
121
141
|
for n, _ in self.items():
|
|
122
142
|
yield n
|
|
123
143
|
|
|
124
144
|
def values(self):
|
|
145
|
+
'''Yield all C{LLK} values.
|
|
146
|
+
'''
|
|
125
147
|
for _, llk in self.items():
|
|
126
148
|
yield llk
|
|
127
149
|
|
|
128
|
-
|
|
129
|
-
#
|
|
150
|
+
if not _FOR_DOCS: # PYCHOK force epydoc
|
|
151
|
+
LLK = LLK() # singleton
|
|
152
|
+
del _FOR_DOCS
|
|
130
153
|
|
|
131
154
|
|
|
132
155
|
def _HeightINT0(h):
|
|
@@ -212,13 +235,6 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
212
235
|
a, b, c = self._abc3
|
|
213
236
|
return self.a2, self.b2, self.c2
|
|
214
237
|
|
|
215
|
-
@Property_RO
|
|
216
|
-
def _ab_elliperim(self):
|
|
217
|
-
'''(INTERNAL) Get C{ab} ellipse' perimeter.
|
|
218
|
-
'''
|
|
219
|
-
a, b, _ = self._abc3
|
|
220
|
-
return elliperim(a, b)
|
|
221
|
-
|
|
222
238
|
@Property_RO
|
|
223
239
|
def _a2c2(self):
|
|
224
240
|
'''(INTERNAL) Get C{a**2 - c**2} == E_sub_x**2.
|
|
@@ -279,13 +295,6 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
279
295
|
d = b - c
|
|
280
296
|
return (d * (b + c)) if d else _0_0
|
|
281
297
|
|
|
282
|
-
@Property_RO
|
|
283
|
-
def _bc_elliperim(self):
|
|
284
|
-
'''(INTERNAL) Get C{bc} ellipse' perimeter.
|
|
285
|
-
'''
|
|
286
|
-
_, b, c = self._abc3
|
|
287
|
-
return elliperim(b, c)
|
|
288
|
-
|
|
289
298
|
@Property_RO
|
|
290
299
|
def c(self):
|
|
291
300
|
'''Get the C{smallest, z} semi-axis (C{meter}, same units as B{C{a}}).
|
|
@@ -339,13 +348,13 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
339
348
|
|
|
340
349
|
@property_ROver
|
|
341
350
|
def _Ellipsoid(self):
|
|
342
|
-
'''(INTERNAL) Get class
|
|
351
|
+
'''(INTERNAL) Get class C{Ellipsoid}, I{once}.
|
|
343
352
|
'''
|
|
344
353
|
return _MODS.ellipsoids.Ellipsoid # overwrite property_ROver
|
|
345
354
|
|
|
346
355
|
@property_ROver
|
|
347
356
|
def _Elliptic(self):
|
|
348
|
-
'''(INTERNAL) Get class
|
|
357
|
+
'''(INTERNAL) Get class C{Ellipsoid}, I{once}.
|
|
349
358
|
'''
|
|
350
359
|
return _MODS.elliptic.Elliptic # overwrite property_ROver
|
|
351
360
|
|
|
@@ -355,15 +364,14 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
355
364
|
|
|
356
365
|
@see: Function L{hartzell4<triaxials.triaxial5.hartzell4>} for further details.
|
|
357
366
|
'''
|
|
358
|
-
return
|
|
367
|
+
return _MODS.triaxials.hartzell4(pov, los=los, tri_biax=self, **name)
|
|
359
368
|
|
|
360
369
|
def height4(self, x_xyz, y=None, z=None, normal=True, eps=EPS, **name):
|
|
361
370
|
'''Compute the projection on and the height above or below this triaxial's surface.
|
|
362
371
|
|
|
363
372
|
@see: Function L{height4<triaxials.triaxial5.height4>} for further details.
|
|
364
373
|
'''
|
|
365
|
-
|
|
366
|
-
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)
|
|
367
375
|
|
|
368
376
|
@Property_RO
|
|
369
377
|
def isOrdered(self):
|
|
@@ -513,6 +521,27 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
513
521
|
'''
|
|
514
522
|
return self._kji if reverse else self._ijk
|
|
515
523
|
|
|
524
|
+
@Property_RO
|
|
525
|
+
def perimeter4ab(self):
|
|
526
|
+
'''Get the C{ab} ellipse' perimeter (C{scalar}).
|
|
527
|
+
'''
|
|
528
|
+
a, b, _ = self._abc3
|
|
529
|
+
return Float(perimeter4ab=_MODS.elliptic.elliperim(a, b))
|
|
530
|
+
|
|
531
|
+
@Property_RO
|
|
532
|
+
def perimeter4ac(self):
|
|
533
|
+
'''Get the C{ac} ellipse' perimeter (C{scalar}).
|
|
534
|
+
'''
|
|
535
|
+
a, _, c = self._abc3
|
|
536
|
+
return Float(perimeter4ac=_MODS.elliptic.elliperim(a, c))
|
|
537
|
+
|
|
538
|
+
@Property_RO
|
|
539
|
+
def perimeter4bc(self):
|
|
540
|
+
'''Get the C{bc} ellipse' perimeter (C{scalar}).
|
|
541
|
+
'''
|
|
542
|
+
_, b, c = self._abc3
|
|
543
|
+
return Float(perimeter4bc=_MODS.elliptic.elliperim(b, c))
|
|
544
|
+
|
|
516
545
|
def _radialTo3(self, sbeta, cbeta, somega, comega):
|
|
517
546
|
'''(INTERNAL) I{Unordered} helper for C{.height4}.
|
|
518
547
|
'''
|
|
@@ -595,42 +624,24 @@ class _UnOrderedTriaxialBase(_NamedEnumItem):
|
|
|
595
624
|
@return: This C{Triaxial}'s attributes (C{str}).
|
|
596
625
|
'''
|
|
597
626
|
T = _UnOrderedTriaxialBase
|
|
598
|
-
|
|
627
|
+
m = _MODS.triaxials
|
|
628
|
+
C = m.Triaxial3B
|
|
599
629
|
if isinstance(self, C):
|
|
600
|
-
t =
|
|
630
|
+
t = T.b, C.e2, C.k2, C.kp2
|
|
601
631
|
else:
|
|
602
|
-
t =
|
|
603
|
-
C =
|
|
632
|
+
t = T.a, # props
|
|
633
|
+
C = m.ConformalSphere
|
|
604
634
|
t += (C.ab, C.bc) if isinstance(self, C) else (T.b, T.c)
|
|
605
635
|
C = _Triaxial3Base
|
|
606
636
|
t += (C.k2, C.kp2) if isinstance(self, C) else \
|
|
607
637
|
(T.e2ab, T.e2bc, T.e2ac)
|
|
608
|
-
for C in (
|
|
609
|
-
self._triaxials_conformal3.Conformal3):
|
|
638
|
+
for C in (m.Conformal, m.Conformal3):
|
|
610
639
|
if isinstance(self, C):
|
|
611
640
|
t += C.xyQ2,
|
|
612
641
|
break
|
|
613
642
|
t += T.volume, T.area
|
|
614
643
|
return self._instr(area_p=self.area_p(), prec=prec, props=t, **name)
|
|
615
644
|
|
|
616
|
-
@property_ROver
|
|
617
|
-
def _triaxials_conformal3(self):
|
|
618
|
-
'''(INTERNAL) Get module L{pygeodesy.triaxials.conformal3}, I{once}.
|
|
619
|
-
'''
|
|
620
|
-
return _MODS.triaxials.conformal3 # overwrite property_ROver
|
|
621
|
-
|
|
622
|
-
@property_ROver
|
|
623
|
-
def _triaxials_triaxial3(self):
|
|
624
|
-
'''(INTERNAL) Get module L{pygeodesy.triaxials.triaxial3}, I{once}.
|
|
625
|
-
'''
|
|
626
|
-
return _MODS.triaxials.triaxial3 # overwrite property_ROver
|
|
627
|
-
|
|
628
|
-
@property_ROver
|
|
629
|
-
def _triaxials_triaxial5(self):
|
|
630
|
-
'''(INTERNAL) Get module L{pygeodesy.triaxials.triaxial5}, I{once}.
|
|
631
|
-
'''
|
|
632
|
-
return _MODS.triaxials.triaxial5 # overwrite property_ROver
|
|
633
|
-
|
|
634
645
|
@Property_RO
|
|
635
646
|
def unOrdered(self):
|
|
636
647
|
'''Is this triaxial I{un-ordered} and I{not spherical} (C{bool})?
|
|
@@ -693,7 +704,7 @@ class _OrderedTriaxialBase(_UnOrderedTriaxialBase):
|
|
|
693
704
|
aE.fF(r) * c2 / s)
|
|
694
705
|
a = Meter2(area=a * b * PI2)
|
|
695
706
|
else: # a == b > c
|
|
696
|
-
a =
|
|
707
|
+
a = self._Ellipsoid(a, b=c).areax
|
|
697
708
|
return a
|
|
698
709
|
|
|
699
710
|
@Property_RO
|
|
@@ -827,7 +838,8 @@ class _Triaxial3Base(_OrderedTriaxialBase):
|
|
|
827
838
|
@property_doc_(" longitude of the I{earth}'s major semi-axis C{a}, (L{Ang}), Karney's C{Triaxial_Earth_lon0}.")
|
|
828
839
|
def Lon0(self):
|
|
829
840
|
if self._Lon0 is None:
|
|
830
|
-
|
|
841
|
+
WGS84_3 = self.name.startswith('WGS84_3')
|
|
842
|
+
self.Lon0 = -(1493 / 100) if WGS84_3 else 0
|
|
831
843
|
return self._Lon0
|
|
832
844
|
|
|
833
845
|
@Lon0.setter # PYCHOK setter!
|
|
@@ -863,11 +875,52 @@ class _Triaxial3Base(_OrderedTriaxialBase):
|
|
|
863
875
|
|
|
864
876
|
|
|
865
877
|
class TriaxialError(_ValueError):
|
|
866
|
-
'''Raised for any
|
|
878
|
+
'''Raised for any triaxial issue.
|
|
867
879
|
'''
|
|
868
880
|
pass # ...
|
|
869
881
|
|
|
870
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
|
+
|
|
871
924
|
def _getitems(items, *indices):
|
|
872
925
|
'''(INTERNAL) Get the C{items} at the given I{indices}.
|
|
873
926
|
|