pygeodesy 24.8.4__py2.py3-none-any.whl → 24.9.9__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-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/METADATA +17 -16
- PyGeodesy-24.9.9.dist-info/RECORD +118 -0
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +23 -23
- pygeodesy/__main__.py +46 -47
- pygeodesy/auxilats/_CX_4.py +104 -181
- pygeodesy/auxilats/_CX_6.py +152 -277
- pygeodesy/auxilats/_CX_8.py +211 -438
- pygeodesy/auxilats/_CX_Rs.py +222 -0
- pygeodesy/auxilats/__init__.py +2 -2
- pygeodesy/auxilats/__main__.py +30 -38
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +28 -36
- pygeodesy/auxilats/auxily.py +30 -50
- pygeodesy/basics.py +18 -7
- pygeodesy/booleans.py +10 -11
- pygeodesy/cartesianBase.py +5 -5
- pygeodesy/constants.py +35 -34
- pygeodesy/ellipsoidalBase.py +18 -15
- pygeodesy/ellipsoidalExact.py +2 -2
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +2 -2
- pygeodesy/ellipsoidalNvector.py +2 -2
- pygeodesy/ellipsoidalVincenty.py +7 -6
- pygeodesy/elliptic.py +154 -88
- pygeodesy/epsg.py +3 -3
- pygeodesy/etm.py +71 -59
- pygeodesy/fmath.py +99 -90
- pygeodesy/fsums.py +201 -14
- pygeodesy/gars.py +9 -8
- pygeodesy/geodesici.py +6 -5
- pygeodesy/geodesicx/_C4_24.py +1 -3
- pygeodesy/geodesicx/_C4_27.py +1 -3
- pygeodesy/geodesicx/_C4_30.py +1 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +44 -46
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +5 -5
- pygeodesy/geodesicx/gxbases.py +32 -18
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +18 -11
- pygeodesy/geoids.py +293 -315
- pygeodesy/heights.py +150 -158
- pygeodesy/internals.py +70 -9
- pygeodesy/interns.py +4 -4
- pygeodesy/karney.py +83 -60
- pygeodesy/ktm.py +4 -4
- pygeodesy/latlonBase.py +13 -7
- pygeodesy/lazily.py +13 -8
- pygeodesy/ltp.py +5 -6
- pygeodesy/ltpTuples.py +7 -1
- pygeodesy/mgrs.py +47 -42
- pygeodesy/named.py +8 -4
- pygeodesy/namedTuples.py +14 -1
- pygeodesy/osgr.py +7 -7
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +7 -6
- pygeodesy/resections.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +42 -60
- pygeodesy/rhumb/solve.py +3 -3
- pygeodesy/simplify.py +10 -10
- pygeodesy/sphericalBase.py +3 -3
- pygeodesy/sphericalTrigonometry.py +2 -2
- pygeodesy/streprs.py +3 -3
- pygeodesy/triaxials.py +207 -201
- pygeodesy/units.py +3 -3
- pygeodesy/unitsBase.py +4 -4
- pygeodesy/utmupsBase.py +3 -3
- pygeodesy/vector2d.py +158 -51
- pygeodesy/vector3d.py +13 -52
- pygeodesy/vector3dBase.py +81 -63
- pygeodesy/webmercator.py +3 -3
- pygeodesy/wgrs.py +20 -22
- PyGeodesy-24.8.4.dist-info/RECORD +0 -117
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''(INTERNAL) Classes C{_Rcoeffs}, C{_Rdict} and C{_Rtuple} to store the deferred
|
|
5
|
+
Python versions of coefficients from I{Karney}'s C++ class U{AuxLatitude
|
|
6
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1AuxLatitude.html>}.
|
|
7
|
+
|
|
8
|
+
Copyright (C) Charles Karney (2022-2024) Karney@Alum.MIT.edu> and licensed under the
|
|
9
|
+
MIT/X11 License. For more information, see <https:#GeographicLib.SourceForge.io>.
|
|
10
|
+
'''
|
|
11
|
+
# make sure int/int division yields float quotient, see .basics
|
|
12
|
+
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
13
|
+
|
|
14
|
+
from pygeodesy.constants import _floats
|
|
15
|
+
from pygeodesy.errors import _AssertionError, _MODS
|
|
16
|
+
from pygeodesy.interns import NN, MISSING, _COMMA_, _duplicate_, _NL_, \
|
|
17
|
+
_QUOTE3_, _SLASH_, _ELLIPSIS4_ # PYCHOK used!
|
|
18
|
+
# from pygeodesy.lazily import _ALL_MODS as _MODS # from .errors
|
|
19
|
+
from pygeodesy.named import ADict, Property_RO
|
|
20
|
+
# from pygeodesy.props import Property_RO # from .named
|
|
21
|
+
|
|
22
|
+
__all__ = ()
|
|
23
|
+
__version__ = '24.09.04'
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _Rcoeffs(ADict):
|
|
27
|
+
'''(INTERNAL) With string-ified C{keys}.
|
|
28
|
+
'''
|
|
29
|
+
def __init__(self, ALorder, coeffs):
|
|
30
|
+
'''New C{_Rcoeffs} from a C{coeffs} dict.
|
|
31
|
+
'''
|
|
32
|
+
try:
|
|
33
|
+
if not isinstance(coeffs, dict):
|
|
34
|
+
raise _RdictError(coeffs=type(coeffs))
|
|
35
|
+
n = 0
|
|
36
|
+
for k, d in coeffs.items():
|
|
37
|
+
if not isinstance(d, _Rdict):
|
|
38
|
+
raise _RdictError(k=k, d=type(d))
|
|
39
|
+
n += d.n
|
|
40
|
+
|
|
41
|
+
ADict.__init__(self, coeffs)
|
|
42
|
+
self.set_(ALorder=ALorder, n=n) # in .validate
|
|
43
|
+
except Exception as x:
|
|
44
|
+
raise _RdictError(ALorder=ALorder, cause=x)
|
|
45
|
+
|
|
46
|
+
def bnuz4(self): # in .auxilats.__main__ # PYCHOK no cover
|
|
47
|
+
# get C{(strB, number, unique, floatB)} rationals
|
|
48
|
+
b = n = u = z = 0
|
|
49
|
+
_zB = _MODS.internals._sizeof
|
|
50
|
+
for R in self._Rtuples():
|
|
51
|
+
_, _, rs = R.k_n_rs
|
|
52
|
+
b += _zB(rs)
|
|
53
|
+
t = R._tuple
|
|
54
|
+
z += _zB(t) # Float
|
|
55
|
+
# assert R.Rdict is None
|
|
56
|
+
n += len(t)
|
|
57
|
+
u += sum(1 for f in t if f in _floats)
|
|
58
|
+
return b, n, (n - u), z
|
|
59
|
+
|
|
60
|
+
def items(self): # string-ify keys # PYCHOK no cover
|
|
61
|
+
for n, v in ADict.items(self):
|
|
62
|
+
yield str(n), v
|
|
63
|
+
|
|
64
|
+
def _Rtuples(self): # PYCHOK no cover
|
|
65
|
+
for d in self.values():
|
|
66
|
+
if isinstance(d, _Rdict):
|
|
67
|
+
# yield from d.values()
|
|
68
|
+
for R in d.values():
|
|
69
|
+
yield R
|
|
70
|
+
|
|
71
|
+
def _validate(self, aL, lenAux):
|
|
72
|
+
# in .auxily.Aux._CXcoeffs(al, Aux.len(aL))
|
|
73
|
+
a, n = self.ALorder, self.n # PYCHOK Adict!
|
|
74
|
+
# for R in self._Rtuples():
|
|
75
|
+
# assert isinstance(R, _Rtuple)
|
|
76
|
+
if aL != a or lenAux != n:
|
|
77
|
+
raise _RdictError(aL=aL, ALorder=a, lenAux=lenAux, n=n)
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class _Rdict(dict): # in ._CX_#, .auxLat, .rhumb.aux_
|
|
82
|
+
'''(INTERNAL) Dict of C{_Rtuple}s.
|
|
83
|
+
'''
|
|
84
|
+
n = 0 # sum(R.k_n_k[1] for r in Rtuples)
|
|
85
|
+
|
|
86
|
+
def __init__(self, nt, *Rtuples):
|
|
87
|
+
'''New C{_Rdict}.
|
|
88
|
+
'''
|
|
89
|
+
if not Rtuples:
|
|
90
|
+
raise _RdictError(Rtuples=MISSING)
|
|
91
|
+
|
|
92
|
+
for R in Rtuples:
|
|
93
|
+
if not isinstance(R, _Rtuple):
|
|
94
|
+
raise _RdictError(R, R=type(R))
|
|
95
|
+
k, n, _ = R.k_n_rs
|
|
96
|
+
if k in self:
|
|
97
|
+
raise _RdictError(_duplicate_, k=k)
|
|
98
|
+
R.Rdict = self
|
|
99
|
+
self[k] = R # overwritten in self._floatuple
|
|
100
|
+
self.n += n
|
|
101
|
+
if self.n != nt:
|
|
102
|
+
raise _RdictError(n=n, nt=nt)
|
|
103
|
+
|
|
104
|
+
def _floats(self, rs):
|
|
105
|
+
# yield floats from a string of comma-separated rationals
|
|
106
|
+
def _p_q(p=NN, q=1, *x):
|
|
107
|
+
return (NN if x else p), q
|
|
108
|
+
|
|
109
|
+
_get = _floats.get
|
|
110
|
+
for r in NN(*rs.split()).split(_COMMA_):
|
|
111
|
+
p, q = _p_q(*r.split(_SLASH_))
|
|
112
|
+
if p:
|
|
113
|
+
f = int(p) / int(q) # fractions.Fraction?
|
|
114
|
+
if not isinstance(f, float):
|
|
115
|
+
raise _RdictError(rs, f=f, p=p, q=q, r=r)
|
|
116
|
+
yield _get(f, f) # from .constants?
|
|
117
|
+
else:
|
|
118
|
+
raise _RdictError(rs, r=r)
|
|
119
|
+
|
|
120
|
+
def _floatuple(self, Rtuple):
|
|
121
|
+
# return a tuple of floats from an C{_Rtuple}
|
|
122
|
+
k, n, rs = Rtuple.k_n_rs
|
|
123
|
+
t = tuple(f for m in map(self._floats, rs)
|
|
124
|
+
for f in m) # ... yield f
|
|
125
|
+
# @see: <https://StackOverflow.com/questions/10632839/>
|
|
126
|
+
# and <https://realPython.com/python-flatten-list/>
|
|
127
|
+
if len(t) != n:
|
|
128
|
+
raise _RdictError(*rs, len=len(t), n=n)
|
|
129
|
+
self[k] = t
|
|
130
|
+
return t
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class _RdictError(_AssertionError):
|
|
134
|
+
'''(INTERNAL) For C{_Rdict} issues.
|
|
135
|
+
'''
|
|
136
|
+
def __init__(self, *rs, **kwds_cause): # PYCHOK no cover
|
|
137
|
+
if rs:
|
|
138
|
+
if len(rs) > 1:
|
|
139
|
+
t = _NL_(NN, *rs)
|
|
140
|
+
t = NN(_QUOTE3_, t, _QUOTE3_)
|
|
141
|
+
else: # single rs
|
|
142
|
+
t = repr(rs[0])
|
|
143
|
+
kwds_cause.update(txt=t)
|
|
144
|
+
_AssertionError.__init__(self, **kwds_cause)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class _Rtuple(list): # MUST be list, NOT tuple!
|
|
148
|
+
'''(INTERNAL) I{Pseudo-tuple} of float rationals used in C{_Rdict}s.
|
|
149
|
+
'''
|
|
150
|
+
Rdict = None
|
|
151
|
+
k_n_rs = None, 0, ()
|
|
152
|
+
|
|
153
|
+
def __init__(self, k, n, *rs):
|
|
154
|
+
'''New C{_Rtuple} with key C{k}, number of floats C{n} and with
|
|
155
|
+
each C{rs} a C{str} of comma-separated rationals C{"p/q, ..."}
|
|
156
|
+
where C{p} and C{q} are C{int} digits only.
|
|
157
|
+
'''
|
|
158
|
+
try:
|
|
159
|
+
if not rs:
|
|
160
|
+
raise _RdictError(rs=MISSING)
|
|
161
|
+
for t in rs:
|
|
162
|
+
if not isinstance(t, str):
|
|
163
|
+
raise _RdictError(rs=type(t))
|
|
164
|
+
if not (isinstance(n, int) and n > 0):
|
|
165
|
+
raise _RdictError(n=type(n))
|
|
166
|
+
self.k_n_rs = k, n, rs
|
|
167
|
+
except Exception as x:
|
|
168
|
+
raise _RdictError(*rs, k=k, n=n, cause=x)
|
|
169
|
+
|
|
170
|
+
def __getitem__(self, i):
|
|
171
|
+
return self._tuple[i]
|
|
172
|
+
|
|
173
|
+
def __iter__(self):
|
|
174
|
+
return iter(self._tuple)
|
|
175
|
+
|
|
176
|
+
def __len__(self):
|
|
177
|
+
return len(self._tuple)
|
|
178
|
+
|
|
179
|
+
@Property_RO
|
|
180
|
+
def _tuple(self):
|
|
181
|
+
# build the C{tuple} once, replace C{_Rdict}
|
|
182
|
+
# item at C{key} with the C{tuple} and fill
|
|
183
|
+
# this C{_Rlist} with the C{tuple} values
|
|
184
|
+
# for the initial __getitem__ retrieval[s]
|
|
185
|
+
try:
|
|
186
|
+
k, n, rs = self.k_n_rs
|
|
187
|
+
t = self.Rdict._floatuple(self)
|
|
188
|
+
self[:] = t # MUST copy into self!
|
|
189
|
+
except Exception as x:
|
|
190
|
+
if len(rs) > 1 and _QUOTE3_ in str(x):
|
|
191
|
+
rs = rs[0], _ELLIPSIS4_
|
|
192
|
+
raise _RdictError(k=k, n=n, rs=rs, cause=x)
|
|
193
|
+
del self.Rdict, self.k_n_rs # trash refs
|
|
194
|
+
return t
|
|
195
|
+
|
|
196
|
+
def append(self, arg):
|
|
197
|
+
raise _RdictError(append=arg)
|
|
198
|
+
|
|
199
|
+
def extend(self, arg):
|
|
200
|
+
raise _RdictError(extend=arg)
|
|
201
|
+
|
|
202
|
+
# **) MIT License
|
|
203
|
+
#
|
|
204
|
+
# Copyright (C) 2024-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
205
|
+
#
|
|
206
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
207
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
208
|
+
# to deal in the Software without restriction, including without limitation
|
|
209
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
210
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
211
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
212
|
+
#
|
|
213
|
+
# The above copyright notice and this permission notice shall be included
|
|
214
|
+
# in all copies or substantial portions of the Software.
|
|
215
|
+
#
|
|
216
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
217
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
218
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
219
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
220
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
221
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
222
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
pygeodesy/auxilats/__init__.py
CHANGED
|
@@ -8,7 +8,7 @@ U{DST<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1DST.htm
|
|
|
8
8
|
U{AuxLatitude<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1AuxLatitude.html>} all
|
|
9
9
|
in I{GeographicLib version 2.2+}.
|
|
10
10
|
|
|
11
|
-
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-
|
|
11
|
+
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-2024) and licensed under the MIT/X11
|
|
12
12
|
License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
13
13
|
|
|
14
14
|
@note: Class L{AuxDST} requires U{numpy<https://PyPI.org/project/numpy>} to be installed, version 1.16
|
|
@@ -29,7 +29,7 @@ from pygeodesy.lazily import _ALL_OTHER
|
|
|
29
29
|
# no modules: auxAngle, auxDLat, auxDST, auxily, auxLat
|
|
30
30
|
__all__ = _ALL_OTHER(Aux, AuxAngle, AuxDLat, AuxDST, AuxLat,
|
|
31
31
|
AuxBeta, AuxChi, AuxMu, AuxPhi, AuxTheta, AuxXi)
|
|
32
|
-
__version__ = '24.
|
|
32
|
+
__version__ = '24.09.04'
|
|
33
33
|
|
|
34
34
|
# **) MIT License
|
|
35
35
|
#
|
pygeodesy/auxilats/__main__.py
CHANGED
|
@@ -5,57 +5,49 @@ u'''Print L{auxilats} version, etc. using C{python -m pygeodesy.auxilats}.
|
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
7
|
__all__ = ()
|
|
8
|
-
__version__ = '24.
|
|
8
|
+
__version__ = '24.09.04'
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def
|
|
12
|
-
'''(INTERNAL) Get the C{CP} stats.
|
|
13
|
-
'''
|
|
14
|
-
from pygeodesy.auxilats import Aux, AuxLat, auxLat
|
|
15
|
-
from pygeodesy.datums import _WGS84
|
|
16
|
-
|
|
17
|
-
A = AuxLat(_WGS84)
|
|
18
|
-
ax = A._coeffs(Aux.XI, Aux.CHI)
|
|
19
|
-
Cx = auxLat._CXcoeffs(A.ALorder)
|
|
20
|
-
pc = '%.1f%%' % (Cx.u * 100.0 / Cx.n)
|
|
21
|
-
return dict(ALorder=A.ALorder, CXlen=Cx.n, CXset=Cx.u, CXset_len=pc, CXx=len(ax))
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _main(): # PYCHOK no cover
|
|
25
|
-
|
|
26
|
-
import os.path as _os_path
|
|
11
|
+
def _main(**ALorder): # PYCHOK no cover
|
|
27
12
|
|
|
28
13
|
try:
|
|
29
|
-
from pygeodesy import auxilats
|
|
30
|
-
from pygeodesy.internals import
|
|
31
|
-
|
|
32
|
-
from pygeodesy.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
v = _Pythonarchine()
|
|
14
|
+
from pygeodesy import auxilats
|
|
15
|
+
from pygeodesy.internals import _fper, _name_version, \
|
|
16
|
+
printf, _versions
|
|
17
|
+
from pygeodesy.interns import _COMMASPACE_, _EQUAL_
|
|
18
|
+
|
|
19
|
+
A = auxilats.AuxLat(**ALorder)
|
|
20
|
+
Cx = A._CXcoeffs # PropertyRO: Adict of _Rdicts
|
|
21
|
+
b, n, u, z = Cx.bnuz4()
|
|
22
|
+
p = dict(ALorder=A.ALorder,CXb=b, CXb_z=_fper(b, z),
|
|
23
|
+
CXn=n, CXu=u, CXu_n=_fper(u, n))
|
|
24
|
+
p = list(_EQUAL_(*t) for t in p.items())
|
|
41
25
|
try:
|
|
42
26
|
import geographiclib
|
|
43
|
-
|
|
27
|
+
p.append(_name_version(geographiclib))
|
|
44
28
|
except ImportError:
|
|
45
29
|
pass
|
|
46
30
|
|
|
47
|
-
a =
|
|
48
|
-
|
|
49
|
-
if not a.startswith(x):
|
|
50
|
-
a = _DOT_(x, a)
|
|
51
|
-
printf('%s%s (%s)', a, _COMMASPACE_.join(p), _COMMASPACE_.join(v))
|
|
31
|
+
a = _name_version(auxilats)
|
|
32
|
+
printf('%s: %s (%s)', a, _COMMASPACE_(*p), _versions())
|
|
52
33
|
|
|
53
34
|
except ImportError:
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
from pygeodesy.internals import _usage
|
|
36
|
+
print(_usage(__file__))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
from sys import argv # .internals._isPyChecker
|
|
40
|
+
_main(ALorder=int(argv[1])) if len(argv) == 2 and argv[1].isdigit() else _main()
|
|
41
|
+
|
|
42
|
+
# % python3.12 -m pygeodesy.auxilats 8
|
|
43
|
+
# 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
|
+
|
|
45
|
+
# % python3.12 -m pygeodesy.auxilats 6
|
|
46
|
+
# pygeodesy.auxilats 24.09.04: ALorder=6, CXb=11099, CXb_z=64.1%, CXn=522, CXu=448, CXu_n=85.8%, geographiclib 2.0 (pygeodesy 24.9.9 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
56
47
|
|
|
48
|
+
# % python3.12 -m pygeodesy.auxilats 4
|
|
49
|
+
# pygeodesy.auxilats 24.09.04: ALorder=4, CXb=5367, CXb_z=58.8%, CXn=252, CXu=203, CXu_n=80.6%, geographiclib 2.0 (pygeodesy 24.9.9 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
57
50
|
|
|
58
|
-
_main()
|
|
59
51
|
|
|
60
52
|
# **) MIT License
|
|
61
53
|
#
|
pygeodesy/auxilats/auxDST.py
CHANGED
|
@@ -24,7 +24,7 @@ from pygeodesy.karney import _2cos2x, _ALL_DOCS
|
|
|
24
24
|
from pygeodesy.props import property_RO, property_ROver
|
|
25
25
|
|
|
26
26
|
__all__ = ()
|
|
27
|
-
__version__ = '24.
|
|
27
|
+
__version__ = '24.08.13'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class AuxDST(object):
|
|
@@ -92,7 +92,7 @@ class AuxDST(object):
|
|
|
92
92
|
|
|
93
93
|
@arg data: Elements DST-III[0:N+1] or DST-IV[0:N] (C{float}[])
|
|
94
94
|
with DST_III[0] = 0.
|
|
95
|
-
@arg cIV: If C{True} DST-IV, otherwise DST-III.
|
|
95
|
+
@arg cIV: If C{True}, DST-IV, otherwise DST-III.
|
|
96
96
|
|
|
97
97
|
@return: FFTransforms (C{float}[0:N]).
|
|
98
98
|
'''
|
pygeodesy/auxilats/auxLat.py
CHANGED
|
@@ -17,11 +17,12 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
17
17
|
|
|
18
18
|
from pygeodesy.auxilats.auxAngle import AuxAngle, AuxBeta, AuxChi, _AuxClass, \
|
|
19
19
|
AuxMu, AuxPhi, AuxTheta, AuxXi
|
|
20
|
-
from pygeodesy.auxilats.auxily import Aux, _sc, _sn,
|
|
20
|
+
from pygeodesy.auxilats.auxily import Aux, _sc, _sn, atan1
|
|
21
|
+
from pygeodesy.auxilats._CX_Rs import _Rdict, _Rtuple
|
|
21
22
|
from pygeodesy.basics import _reverange, _xinstanceof, _passarg
|
|
22
23
|
from pygeodesy.constants import INF, MAX_EXP, MIN_EXP, NAN, PI_2, PI_4, _EPSqrt, \
|
|
23
|
-
_0_0, _0_0s, _0_1,
|
|
24
|
-
|
|
24
|
+
_0_0, _0_0s, _0_1, _0_5, _1_0, _2_0, _3_0, _360_0, \
|
|
25
|
+
_log2, _over, isfinite, isinf, isnan
|
|
25
26
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84, \
|
|
26
27
|
Ellipsoid, _name__, _EWGS84
|
|
27
28
|
# from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # from .datums
|
|
@@ -30,9 +31,9 @@ from pygeodesy.errors import AuxError, _xkwds_not, _xkwds_pop2, _Xorder
|
|
|
30
31
|
# from pygeodesy.fmath import cbrt # from .karney
|
|
31
32
|
from pygeodesy.fsums import Fsum, _Fsumf_, _sum
|
|
32
33
|
# from pygeodesy.internals import _passarg # from .basics
|
|
33
|
-
from pygeodesy.interns import NN,
|
|
34
|
-
from pygeodesy.karney import _2cos2x, _polynomial, _ALL_DOCS, cbrt
|
|
35
|
-
# from pygeodesy.lazily import _ALL_DOCS
|
|
34
|
+
from pygeodesy.interns import NN, _not_scalar_, _UNDER_
|
|
35
|
+
from pygeodesy.karney import _2cos2x, _polynomial, _ALL_DOCS, cbrt
|
|
36
|
+
# from pygeodesy.lazily import _ALL_DOCS # from .karney
|
|
36
37
|
# from pygeodesy.named import _name__ # from .datums
|
|
37
38
|
from pygeodesy.props import Property, Property_RO, _update_all
|
|
38
39
|
from pygeodesy.units import _isDegrees, _isRadius, Degrees, Meter
|
|
@@ -47,7 +48,7 @@ except ImportError: # Python 3.11-
|
|
|
47
48
|
return pow(_2_0, x)
|
|
48
49
|
|
|
49
50
|
__all__ = ()
|
|
50
|
-
__version__ = '24.
|
|
51
|
+
__version__ = '24.09.03'
|
|
51
52
|
|
|
52
53
|
_TRIPS = 1024 # XXX 2 or 3?
|
|
53
54
|
|
|
@@ -222,9 +223,8 @@ class AuxLat(AuxAngle):
|
|
|
222
223
|
except KeyError:
|
|
223
224
|
pass
|
|
224
225
|
|
|
225
|
-
Cx = _CXcoeffs(aL)
|
|
226
226
|
try:
|
|
227
|
-
Cx =
|
|
227
|
+
Cx = self._CXcoeffs[auxout][auxin] # _Rtuple!
|
|
228
228
|
except KeyError as x:
|
|
229
229
|
raise AuxError(auxout=auxout, auxin=auxin, cause=x)
|
|
230
230
|
|
|
@@ -238,13 +238,12 @@ class AuxLat(AuxAngle):
|
|
|
238
238
|
else:
|
|
239
239
|
_m = _reverange # PYCHOK expected
|
|
240
240
|
|
|
241
|
-
i =
|
|
241
|
+
i = 0
|
|
242
242
|
cs = []
|
|
243
|
-
_c = cs.append
|
|
244
243
|
_p = _polynomial
|
|
245
244
|
for m in _m(aL):
|
|
246
245
|
j = i + m + 1 # order m = j - i - 1
|
|
247
|
-
|
|
246
|
+
cs.append(_p(x, Cx, i, j) * d)
|
|
248
247
|
d *= n
|
|
249
248
|
i = j
|
|
250
249
|
# assert i == len(Cx) and len(cs) == aL
|
|
@@ -378,6 +377,12 @@ class AuxLat(AuxAngle):
|
|
|
378
377
|
|
|
379
378
|
raise AuxError(auxout=auxout, Zeta_d=Zeta_d, exact=exact)
|
|
380
379
|
|
|
380
|
+
@Property_RO
|
|
381
|
+
def _CXcoeffs(self): # in .auxilats.__main__, .testAuxilats
|
|
382
|
+
'''(INTERNAL) Get the C{CX_4}, C{_6} or C{_8} coefficients.
|
|
383
|
+
'''
|
|
384
|
+
return Aux._CXcoeffs(self.ALorder)
|
|
385
|
+
|
|
381
386
|
def _Dq(self, tphi):
|
|
382
387
|
# I{Divided Difference} of (q(1) - q(sphi)) / (1 - sphi).
|
|
383
388
|
sphi = _sn(tphi)
|
|
@@ -763,19 +768,6 @@ def _Clenshaw(sinp, Zeta, cs, K):
|
|
|
763
768
|
return x
|
|
764
769
|
|
|
765
770
|
|
|
766
|
-
def _CXcoeffs(aL): # PYCHOK in .auxilats.__main__
|
|
767
|
-
'''(INTERNAL) Get the C{CX_4}, C{_6} or C{_8} coefficients.
|
|
768
|
-
'''
|
|
769
|
-
try: # from pygeodesy.auxilats._CX_x import _coeffs_x as _coeffs
|
|
770
|
-
_CX_x = _DOT_(_MODS.auxilats.__name__, _UNDER_('_CX', aL))
|
|
771
|
-
_coeffs = _MODS.getattr(_CX_x, _UNDER_('_coeffs', aL))
|
|
772
|
-
except (AttributeError, ImportError, KeyError, TypeError) as x:
|
|
773
|
-
raise AuxError(ALorder=aL, cause=x)
|
|
774
|
-
# assert _coeffs.ALorder == aL
|
|
775
|
-
# assert _coeffs.n == Aux.len(aL)
|
|
776
|
-
return _coeffs
|
|
777
|
-
|
|
778
|
-
|
|
779
771
|
def _diff_name2(Phi, diff=False, **name):
|
|
780
772
|
'''(INTERNAL) Get C{{Bdiff}=False} and C{B{name}=NN}.
|
|
781
773
|
'''
|
|
@@ -836,17 +828,17 @@ def _Newton(tphi, Zeta, _toZeta, **name):
|
|
|
836
828
|
return Phi
|
|
837
829
|
|
|
838
830
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
del
|
|
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'))
|
|
835
|
+
|
|
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!
|
|
840
|
+
|
|
841
|
+
del _Rdict, _Rtuple
|
|
850
842
|
# assert set(_AR2Coeffs.keys()) == set(_RRCoeffs.keys())
|
|
851
843
|
|
|
852
844
|
# AuxLat._Lmax = max(_AR2Coeffs.keys()) # == max(ALorder)
|
pygeodesy/auxilats/auxily.py
CHANGED
|
@@ -14,25 +14,25 @@ under the MIT/X11 License. For more information, see the U{GeographicLib
|
|
|
14
14
|
# make sure int/int division yields float quotient, see .basics
|
|
15
15
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
16
16
|
|
|
17
|
-
from pygeodesy
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
# from pygeodesy import auxilats # _MODS
|
|
18
|
+
from pygeodesy.constants import INF, NAN, isinf, isnan, _0_0, _0_5, _1_0, \
|
|
19
|
+
_copysign_1_0, _over, _1_over
|
|
20
|
+
from pygeodesy.errors import AuxError
|
|
20
21
|
from pygeodesy.fmath import hypot1 as _sc, hypot2_
|
|
21
|
-
|
|
22
|
-
from pygeodesy.
|
|
23
|
-
# from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS # from .karney
|
|
24
|
-
# from pygeodesy.named import ADict # from .karney
|
|
22
|
+
from pygeodesy.interns import NN, _DOT_, _UNDER_ # PYCHOK used!
|
|
23
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS # PYCHOK used!
|
|
25
24
|
from pygeodesy.utily import atan1
|
|
26
25
|
|
|
27
26
|
from math import asinh, copysign
|
|
28
27
|
|
|
29
28
|
__all__ = ()
|
|
30
|
-
__version__ = '24.
|
|
29
|
+
__version__ = '24.09.03'
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
class Aux(object):
|
|
34
33
|
'''Enum-style Aux names.
|
|
35
34
|
'''
|
|
35
|
+
_coeffs = {}
|
|
36
36
|
GEOGRAPHIC = PHI = GEODETIC = 0
|
|
37
37
|
PARAMETRIC = BETA = REDUCED = 1
|
|
38
38
|
GEOCENTRIC = THETA = 2 # all ...
|
|
@@ -44,18 +44,33 @@ class Aux(object):
|
|
|
44
44
|
|
|
45
45
|
def __index__(self, aux):
|
|
46
46
|
# throws KeyError, not IndexError
|
|
47
|
-
return
|
|
47
|
+
return _Aux2Greek[aux]
|
|
48
48
|
|
|
49
49
|
def __len__(self):
|
|
50
50
|
return Aux.N
|
|
51
51
|
|
|
52
|
+
def _CXcoeffs(self, aL): # in .auxLat.AuxLat._CXcoeffs
|
|
53
|
+
'''(INTERNAL) Get the C{_CX_4._coeffs_4}, C{_CX_6._coeffs_6}
|
|
54
|
+
or C{_CS_8._coeffs_8} coefficients, once.
|
|
55
|
+
'''
|
|
56
|
+
try:
|
|
57
|
+
_coeffs = Aux._coeffs[aL]
|
|
58
|
+
except KeyError:
|
|
59
|
+
try: # from pygeodesy.auxilats._CX_x import _coeffs_x as _coeffs
|
|
60
|
+
_CX_x = _DOT_(_MODS.auxilats.__name__, _UNDER_('_CX', aL))
|
|
61
|
+
_coeffs = _MODS.getattr(_CX_x, _UNDER_('_coeffs', aL))
|
|
62
|
+
except (AttributeError, ImportError, KeyError, TypeError) as x:
|
|
63
|
+
raise AuxError(ALorder=aL, cause=x)
|
|
64
|
+
Aux._coeffs[aL] = _coeffs._validate(aL, Aux.len(aL))
|
|
65
|
+
return _coeffs
|
|
66
|
+
|
|
52
67
|
def _1d(self, auxout, auxin):
|
|
53
68
|
'''Get the 1-d index into N^2 coeffs.
|
|
54
69
|
'''
|
|
55
70
|
N = Aux.N
|
|
56
71
|
if 0 <= auxout < N and 0 <= auxin < N:
|
|
57
72
|
return N * auxout + auxin
|
|
58
|
-
raise AuxError(auxout=auxout, auxin=auxin, N=N)
|
|
73
|
+
raise AuxError(auxout=auxout, auxin=auxin, N=N)
|
|
59
74
|
|
|
60
75
|
def Greek(self, aux):
|
|
61
76
|
'''Get an angle's name (C{str}).
|
|
@@ -65,9 +80,9 @@ class Aux(object):
|
|
|
65
80
|
def len(self, ALorder): # PYCHOK no cover
|
|
66
81
|
aL = ALorder # aka Lmax
|
|
67
82
|
mu = Aux.MU * (Aux.MU + 1)
|
|
68
|
-
|
|
69
|
-
return (mu * (aL * (aL + 3) -
|
|
70
|
-
|
|
83
|
+
nu = Aux.N2 - Aux.N - mu
|
|
84
|
+
return (mu * (aL * (aL + 3) - (aL // 2) * 2) // 4 +
|
|
85
|
+
nu * (aL * (aL + 1)) // 2)
|
|
71
86
|
|
|
72
87
|
def power(self, auxout, auxin):
|
|
73
88
|
'''Get the C{convert} exponent (C{int} or C{None}).
|
|
@@ -83,21 +98,13 @@ Aux = Aux() # PYCHOK singleton
|
|
|
83
98
|
_Aux2Greek = {Aux.AUTHALIC: 'Xi',
|
|
84
99
|
Aux.CONFORMAL: 'Chi',
|
|
85
100
|
Aux.GEOCENTRIC: 'Theta',
|
|
86
|
-
Aux.GEODETIC: 'Phi',
|
|
87
|
-
Aux.PARAMETRIC: 'Beta',
|
|
101
|
+
Aux.GEODETIC: 'Phi', # == .GEOGRAPHIC
|
|
102
|
+
Aux.PARAMETRIC: 'Beta', # == .REDUCED
|
|
88
103
|
Aux.RECTIFYING: 'Mu'}
|
|
89
104
|
_Greek2Aux = dict(map(reversed, _Aux2Greek.items())) # PYCHOK exported
|
|
90
105
|
# _Greek2Aux.update((_g.upper(), _x) for _g, _x in _Greek2Aux.items())
|
|
91
106
|
|
|
92
107
|
|
|
93
|
-
class _Coeffs(ADict):
|
|
94
|
-
'''(INTERNAL) With C{items keys} string-ified.
|
|
95
|
-
'''
|
|
96
|
-
def items(self):
|
|
97
|
-
for n, v in ADict.items(self):
|
|
98
|
-
yield str(n), v
|
|
99
|
-
|
|
100
|
-
|
|
101
108
|
def _Dasinh(x, y):
|
|
102
109
|
d = y - x
|
|
103
110
|
if isinf(d): # PYCHOK no cover
|
|
@@ -220,33 +227,6 @@ def _sn(tx):
|
|
|
220
227
|
return tx # preserve signed-0
|
|
221
228
|
|
|
222
229
|
|
|
223
|
-
class _Ufloats(dict): # in .auxilats.auxily
|
|
224
|
-
'''(INTERNAL) "Uniquify" floats.
|
|
225
|
-
'''
|
|
226
|
-
n = 0 # total number of floats
|
|
227
|
-
|
|
228
|
-
def __call__(self, *fs):
|
|
229
|
-
'''Return a tuple of "uniquified" floats.
|
|
230
|
-
'''
|
|
231
|
-
self.n += len(fs)
|
|
232
|
-
_f = self.setdefault
|
|
233
|
-
return tuple(_f(f, f) for f in map(float, fs)) # PYCHOK as attr
|
|
234
|
-
|
|
235
|
-
def _Coeffs(self, ALorder, coeffs):
|
|
236
|
-
'''Return C{coeffs} (C{_Coeffs}, I{embellished}).
|
|
237
|
-
'''
|
|
238
|
-
# if True:
|
|
239
|
-
# n = 0
|
|
240
|
-
# for d in coeffs.values():
|
|
241
|
-
# n += sum(d.values())
|
|
242
|
-
# assert n == self.n
|
|
243
|
-
Cx = _Coeffs(coeffs)
|
|
244
|
-
Cx.set_(ALorder=ALorder, # used in .auxilats.__main__
|
|
245
|
-
n=self.n, # total number of floats
|
|
246
|
-
u=len(self.keys())) # unique floats
|
|
247
|
-
return Cx
|
|
248
|
-
|
|
249
|
-
|
|
250
230
|
__all__ += _ALL_DOCS(Aux.__class__)
|
|
251
231
|
|
|
252
232
|
# **) MIT License
|
pygeodesy/basics.py
CHANGED
|
@@ -37,7 +37,7 @@ from math import copysign as _copysign
|
|
|
37
37
|
import inspect as _inspect
|
|
38
38
|
|
|
39
39
|
__all__ = _ALL_LAZY.basics
|
|
40
|
-
__version__ = '24.
|
|
40
|
+
__version__ = '24.09.02'
|
|
41
41
|
|
|
42
42
|
_below_ = 'below'
|
|
43
43
|
_list_tuple_types = (list, tuple)
|
|
@@ -68,8 +68,8 @@ except ImportError:
|
|
|
68
68
|
_Seqs = list, _Sequence # range for function len2 below
|
|
69
69
|
|
|
70
70
|
try:
|
|
71
|
-
_Bytes = unicode, bytearray # PYCHOK
|
|
72
|
-
_Strs = basestring, str # XXX
|
|
71
|
+
_Bytes = unicode, bytearray # PYCHOK in .internals
|
|
72
|
+
_Strs = basestring, str # XXX str == bytes
|
|
73
73
|
str2ub = ub2str = _passarg # avoids UnicodeDecodeError
|
|
74
74
|
|
|
75
75
|
def _Xstr(exc): # PYCHOK no cover
|
|
@@ -93,7 +93,7 @@ try:
|
|
|
93
93
|
except NameError: # Python 3+
|
|
94
94
|
from pygeodesy.interns import _utf_8_
|
|
95
95
|
|
|
96
|
-
_Bytes = bytes, bytearray
|
|
96
|
+
_Bytes = bytes, bytearray # in .internals
|
|
97
97
|
_Strs = str, # tuple
|
|
98
98
|
_Xstr = str
|
|
99
99
|
|
|
@@ -166,7 +166,7 @@ def clips(sb, limit=50, white=NN, length=False):
|
|
|
166
166
|
@arg sb: String (C{str} or C{bytes}).
|
|
167
167
|
@kwarg limit: Length limit (C{int}).
|
|
168
168
|
@kwarg white: Optionally, replace all whitespace (C{str}).
|
|
169
|
-
@kwarg
|
|
169
|
+
@kwarg length: If C{True}, append the original I{[length]} (C{bool}).
|
|
170
170
|
|
|
171
171
|
@return: The clipped or unclipped B{C{sb}}.
|
|
172
172
|
'''
|
|
@@ -733,7 +733,7 @@ def _xcopy(obj, deep=False):
|
|
|
733
733
|
'''(INTERNAL) Copy an object, shallow or deep.
|
|
734
734
|
|
|
735
735
|
@arg obj: The object to copy (any C{type}).
|
|
736
|
-
@kwarg deep: If C{True} make a deep, otherwise
|
|
736
|
+
@kwarg deep: If C{True}, make a deep, otherwise
|
|
737
737
|
a shallow copy (C{bool}).
|
|
738
738
|
|
|
739
739
|
@return: The copy of B{C{obj}}.
|
|
@@ -741,11 +741,22 @@ def _xcopy(obj, deep=False):
|
|
|
741
741
|
return _deepcopy(obj) if deep else _copy(obj)
|
|
742
742
|
|
|
743
743
|
|
|
744
|
+
def _xcoverage(where, *required):
|
|
745
|
+
'''(INTERNAL) Import C{coverage} and check required version.
|
|
746
|
+
'''
|
|
747
|
+
try:
|
|
748
|
+
_xpackage(_xcoverage)
|
|
749
|
+
import coverage
|
|
750
|
+
except ImportError as x:
|
|
751
|
+
raise _xImportError(x, where)
|
|
752
|
+
return _xversion(coverage, where, *required)
|
|
753
|
+
|
|
754
|
+
|
|
744
755
|
def _xdup(obj, deep=False, **items):
|
|
745
756
|
'''(INTERNAL) Duplicate an object, replacing some attributes.
|
|
746
757
|
|
|
747
758
|
@arg obj: The object to copy (any C{type}).
|
|
748
|
-
@kwarg deep: If C{True} copy deep, otherwise shallow.
|
|
759
|
+
@kwarg deep: If C{True}, copy deep, otherwise shallow (C{bool}).
|
|
749
760
|
@kwarg items: Attributes to be changed (C{any}).
|
|
750
761
|
|
|
751
762
|
@return: A duplicate of B{C{obj}} with modified
|