pygeodesy 25.1.9__py2.py3-none-any.whl → 25.4.25__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 +35 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +59 -40
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +9 -7
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +13 -13
- pygeodesy/auxilats/auxily.py +13 -9
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +65 -22
- pygeodesy/booleans.py +12 -10
- pygeodesy/cartesianBase.py +21 -20
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +10 -7
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +167 -138
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +9 -9
- pygeodesy/fmath.py +10 -9
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +107 -122
- pygeodesy/gars.py +7 -7
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +12 -10
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +7 -8
- pygeodesy/geoids.py +35 -34
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +31 -46
- pygeodesy/interns.py +12 -9
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +73 -66
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +14 -18
- pygeodesy/lazily.py +73 -74
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +8 -7
- pygeodesy/ltpTuples.py +2 -2
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +47 -31
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +11 -10
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +14 -14
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +88 -18
- pygeodesy/vector2d.py +18 -11
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +35 -31
- pygeodesy-25.4.25.dist-info/RECORD +118 -0
- pygeodesy-25.1.9.dist-info/RECORD +0 -118
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/auxilats/__main__.py
CHANGED
|
@@ -5,23 +5,22 @@ u'''Print L{auxilats} version, etc. using C{python -m pygeodesy.auxilats}.
|
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
7
|
__all__ = ()
|
|
8
|
-
__version__ = '
|
|
8
|
+
__version__ = '25.04.14'
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _main(**ALorder): # PYCHOK no cover
|
|
12
12
|
|
|
13
13
|
try:
|
|
14
|
-
from pygeodesy import auxilats
|
|
14
|
+
from pygeodesy import ADict, auxilats
|
|
15
15
|
from pygeodesy.internals import _fper, _name_version, \
|
|
16
16
|
printf, _versions
|
|
17
|
-
from pygeodesy.interns import _COMMASPACE_
|
|
17
|
+
from pygeodesy.interns import _COMMASPACE_
|
|
18
18
|
|
|
19
19
|
A = auxilats.AuxLat(**ALorder)
|
|
20
20
|
Cx = A._CXcoeffs # PropertyRO: Adict of _Rdicts
|
|
21
21
|
b, n, u, z = Cx.bnuz4()
|
|
22
|
-
p
|
|
23
|
-
|
|
24
|
-
p = list(_EQUAL_(*t) for t in p.items())
|
|
22
|
+
p = ADict(ALorder=A.ALorder, CXb=b, CXb_z=_fper(b, z),
|
|
23
|
+
CXn=n, CXu=u, CXu_n=_fper(u, n))._toL()
|
|
25
24
|
try:
|
|
26
25
|
import geographiclib
|
|
27
26
|
p.append(_name_version(geographiclib))
|
|
@@ -36,9 +35,12 @@ def _main(**ALorder): # PYCHOK no cover
|
|
|
36
35
|
print(_usage(__file__))
|
|
37
36
|
|
|
38
37
|
|
|
39
|
-
from sys import argv # .internals.
|
|
38
|
+
from sys import argv # .internals._isPyChOK
|
|
40
39
|
_main(ALorder=int(argv[1])) if len(argv) == 2 and argv[1].isdigit() else _main()
|
|
41
40
|
|
|
41
|
+
# % python3.13 -m pygeodesy.auxilats
|
|
42
|
+
# pygeodesy.auxilats 25.04.14: ALorder=6, CXb=11099, CXb_z=64.1%, CXn=522, CXu=448, CXu_n=85.8%, geographiclib 2.0 (pygeodesy 25.4.24 Python 3.13.3 64bit arm64 macOS 15.4)
|
|
43
|
+
|
|
42
44
|
# % python3.12 -m pygeodesy.auxilats 8
|
|
43
45
|
# pygeodesy.auxilats 24.09.04: ALorder=8, CXb=20310, CXb_z=71.5%, CXn=888, CXu=780, CXu_n=87.8%, geographiclib 2.0 (pygeodesy 24.9.9 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
44
46
|
|
pygeodesy/auxilats/auxAngle.py
CHANGED
|
@@ -32,7 +32,7 @@ from pygeodesy.utily import atan2, atan2d, sincos2, sincos2d
|
|
|
32
32
|
from math import asinh, copysign, degrees, fabs, radians, sinh
|
|
33
33
|
|
|
34
34
|
__all__ = ()
|
|
35
|
-
__version__ = '
|
|
35
|
+
__version__ = '25.04.14'
|
|
36
36
|
|
|
37
37
|
_0_INF_NAN_NINF = (0, _0_0) + _INF_NAN_NINF
|
|
38
38
|
_MAX_2 = MAX * _0_5 # PYCHOK used!
|
|
@@ -207,7 +207,7 @@ class AuxAngle(_Named):
|
|
|
207
207
|
def _copy_2(self, which):
|
|
208
208
|
'''(INTERNAL) Copy for I{dyadic} operators.
|
|
209
209
|
'''
|
|
210
|
-
return _Named.copy(self, deep=False,
|
|
210
|
+
return _Named.copy(self, deep=False, name__=which)
|
|
211
211
|
|
|
212
212
|
def _copy_r2(self, other, which):
|
|
213
213
|
'''(INTERNAL) Copy for I{reverse-dyadic} operators.
|
pygeodesy/auxilats/auxLat.py
CHANGED
|
@@ -9,8 +9,8 @@ Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-2024) and lice
|
|
|
9
9
|
under the MIT/X11 License. For more information, see the U{GeographicLib
|
|
10
10
|
<https://GeographicLib.SourceForge.io>} documentation.
|
|
11
11
|
|
|
12
|
-
@see: U{Auxiliary latitudes<https
|
|
13
|
-
U{On auxiliary latitudes<https
|
|
12
|
+
@see: U{Auxiliary latitudes<https://GeographicLib.SourceForge.io/C++/doc/auxlat.html>}
|
|
13
|
+
U{On auxiliary latitudes<https://ArXiv.org/abs/2212.05818>}.
|
|
14
14
|
'''
|
|
15
15
|
# make sure int/int division yields float quotient, see .basics
|
|
16
16
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
@@ -18,8 +18,8 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
18
18
|
from pygeodesy.auxilats.auxAngle import AuxAngle, AuxBeta, AuxChi, _AuxClass, \
|
|
19
19
|
AuxMu, AuxPhi, AuxTheta, AuxXi
|
|
20
20
|
from pygeodesy.auxilats.auxily import Aux, _sc, _sn
|
|
21
|
-
from pygeodesy.auxilats._CX_Rs import _Rdict, _Rtuple
|
|
22
|
-
from pygeodesy.basics import _reverange, _xinstanceof, _passarg
|
|
21
|
+
from pygeodesy.auxilats._CX_Rs import _Rdict, _Rkey, _Rtuple
|
|
22
|
+
from pygeodesy.basics import _isin, _reverange, _xinstanceof, _passarg
|
|
23
23
|
from pygeodesy.constants import INF, MAX_EXP, MIN_EXP, NAN, PI_2, PI_4, _EPSqrt, \
|
|
24
24
|
_0_0, _0_0s, _0_1, _0_5, _1_0, _2_0, _3_0, _360_0, \
|
|
25
25
|
_log2, _over, isfinite, isinf, isnan
|
|
@@ -48,7 +48,7 @@ except ImportError: # Python 3.11-
|
|
|
48
48
|
return pow(_2_0, x)
|
|
49
49
|
|
|
50
50
|
__all__ = ()
|
|
51
|
-
__version__ = '
|
|
51
|
+
__version__ = '25.04.14'
|
|
52
52
|
|
|
53
53
|
_TRIPS = 1024 # XXX 2 or 3?
|
|
54
54
|
|
|
@@ -90,7 +90,7 @@ class AuxLat(AuxAngle):
|
|
|
90
90
|
else:
|
|
91
91
|
name = NN
|
|
92
92
|
try:
|
|
93
|
-
if
|
|
93
|
+
if not _isin(a_earth, _EWGS84, _WGS84):
|
|
94
94
|
n = _name__(name, name__=AuxLat)
|
|
95
95
|
if b is f is None:
|
|
96
96
|
E = _ellipsoidal_datum(a_earth, name=n).ellipsoid # XXX raiser=_earth_
|
|
@@ -829,16 +829,16 @@ def _Newton(tphi, Zeta, _toZeta, **name):
|
|
|
829
829
|
|
|
830
830
|
|
|
831
831
|
_AR2Coeffs = _Rdict(18,
|
|
832
|
-
_Rtuple(4, 4, '4/315, 4/105, 4/15, -1/3'),
|
|
833
|
-
_Rtuple(6, 6, '4/1287, 4/693, 4/15, 4/105, 4/315, -1/3'),
|
|
834
|
-
_Rtuple(8, 8, '4/3315, 4/2145, 4/1287, 4/693, 4/315, 4/105, 4/15, -1/3'))
|
|
832
|
+
_Rtuple(_Rkey(4), 4, '4/315, 4/105, 4/15, -1/3'),
|
|
833
|
+
_Rtuple(_Rkey(6), 6, '4/1287, 4/693, 4/15, 4/105, 4/315, -1/3'),
|
|
834
|
+
_Rtuple(_Rkey(8), 8, '4/3315, 4/2145, 4/1287, 4/693, 4/315, 4/105, 4/15, -1/3'))
|
|
835
835
|
|
|
836
836
|
_RRCoeffs = _Rdict(9,
|
|
837
|
-
_Rtuple(4, 2, '1/64, 1/4'),
|
|
838
|
-
_Rtuple(6, 3, '1/256, 1/64, 1/4'),
|
|
839
|
-
_Rtuple(8, 4, '25/16384, 1/256, 1/64, 1/4')) # PYCHOK used!
|
|
837
|
+
_Rtuple(_Rkey(4), 2, '1/64, 1/4'),
|
|
838
|
+
_Rtuple(_Rkey(6), 3, '1/256, 1/64, 1/4'),
|
|
839
|
+
_Rtuple(_Rkey(8), 4, '25/16384, 1/256, 1/64, 1/4')) # PYCHOK used!
|
|
840
840
|
|
|
841
|
-
del _Rdict, _Rtuple
|
|
841
|
+
del _Rdict, _Rkey, _Rtuple
|
|
842
842
|
# assert set(_AR2Coeffs.keys()) == set(_RRCoeffs.keys())
|
|
843
843
|
|
|
844
844
|
# AuxLat._Lmax = max(_AR2Coeffs.keys()) # == max(ALorder)
|
pygeodesy/auxilats/auxily.py
CHANGED
|
@@ -15,10 +15,13 @@ under the MIT/X11 License. For more information, see the U{GeographicLib
|
|
|
15
15
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
16
16
|
|
|
17
17
|
# from pygeodesy import auxilats # _MODS
|
|
18
|
+
from pygeodesy.auxilats._CX_Rs import _Rkey
|
|
19
|
+
from pygeodesy.basics import _isin, typename
|
|
18
20
|
from pygeodesy.constants import INF, NAN, isinf, isnan, _0_0, _0_5, _1_0, \
|
|
19
21
|
_copysign_1_0, _over, _1_over
|
|
20
22
|
from pygeodesy.errors import AuxError
|
|
21
23
|
from pygeodesy.fmath import hypot1 as _sc, hypot2_
|
|
24
|
+
# from pygeodesy.internals import typename # from .basics
|
|
22
25
|
from pygeodesy.interns import NN, _DOT_, _UNDER_ # PYCHOK used!
|
|
23
26
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS # PYCHOK used!
|
|
24
27
|
from pygeodesy.utily import atan1
|
|
@@ -26,19 +29,19 @@ from pygeodesy.utily import atan1
|
|
|
26
29
|
from math import asinh, copysign
|
|
27
30
|
|
|
28
31
|
__all__ = ()
|
|
29
|
-
__version__ = '
|
|
32
|
+
__version__ = '25.04.14'
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
class Aux(object):
|
|
33
36
|
'''Enum-style Aux names.
|
|
34
37
|
'''
|
|
35
38
|
_coeffs = {}
|
|
36
|
-
GEOGRAPHIC = PHI =
|
|
37
|
-
PARAMETRIC = BETA =
|
|
38
|
-
GEOCENTRIC = THETA = 2 # all ...
|
|
39
|
-
RECTIFYING = MU = 3 # use n^2
|
|
40
|
-
CONFORMAL = CHI = 4 # use n
|
|
41
|
-
AUTHALIC = XI = 5 # use n
|
|
39
|
+
GEOGRAPHIC = PHI = GEODETIC = _Rkey(0)
|
|
40
|
+
PARAMETRIC = BETA = REDUCED = _Rkey(1)
|
|
41
|
+
GEOCENTRIC = THETA = _Rkey(2) # all ...
|
|
42
|
+
RECTIFYING = MU = _Rkey(3) # use n^2
|
|
43
|
+
CONFORMAL = CHI = _Rkey(4) # use n
|
|
44
|
+
AUTHALIC = XI = _Rkey(5) # use n
|
|
42
45
|
N = 6
|
|
43
46
|
N2 = 36
|
|
44
47
|
|
|
@@ -57,7 +60,7 @@ class Aux(object):
|
|
|
57
60
|
_coeffs = Aux._coeffs[aL]
|
|
58
61
|
except KeyError:
|
|
59
62
|
try: # from pygeodesy.auxilats._CX_x import _coeffs_x as _coeffs
|
|
60
|
-
_CX_x = _DOT_(_MODS.auxilats
|
|
63
|
+
_CX_x = _DOT_(typename(_MODS.auxilats), _UNDER_('_CX', aL))
|
|
61
64
|
_coeffs = _MODS.getattr(_CX_x, _UNDER_('_coeffs', aL))
|
|
62
65
|
except (AttributeError, ImportError, KeyError, TypeError) as x:
|
|
63
66
|
raise AuxError(ALorder=aL, cause=x)
|
|
@@ -91,7 +94,7 @@ class Aux(object):
|
|
|
91
94
|
return (auxout - auxin) if max(auxin, auxout) < Aux.MU else None
|
|
92
95
|
|
|
93
96
|
def use_n2(self, aux):
|
|
94
|
-
return
|
|
97
|
+
return not _isin(aux, Aux.CHI, Aux.XI)
|
|
95
98
|
|
|
96
99
|
Aux = Aux() # PYCHOK singleton
|
|
97
100
|
|
|
@@ -228,6 +231,7 @@ def _sn(tx):
|
|
|
228
231
|
|
|
229
232
|
|
|
230
233
|
__all__ += _ALL_DOCS(Aux.__class__)
|
|
234
|
+
del _Rkey
|
|
231
235
|
|
|
232
236
|
# **) MIT License
|
|
233
237
|
#
|
pygeodesy/azimuthal.py
CHANGED
|
@@ -42,19 +42,20 @@ altitude in Earth radii<https://WikiPedia.org/wiki/Azimuthal_equidistant_project
|
|
|
42
42
|
# make sure int/int division yields float quotient, see .basics
|
|
43
43
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
44
44
|
|
|
45
|
-
# from pygeodesy.basics import _xinstanceof # from .ellipsoidalBase
|
|
45
|
+
# from pygeodesy.basics import _isin, _xinstanceof # from .ellipsoidalBase
|
|
46
46
|
from pygeodesy.constants import EPS, EPS0, EPS1, NAN, isnon0, _umod_360, \
|
|
47
47
|
_EPStol, _0_0, _0_1, _0_5, _1_0, _N_1_0, _2_0
|
|
48
48
|
from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB, \
|
|
49
|
-
|
|
49
|
+
_isin, _xinstanceof
|
|
50
50
|
from pygeodesy.datums import _spherical_datum, _WGS84
|
|
51
51
|
from pygeodesy.errors import _ValueError, _xdatum, _xkwds
|
|
52
52
|
from pygeodesy.fmath import euclid, fdot_, hypot as _hypot, Fsum
|
|
53
53
|
# from pygeodesy.fsums import Fsum # from .fmath
|
|
54
54
|
# from pygeodesy.formy import antipode # _MODS
|
|
55
|
+
# from pygeodesy.internals import typename # from .karney
|
|
55
56
|
from pygeodesy.interns import _azimuth_, _datum_, _lat_, _lon_, _scale_, \
|
|
56
57
|
_SPACE_, _x_, _y_
|
|
57
|
-
from pygeodesy.karney import _norm180
|
|
58
|
+
from pygeodesy.karney import _norm180, typename
|
|
58
59
|
from pygeodesy.latlonBase import _MODS, LatLonBase as _LLB
|
|
59
60
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _FOR_DOCS # ALL_MODS
|
|
60
61
|
from pygeodesy.named import _name__, _name2__, _NamedBase, _NamedTuple, _Pass
|
|
@@ -70,7 +71,7 @@ from pygeodesy.utily import asin1, atan1, atan2, atan2b, atan2d, \
|
|
|
70
71
|
from math import acos, degrees, fabs, sin, sqrt
|
|
71
72
|
|
|
72
73
|
__all__ = _ALL_LAZY.azimuthal
|
|
73
|
-
__version__ = '
|
|
74
|
+
__version__ = '25.04.14'
|
|
74
75
|
|
|
75
76
|
_EPS_K = _EPStol * _0_1 # Karney's eps_ or _EPSmin * _0_1?
|
|
76
77
|
_over_horizon_ = 'over horizon'
|
|
@@ -112,7 +113,7 @@ class _AzimuthalBase(_NamedBase):
|
|
|
112
113
|
|
|
113
114
|
@raise TypeError: Invalid B{C{datum}}.
|
|
114
115
|
'''
|
|
115
|
-
if
|
|
116
|
+
if not _isin(datum, None, self._datum):
|
|
116
117
|
self._datum = _spherical_datum(datum, **name)
|
|
117
118
|
if name:
|
|
118
119
|
self.name = name
|
|
@@ -1088,7 +1089,7 @@ class Stereographic(_AzimuthalBase):
|
|
|
1088
1089
|
def k0(self, factor):
|
|
1089
1090
|
'''Set the central scale factor (C{scalar}).
|
|
1090
1091
|
'''
|
|
1091
|
-
n = Stereographic.k0.fget
|
|
1092
|
+
n = typename(Stereographic.k0.fget) # 'k0', name__=Stereographic.k0.fget
|
|
1092
1093
|
self._k0 = Scalar_(factor, name=n, low=EPS, high=2) # XXX high=1, 2, other?
|
|
1093
1094
|
self._k02 = self._k0 * _2_0
|
|
1094
1095
|
|
pygeodesy/basics.py
CHANGED
|
@@ -20,8 +20,8 @@ from pygeodesy.errors import _AttributeError, _ImportError, _NotImplementedError
|
|
|
20
20
|
_TypeError, _TypesError, _ValueError, _xAssertionError, \
|
|
21
21
|
_xkwds_get1
|
|
22
22
|
# from pygeodesy.fsums import _isFsum_2Tuple # _MODS
|
|
23
|
-
from pygeodesy.internals import _0_0, _enquote, _getenv, _passarg,
|
|
24
|
-
_version_info
|
|
23
|
+
from pygeodesy.internals import _0_0, _enquote, _envPYGEODESY, _getenv, _passarg, \
|
|
24
|
+
_PYGEODESY_ENV, typename, _version_info
|
|
25
25
|
from pygeodesy.interns import MISSING, NN, _1_, _by_, _COMMA_, _DOT_, _DEPRECATED_, \
|
|
26
26
|
_ELLIPSIS4_, _EQUAL_, _in_, _invalid_, _N_A_, _not_, \
|
|
27
27
|
_not_scalar_, _odd_, _SPACE_, _UNDER_, _version_
|
|
@@ -37,7 +37,7 @@ from math import copysign as _copysign
|
|
|
37
37
|
# import inspect as _inspect # _MODS
|
|
38
38
|
|
|
39
39
|
__all__ = _ALL_LAZY.basics
|
|
40
|
-
__version__ = '
|
|
40
|
+
__version__ = '25.04.14'
|
|
41
41
|
|
|
42
42
|
_below_ = 'below'
|
|
43
43
|
_list_tuple_types = (list, tuple)
|
|
@@ -207,6 +207,22 @@ def _enumereverse(iterable):
|
|
|
207
207
|
yield j, iterable[j]
|
|
208
208
|
|
|
209
209
|
|
|
210
|
+
try:
|
|
211
|
+
from math import gcd as _gcd
|
|
212
|
+
except ImportError: # 3.4-
|
|
213
|
+
|
|
214
|
+
def _gcd(a, b): # PYCHOK redef
|
|
215
|
+
# <https://WikiPedia.org/wiki/Greatest_common_divisor>
|
|
216
|
+
a, b = int(a), int(b)
|
|
217
|
+
if b > a:
|
|
218
|
+
a, b = b, a
|
|
219
|
+
# if b <= 0:
|
|
220
|
+
# return 1
|
|
221
|
+
while b:
|
|
222
|
+
a, b = b, (a % b)
|
|
223
|
+
return a
|
|
224
|
+
|
|
225
|
+
|
|
210
226
|
def halfs2(str2):
|
|
211
227
|
'''Split a string in 2 halfs.
|
|
212
228
|
|
|
@@ -222,6 +238,15 @@ def halfs2(str2):
|
|
|
222
238
|
return str2[:h], str2[h:]
|
|
223
239
|
|
|
224
240
|
|
|
241
|
+
def _integer_ratio2(x): # PYCHOK no cover
|
|
242
|
+
'''(INTERNAL) Return C{B{x}.as_interger_ratio()}.
|
|
243
|
+
'''
|
|
244
|
+
try: # int.as_integer_ratio in 3.8+
|
|
245
|
+
return x.as_integer_ratio()
|
|
246
|
+
except (AttributeError, OverflowError, TypeError, ValueError):
|
|
247
|
+
return (x if isint(x) else float(x)), 1
|
|
248
|
+
|
|
249
|
+
|
|
225
250
|
def int1s(x): # PYCHOK no cover
|
|
226
251
|
'''Count the number of 1-bits in an C{int}, I{unsigned}.
|
|
227
252
|
|
|
@@ -287,17 +312,23 @@ def iscomplex(obj, both=False):
|
|
|
287
312
|
return False
|
|
288
313
|
|
|
289
314
|
|
|
290
|
-
def isDEPRECATED(obj):
|
|
291
|
-
'''Is B{C{obj}}ect a C{DEPRECATED}
|
|
315
|
+
def isDEPRECATED(obj, outer=1):
|
|
316
|
+
'''Is B{C{obj}}ect or its outer C{type} a C{DEPRECATED}
|
|
317
|
+
class, constant, method or function?
|
|
292
318
|
|
|
293
319
|
@return: C{True} if C{DEPRECATED}, {False} if not or
|
|
294
320
|
C{None} if undetermined.
|
|
295
321
|
'''
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
322
|
+
r = None
|
|
323
|
+
for _ in range(max(0, outer) + 1):
|
|
324
|
+
try: # inspect.getdoc(obj)
|
|
325
|
+
if _DEPRECATED_ in obj.__doc__:
|
|
326
|
+
return True
|
|
327
|
+
r = False
|
|
328
|
+
except AttributeError:
|
|
329
|
+
pass
|
|
330
|
+
obj = type(obj)
|
|
331
|
+
return r
|
|
301
332
|
|
|
302
333
|
|
|
303
334
|
def isfloat(obj, both=False):
|
|
@@ -327,6 +358,13 @@ except AttributeError: # Python 2-
|
|
|
327
358
|
and not obj[:1].isdigit())
|
|
328
359
|
|
|
329
360
|
|
|
361
|
+
def _isin(obj, *objs):
|
|
362
|
+
'''(INTERNAL) Return C{bool(obj in objs)} with C{True} and C{False} matching.
|
|
363
|
+
'''
|
|
364
|
+
return any(o is obj for o in objs) or \
|
|
365
|
+
any(o == obj for o in objs if not isbool(o))
|
|
366
|
+
|
|
367
|
+
|
|
330
368
|
def isinstanceof(obj, *Classes):
|
|
331
369
|
'''Is B{C{obj}}ect an instance of one of the C{Classes}?
|
|
332
370
|
|
|
@@ -371,7 +409,7 @@ def isiterable(obj, strict=False):
|
|
|
371
409
|
@return: C{True} if C{iterable}, C{False} otherwise.
|
|
372
410
|
'''
|
|
373
411
|
# <https://PyPI.org/project/isiterable/>
|
|
374
|
-
return isiterabletype(obj) if strict else hasattr(obj, '__iter__') # map, range, set
|
|
412
|
+
return bool(isiterabletype(obj)) if strict else hasattr(obj, '__iter__') # map, range, set
|
|
375
413
|
|
|
376
414
|
|
|
377
415
|
def isiterablen(obj, strict=False):
|
|
@@ -383,7 +421,7 @@ def isiterablen(obj, strict=False):
|
|
|
383
421
|
@return: C{True} if C{iterable} with C{len}gth, C{False} otherwise.
|
|
384
422
|
'''
|
|
385
423
|
_has = isiterabletype if strict else hasattr
|
|
386
|
-
return _has(obj, '__len__') and _has(obj, '__getitem__')
|
|
424
|
+
return bool(_has(obj, '__len__') and _has(obj, '__getitem__'))
|
|
387
425
|
|
|
388
426
|
|
|
389
427
|
def isiterabletype(obj, method='__iter__'):
|
|
@@ -763,9 +801,13 @@ def _splituple(strs, *sep_splits): # in .mgrs, ...
|
|
|
763
801
|
'''(INTERNAL) Split a C{comma}- or C{whitespace}-separated
|
|
764
802
|
string into a C{tuple} of stripped C{str}ings.
|
|
765
803
|
'''
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
804
|
+
if sep_splits:
|
|
805
|
+
t = (t.strip() for t in strs.split(*sep_splits))
|
|
806
|
+
else:
|
|
807
|
+
t = strs.strip()
|
|
808
|
+
if t:
|
|
809
|
+
t = t.replace(_COMMA_, _SPACE_).split()
|
|
810
|
+
return tuple(t) if t else ()
|
|
769
811
|
|
|
770
812
|
|
|
771
813
|
def unsigned0(x):
|
|
@@ -876,8 +918,8 @@ def _xiterablen(obj):
|
|
|
876
918
|
def _xiterror(obj, _xwhich):
|
|
877
919
|
'''(INTERNAL) Helper for C{_xinterable} and C{_xiterablen}.
|
|
878
920
|
'''
|
|
879
|
-
t =
|
|
880
|
-
raise _TypeError(repr(obj), txt=t)
|
|
921
|
+
t = typename(_xwhich)[2:] # less '_x'
|
|
922
|
+
raise _TypeError(repr(obj), txt=_not_(t))
|
|
881
923
|
|
|
882
924
|
|
|
883
925
|
def _xnumpy(where, *required):
|
|
@@ -899,13 +941,13 @@ def _xor(x, *xs):
|
|
|
899
941
|
return x
|
|
900
942
|
|
|
901
943
|
|
|
902
|
-
def _xpackages(
|
|
944
|
+
def _xpackages(_xhich):
|
|
903
945
|
'''(INTERNAL) Check dependency to be excluded.
|
|
904
946
|
'''
|
|
905
947
|
if _XPACKAGES: # PYCHOK no cover
|
|
906
|
-
n =
|
|
948
|
+
n = typename(_xhich)[2:] # less '_x'
|
|
907
949
|
if n.lower() in _XPACKAGES:
|
|
908
|
-
E =
|
|
950
|
+
E = _PYGEODESY_ENV(_xpackages_)
|
|
909
951
|
x = _SPACE_(n, _in_, E)
|
|
910
952
|
e = _enquote(_getenv(E, NN))
|
|
911
953
|
raise ImportError(_EQUAL_(x, e))
|
|
@@ -955,7 +997,7 @@ def _xversion(package, where, *required, **name):
|
|
|
955
997
|
if required:
|
|
956
998
|
t = _version_info(package)
|
|
957
999
|
if t[:len(required)] < required:
|
|
958
|
-
t = _SPACE_(package
|
|
1000
|
+
t = _SPACE_(typename(package),
|
|
959
1001
|
_version_, _DOT_(*t),
|
|
960
1002
|
_below_, _DOT_(*required),
|
|
961
1003
|
_req_d_by(where, **name))
|
|
@@ -982,7 +1024,8 @@ else: # Python 3.10+
|
|
|
982
1024
|
def _zip(*args):
|
|
983
1025
|
return zip(*args, strict=True)
|
|
984
1026
|
|
|
985
|
-
|
|
1027
|
+
_xpackages_ = typename(_xpackages).lstrip(_UNDER_)
|
|
1028
|
+
_XPACKAGES = _splituple(_envPYGEODESY(_xpackages_).lower()) # test/bases._X_OK
|
|
986
1029
|
|
|
987
1030
|
# **) MIT License
|
|
988
1031
|
#
|
pygeodesy/booleans.py
CHANGED
|
@@ -17,12 +17,14 @@ C{reverse-difference}, C{sum} and C{union}.
|
|
|
17
17
|
# make sure int/int division yields float quotient, see .basics
|
|
18
18
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
19
19
|
|
|
20
|
-
from pygeodesy.basics import isodd, issubclassof, map2,
|
|
20
|
+
from pygeodesy.basics import _isin, isodd, issubclassof, map2, \
|
|
21
|
+
_xscalar, typename
|
|
21
22
|
from pygeodesy.constants import EPS, EPS2, INT0, _0_0, _0_5, _1_0
|
|
22
23
|
from pygeodesy.errors import ClipError, _IsnotError, _TypeError, \
|
|
23
24
|
_ValueError, _xattr, _xkwds_get, _xkwds_pop2
|
|
24
25
|
from pygeodesy.fmath import favg, fdot_, hypot, hypot2
|
|
25
26
|
# from pygeodesy.fsums import fsum1 # _MODS
|
|
27
|
+
# from pygeodesy.internals import typename # from .basics
|
|
26
28
|
from pygeodesy.interns import NN, _BANG_, _clipid_, _COMMASPACE_, \
|
|
27
29
|
_composite_, _DOT_, _duplicate_, _e_, \
|
|
28
30
|
_ELLIPSIS_, _few_, _height_, _lat_, _LatLon_, \
|
|
@@ -43,7 +45,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
|
|
|
43
45
|
# from math import fabs # from .utily
|
|
44
46
|
|
|
45
47
|
__all__ = _ALL_LAZY.booleans
|
|
46
|
-
__version__ = '
|
|
48
|
+
__version__ = '25.04.14'
|
|
47
49
|
|
|
48
50
|
_0EPS = EPS # near-zero, positive
|
|
49
51
|
_EPS0 = -EPS # near-zero, negative
|
|
@@ -352,11 +354,11 @@ class LatLonFHP(_LatLonBool):
|
|
|
352
354
|
def _isduplicate(self):
|
|
353
355
|
# Is this point a I{duplicate} intersection?
|
|
354
356
|
p = self._dupof
|
|
355
|
-
return bool(p and
|
|
356
|
-
and
|
|
357
|
-
and
|
|
358
|
-
# and p._alpha
|
|
359
|
-
and self._alpha
|
|
357
|
+
return bool(p and self._linked
|
|
358
|
+
and p is not self
|
|
359
|
+
and p == self
|
|
360
|
+
# and _isin(p._alpha, None, self._alpha)
|
|
361
|
+
and _isin(self._alpha, _0_0, p._alpha))
|
|
360
362
|
|
|
361
363
|
# @property_RO
|
|
362
364
|
# def _isduplicated(self):
|
|
@@ -940,7 +942,7 @@ class _CompositeBase(_Named):
|
|
|
940
942
|
c = Fmt.SQUARE(c) if c > 1 else NN
|
|
941
943
|
n = Fmt.SQUARE(len(self))
|
|
942
944
|
t = Fmt.PAREN(self) # XXX not unstr
|
|
943
|
-
return NN(self.
|
|
945
|
+
return NN(self.typename, c, n, t)
|
|
944
946
|
|
|
945
947
|
def __str__(self):
|
|
946
948
|
'''String C{str} of this composite.
|
|
@@ -1051,7 +1053,7 @@ class _CompositeBase(_Named):
|
|
|
1051
1053
|
def _kwds(self, op, **more):
|
|
1052
1054
|
# Get all keyword arguments as C{dict}.
|
|
1053
1055
|
kwds = dict(raiser=self.raiser, eps=self.eps,
|
|
1054
|
-
name=self.name or op
|
|
1056
|
+
name=self.name or typename(op))
|
|
1055
1057
|
kwds.update(more)
|
|
1056
1058
|
return kwds
|
|
1057
1059
|
|
|
@@ -1105,7 +1107,7 @@ class _CompositeBase(_Named):
|
|
|
1105
1107
|
def _sum(self, other, op):
|
|
1106
1108
|
# Combine this and an C{other} composite
|
|
1107
1109
|
LL = self._LL
|
|
1108
|
-
sp = self.copy(name=self.name or op
|
|
1110
|
+
sp = self.copy(name=self.name or typename(op))
|
|
1109
1111
|
sp._clips, sid = (), INT0 # new clips
|
|
1110
1112
|
for cp in (self, other):
|
|
1111
1113
|
for c in cp._clips:
|
pygeodesy/cartesianBase.py
CHANGED
|
@@ -10,17 +10,18 @@ U{https://www.Movable-Type.co.UK/scripts/latlong-vectors.html} and
|
|
|
10
10
|
U{https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html}.
|
|
11
11
|
'''
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
from pygeodesy.basics import _isin, _xinstanceof, typename
|
|
14
14
|
from pygeodesy.constants import EPS, EPS0, INT0, PI2, _isfinite, isnear0, \
|
|
15
15
|
_0_0, _1_0, _N_1_0, _2_0, _4_0, _6_0
|
|
16
16
|
from pygeodesy.datums import Datum, _earth_ellipsoid, _spherical_datum, \
|
|
17
|
-
Transform, _WGS84
|
|
17
|
+
Transform, _WGS84
|
|
18
18
|
# from pygeodesy.ecef import EcefKarney # _MODS
|
|
19
19
|
from pygeodesy.errors import _IsnotError, _TypeError, _ValueError, _xattr, \
|
|
20
20
|
_xdatum, _xkwds, _xkwds_get, _xkwds_pop2
|
|
21
21
|
from pygeodesy.fmath import cbrt, hypot, hypot_, hypot2, fabs, sqrt # hypot
|
|
22
22
|
# from pygeodesy.formy import _hartzell # _MODS
|
|
23
23
|
from pygeodesy.fsums import fsumf_, Fmt
|
|
24
|
+
# from pygeodesy.internals import typename # from .basics
|
|
24
25
|
from pygeodesy.interns import _COMMASPACE_, _datum_, _no_, _phi_
|
|
25
26
|
from pygeodesy.interns import _ellipsoidal_, _spherical_ # PYCHOK used!
|
|
26
27
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
@@ -30,8 +31,7 @@ from pygeodesy.namedTuples import LatLon4Tuple, _NamedTupleTo , Vector3Tuple, \
|
|
|
30
31
|
# from pygeodesy.nvectorBase import _N_vector # _MODS
|
|
31
32
|
from pygeodesy.props import deprecated_method, Property, Property_RO, property_doc_, \
|
|
32
33
|
property_RO, _update_all
|
|
33
|
-
# from pygeodesy
|
|
34
|
-
# tienstra7 # _MODS
|
|
34
|
+
# from pygeodesy import resections as _resections # _MODS.into
|
|
35
35
|
# from pygeodesy.streprs import Fmt # from .fsums
|
|
36
36
|
# from pygeodesy.triaxials import Triaxial_ # _MODS
|
|
37
37
|
from pygeodesy.units import Degrees, Height, _heigHt, _isMeter, Meter, Radians
|
|
@@ -43,10 +43,11 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
|
43
43
|
# from math import degrees, fabs, radians, sqrt # from .fmath, .utily
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.cartesianBase
|
|
46
|
-
__version__ = '
|
|
46
|
+
__version__ = '25.04.21'
|
|
47
47
|
|
|
48
|
-
_r_
|
|
49
|
-
|
|
48
|
+
_r_ = 'r'
|
|
49
|
+
_resections = _MODS.into(resections=__name__)
|
|
50
|
+
_theta_ = 'theta'
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
class CartesianBase(Vector3d, _NamedLocal):
|
|
@@ -112,8 +113,8 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
112
113
|
|
|
113
114
|
@see: Function L{pygeodesy.cassini} for references and more details.
|
|
114
115
|
'''
|
|
115
|
-
return
|
|
116
|
-
|
|
116
|
+
return _resections.cassini(self, pointB, pointC, alpha, beta,
|
|
117
|
+
useZ=useZ, datum=self.datum)
|
|
117
118
|
|
|
118
119
|
@deprecated_method
|
|
119
120
|
def collins(self, pointB, pointC, alpha, beta, useZ=False):
|
|
@@ -148,8 +149,8 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
148
149
|
|
|
149
150
|
@see: Function L{pygeodesy.collins5} for references and more details.
|
|
150
151
|
'''
|
|
151
|
-
return
|
|
152
|
-
|
|
152
|
+
return _resections.collins5(self, pointB, pointC, alpha, beta,
|
|
153
|
+
useZ=useZ, datum=self.datum)
|
|
153
154
|
|
|
154
155
|
@deprecated_method
|
|
155
156
|
def convertDatum(self, datum2, **datum):
|
|
@@ -304,7 +305,7 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
304
305
|
|
|
305
306
|
@raise TypeError: Invalid or undefined B{C{earth}} or C{datum}.
|
|
306
307
|
'''
|
|
307
|
-
n = self.height3
|
|
308
|
+
n = typename(self.height3)
|
|
308
309
|
d = self.datum if earth is None else _spherical_datum(earth, name=n)
|
|
309
310
|
c, h = self, _heigHt(self, height)
|
|
310
311
|
if h and d:
|
|
@@ -357,7 +358,7 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
357
358
|
|
|
358
359
|
@see: Methods L{Ellipsoid.height4} and L{Triaxial_.height4} for more information.
|
|
359
360
|
'''
|
|
360
|
-
n = self.height4
|
|
361
|
+
n = typename(self.height4)
|
|
361
362
|
d = self.datum if earth is None else earth
|
|
362
363
|
if normal and d is self.datum:
|
|
363
364
|
r = self._height4
|
|
@@ -504,8 +505,8 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
504
505
|
|
|
505
506
|
@see: Function L{pygeodesy.pierlot} for references and more details.
|
|
506
507
|
'''
|
|
507
|
-
return
|
|
508
|
-
|
|
508
|
+
return _resections.pierlot(self, point2, point3, alpha12, alpha23,
|
|
509
|
+
useZ=useZ, eps=eps, datum=self.datum)
|
|
509
510
|
|
|
510
511
|
def pierlotx(self, point2, point3, alpha1, alpha2, alpha3, useZ=False):
|
|
511
512
|
'''3-Point resection between this and two other points using U{Pierlot
|
|
@@ -531,8 +532,8 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
531
532
|
|
|
532
533
|
@see: Function L{pygeodesy.pierlotx} for references and more details.
|
|
533
534
|
'''
|
|
534
|
-
return
|
|
535
|
-
|
|
535
|
+
return _resections.pierlotx(self, point2, point3, alpha1, alpha2, alpha3,
|
|
536
|
+
useZ=useZ, datum=self.datum)
|
|
536
537
|
|
|
537
538
|
def Roc2(self, earth=None):
|
|
538
539
|
'''Compute this cartesian's I{normal} and I{pseudo, z-based} radius of curvature.
|
|
@@ -605,8 +606,8 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
605
606
|
|
|
606
607
|
@see: Function L{pygeodesy.tienstra7} for references and more details.
|
|
607
608
|
'''
|
|
608
|
-
return
|
|
609
|
-
|
|
609
|
+
return _resections.tienstra7(self, pointB, pointC, alpha, beta, gamma,
|
|
610
|
+
useZ=useZ, datum=self.datum)
|
|
610
611
|
|
|
611
612
|
@deprecated_method
|
|
612
613
|
def to2ab(self): # PYCHOK no cover
|
|
@@ -659,7 +660,7 @@ class CartesianBase(Vector3d, _NamedLocal):
|
|
|
659
660
|
'''
|
|
660
661
|
_xinstanceof(Datum, datum2=datum2)
|
|
661
662
|
|
|
662
|
-
c = self if datum
|
|
663
|
+
c = self if _isin(datum, None, self.datum) else \
|
|
663
664
|
self.toDatum(datum)
|
|
664
665
|
|
|
665
666
|
i, d = False, c.datum
|