pygeodesy 25.1.5__py2.py3-none-any.whl → 25.4.8__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 +22 -21
- pygeodesy/auxilats/_CX_Rs.py +56 -37
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxLat.py +9 -9
- pygeodesy/auxilats/auxily.py +9 -7
- pygeodesy/basics.py +35 -6
- pygeodesy/etm.py +3 -3
- pygeodesy/fmath.py +2 -2
- pygeodesy/fsums.py +38 -54
- pygeodesy/gars.py +5 -6
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geohash.py +5 -6
- pygeodesy/geoids.py +3 -5
- pygeodesy/internals.py +6 -5
- pygeodesy/interns.py +3 -3
- pygeodesy/karney.py +6 -5
- pygeodesy/lazily.py +11 -14
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +8 -8
- {PyGeodesy-25.1.5.dist-info → pygeodesy-25.4.8.dist-info}/METADATA +37 -37
- {PyGeodesy-25.1.5.dist-info → pygeodesy-25.4.8.dist-info}/RECORD +24 -24
- {PyGeodesy-25.1.5.dist-info → pygeodesy-25.4.8.dist-info}/WHEEL +0 -0
- {PyGeodesy-25.1.5.dist-info → pygeodesy-25.4.8.dist-info}/top_level.txt +0 -0
pygeodesy/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ methods for geodetic (lat-/longitude), geocentric (U{ECEF<https://WikiPedia.org/
|
|
|
7
7
|
cartesian) and certain U{triaxial ellipsoidal<https://GeographicLib.SourceForge.io/1.44/triaxial.html>}
|
|
8
8
|
coordinates.
|
|
9
9
|
|
|
10
|
-
Transcoded
|
|
10
|
+
Transcoded in part from U{JavaScript originals<https://GitHub.com/ChrisVeness/geodesy>} by I{Chris Veness (C)
|
|
11
11
|
2005-2024} and from several U{C++ classes<https://GeographicLib.SourceForge.io/C++/doc/annotated.html>} by I{Charles
|
|
12
12
|
F. F. Karney (C) 2008-2024} and published under the same U{MIT License<https://OpenSource.org/licenses/MIT>}**.
|
|
13
13
|
|
|
@@ -64,19 +64,19 @@ wiki/Hausdorff_distance>} distances.
|
|
|
64
64
|
Installation
|
|
65
65
|
============
|
|
66
66
|
|
|
67
|
-
To install
|
|
68
|
-
|
|
67
|
+
To install C{pygeodesy}, type C{python[3] -m pip install pygeodesy} or C{python[3] -m easy_install
|
|
68
|
+
pygeodesy} in a terminal or command window.
|
|
69
69
|
|
|
70
|
-
If the wheel C{
|
|
71
|
-
PyPI.org/project/
|
|
70
|
+
If the wheel C{pygeodesy-yy.m.d-py2.py3-none-any.whl} is missing in U{PyPI Download files<https://
|
|
71
|
+
PyPI.org/project/pygeodesy/#files>}, download the file from U{GitHub/dist<https://GitHub.com/mrJean1/
|
|
72
72
|
PyGeodesy/tree/master/dist>}. Install that with C{python[3] -m pip install <path-to-downloaded-wheel>}
|
|
73
73
|
and verify with C{python[3] -m pygeodesy}.
|
|
74
74
|
|
|
75
|
-
Alternatively, download C{
|
|
75
|
+
Alternatively, download C{pygeodesy-yy.m.d.tar.gz} from U{PyPI<https://PyPI.org/project/pygeodesy>}
|
|
76
76
|
or U{GitHub<https://GitHub.com/mrJean1/PyGeodesy>}, C{unzip} the downloaded file, C{cd} to
|
|
77
|
-
directory C{
|
|
77
|
+
directory C{pygeodesy-yy.m.d} and type C{python[3] setup.py install}.
|
|
78
78
|
|
|
79
|
-
To run all
|
|
79
|
+
To run all C{pygeodesy} tests, type C{python[3] test/run.py} or type C{python[3] test/unitTestSuite.py}
|
|
80
80
|
before or after installation.
|
|
81
81
|
|
|
82
82
|
Dependencies
|
|
@@ -113,16 +113,16 @@ env variable C{PYGEODESY_RHUMBSOLVE} or with property L{Ellipsoid.rhumbsolve}.
|
|
|
113
113
|
Documentation
|
|
114
114
|
=============
|
|
115
115
|
|
|
116
|
-
In addition to the C{pygeodesy} package, the U{
|
|
116
|
+
In addition to the C{pygeodesy} package, the U{pygeodesy<https://PyPI.org/project/pygeodesy>}
|
|
117
117
|
U{distribution files<https://GitHub.com/mrJean1/PyGeodesy/tree/master/dist>} contain the tests,
|
|
118
118
|
the test results (on macOS only) and the complete U{documentation<https://mrJean1.GitHub.io/PyGeodesy>}
|
|
119
119
|
(generated by U{Epydoc<https://PyPI.org/project/epydoc>} using command line:
|
|
120
|
-
C{epydoc --html --no-private --no-source --name=
|
|
120
|
+
C{epydoc --html --no-private --no-source --name=pygeodesy --url=... -v pygeodesy}).
|
|
121
121
|
|
|
122
122
|
Tests
|
|
123
123
|
=====
|
|
124
124
|
|
|
125
|
-
The tests ran with Python 3.13.
|
|
125
|
+
The tests ran with Python 3.13.2 (with U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0),
|
|
126
126
|
Python 3.12.7 (with U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0,
|
|
127
127
|
U{numpy<https://PyPI.org/project/numpy>} 2.1.0, U{scipy<https://PyPI.org/project/scipy>} 1.14.1,
|
|
128
128
|
U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
|
|
@@ -139,20 +139,21 @@ U{numpy<https://PyPI.org/project/numpy>} 1.16.6, U{scipy<https://PyPI.org/projec
|
|
|
139
139
|
U{GeoConvert<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
|
|
140
140
|
U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
|
|
141
141
|
U{IntersectTool<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3 and
|
|
142
|
-
U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3), all in 64-bit on
|
|
142
|
+
U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3), all in 64-bit on
|
|
143
|
+
macOS 15.4 Sequoia.
|
|
143
144
|
|
|
144
145
|
All tests ran with and without C{lazy import} for Python 3 and with command line option C{-W default} and
|
|
145
146
|
env variable C{PYGEODESY_WARNINGS=on} for all Python versions. The results of those tests are included in
|
|
146
147
|
the distribution files.
|
|
147
148
|
|
|
148
149
|
Test coverage has been measured with U{coverage<https://PyPI.org/project/coverage>} 7.6.1 using Python
|
|
149
|
-
3.13.
|
|
150
|
+
3.13.2, 3.12.7, 3.11.5 and 3.10.8. The complete coverage report in HTML and a PDF summary are included in
|
|
150
151
|
the distribution files.
|
|
151
152
|
|
|
152
|
-
Python 3.13.
|
|
153
|
+
Python 3.13.2, 3.12.7, 3.11.5 and 3.10.8 run on Apple M1 Silicon (C{arm64}), I{natively}. Python 2.7.18 runs
|
|
153
154
|
on Intel (C{x86_64}) or Intel I{emulation} ("C{arm64_x86_64}", see function L{machine<pygeodesy.machine>}).
|
|
154
155
|
|
|
155
|
-
The tests also ran with Python 3.13.
|
|
156
|
+
The tests also ran with Python 3.13.2 (and U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on
|
|
156
157
|
U{Debian 12<https://Cirrus-CI.com/github/mrJean1/PyGeodesy/master>} in 64-bit only, with Python 3.12.5 (and
|
|
157
158
|
U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on U{Windows 2019Server
|
|
158
159
|
<https://CI.AppVeyor.com/project/mrJean1/pygeodesy>} in 64-bit only and with Python 2.7.18 (and U{geographiclib
|
|
@@ -162,7 +163,7 @@ in 64- and 32-bit.
|
|
|
162
163
|
A single-File and single-Directory application with C{pygeodesy} has been bundled using U{PyInstaller
|
|
163
164
|
<https://PyPI.org/project/pyinstaller>} 3.4 and 64-bit Python 3.7.3 on macOS 10.13.6 High Sierra.
|
|
164
165
|
|
|
165
|
-
Previously, the tests were run with Python 3.13.0, 3.12.0-6, 3.11.2-4, 3.10.1-7, 3.9.6, 3.9.1, 3.8.7, 3.7.1, 2.7.15,
|
|
166
|
+
Previously, the tests were run with Python 3.13.0-1, 3.12.0-6, 3.11.2-4, 3.10.1-7, 3.9.6, 3.9.1, 3.8.7, 3.7.1, 2.7.15,
|
|
166
167
|
U{PyPy<https://PyPy.org>} 7.3.12 (Python 3.10.12), 7.3.1 (Python 3.6.9) and U{PyPy<https://PyPy.org>} 7.1.1 (Python
|
|
167
168
|
2.7.13) (and U{geographiclib <https://PyPI.org/project/geographiclib>} 1.52, U{numpy<https://PyPI.org/project/numpy>}
|
|
168
169
|
1.16.3, 1.16.4, 1.16.6, 1.19.0, 1.19.4, 1.19.5 or 1.22.4 and U{scipy<https://PyPI.org/project/scipy>} 1.2.1, 1.4.1,
|
|
@@ -171,7 +172,7 @@ U{PyPy<https://PyPy.org>} 7.3.12 (Python 3.10.12), 7.3.1 (Python 3.6.9) and U{Py
|
|
|
171
172
|
1.16.5, 1.16.2, 1.15.2, 1.14.0, 1.13.1, 1.8.0rc1 or 1.6.2 and U{scipy<https://PyPI.org/project/scipy>} 1.5.0), U{PyPy
|
|
172
173
|
<https://PyPy.org>} 7.3.0 (Python 2.7.13 and 3.6.9), U{PyPy<https://PyPy.org>} 6.0.0 (Python 2.7.13 and 3.5.3)
|
|
173
174
|
and U{Intel-Python<https://software.Intel.com/en-us/distribution-for-python>} 3.5.3 (and U{numpy
|
|
174
|
-
<https://PyPI.org/project/numpy>} 1.11.3) on macOS 14.0-
|
|
175
|
+
<https://PyPI.org/project/numpy>} 1.11.3) on macOS 14.0-6.1 Sonoma, 13.0-5.2 Ventura, 12.1-6 Monterey, 11.0-5.2-6.1
|
|
175
176
|
Big Sur (aka 10.16), 10.15.3, 10.15.5-7 Catalina, 10.14 Mojave, 10.13.6 High Sierra and 10.12 Sierra, MacOS X
|
|
176
177
|
10.11 El Capitan and/or MacOS X 10.10 Yosemite, with U{Pythonista<https://OMZ-Software.com/pythonista>}3.2 (with
|
|
177
178
|
geographiclib 1.50 or 1.49 and numpy 1.8.0) on iOS 14.4.2, 11.4.1, 12.0-3 on iPad4, iPhone6, iPhone10 and/or
|
|
@@ -186,7 +187,7 @@ All Python source code has been statically U{checked<https://GitHub.com/ActiveSt
|
|
|
186
187
|
Python/546532_PyChecker_postprocessor>} with U{PyChecker<https://PyPI.org/project/pychecker>}, U{PyFlakes
|
|
187
188
|
<https://PyPI.org/project/pyflakes>}, U{PyCodeStyle<https://PyPI.org/project/pycodestyle>} (formerly Pep8) and
|
|
188
189
|
U{McCabe<https://PyPI.org/project/mccabe>} using Python 2.7.18 and with U{Flake8<https://PyPI.org/project/flake8>}
|
|
189
|
-
using Python 3.11.5, both in 64-bit on macOS
|
|
190
|
+
using Python 3.11.5, both in 64-bit on macOS 15.4 Sequoia.
|
|
190
191
|
|
|
191
192
|
For a summary of all I{Karney}-based functionality in C{pygeodesy}, see module U{karney
|
|
192
193
|
<https://mrJean1.GitHub.io/PyGeodesy/docs/pygeodesy.karney-module.html>}.
|
|
@@ -197,7 +198,7 @@ characters and if so, I{not} C{unicode}.
|
|
|
197
198
|
Env variables
|
|
198
199
|
=============
|
|
199
200
|
|
|
200
|
-
The following environment variables are observed by C{
|
|
201
|
+
The following environment variables are observed by C{pygeodesy}:
|
|
201
202
|
|
|
202
203
|
- C{PYGEODESY_EXCEPTION_CHAINING} - see module L{errors<pygeodesy.errors>}.
|
|
203
204
|
- C{PYGEODESY_FMT_FORM} - see module L{dms<pygeodesy.dms>}.
|
|
@@ -355,7 +356,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.}
|
|
|
355
356
|
|
|
356
357
|
@var pygeodesy_abspath: Fully qualified C{pygeodesy} directory name (C{str}).
|
|
357
358
|
|
|
358
|
-
@var version: Normalized C{
|
|
359
|
+
@var version: Normalized C{pygeodesy} version (C{str}).
|
|
359
360
|
'''
|
|
360
361
|
|
|
361
362
|
import os.path as _os_path
|
|
@@ -598,7 +599,7 @@ else:
|
|
|
598
599
|
|
|
599
600
|
from pygeodesy.internals import _version2, _DOT_ # PYCHOK import
|
|
600
601
|
# from pygeodesy.interns import _DOT_ # from .internals
|
|
601
|
-
__version__ = '25.
|
|
602
|
+
__version__ = '25.04.08'
|
|
602
603
|
# see setup.py for similar logic
|
|
603
604
|
version = _DOT_(*_version2(__version__, n=3))
|
|
604
605
|
|
pygeodesy/auxilats/_CX_Rs.py
CHANGED
|
@@ -11,8 +11,10 @@ MIT/X11 License. For more information, see <https:#GeographicLib.SourceForge.io
|
|
|
11
11
|
# make sure int/int division yields float quotient, see .basics
|
|
12
12
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
13
13
|
|
|
14
|
-
from pygeodesy.
|
|
14
|
+
# from pygeodesy.basics import _splituple # _MODS
|
|
15
|
+
from pygeodesy.constants import _floats as _Cs
|
|
15
16
|
from pygeodesy.errors import _AssertionError, _MODS
|
|
17
|
+
# from pygeodesy.internals import _sizeof # _MODS
|
|
16
18
|
from pygeodesy.interns import NN, MISSING, _COMMA_, _duplicate_, _NL_, \
|
|
17
19
|
_QUOTE3_, _SLASH_, _ELLIPSIS4_ # PYCHOK used!
|
|
18
20
|
# from pygeodesy.lazily import _ALL_MODS as _MODS # from .errors
|
|
@@ -20,7 +22,7 @@ from pygeodesy.named import ADict, Property_RO
|
|
|
20
22
|
# from pygeodesy.props import Property_RO # from .named
|
|
21
23
|
|
|
22
24
|
__all__ = ()
|
|
23
|
-
__version__ = '
|
|
25
|
+
__version__ = '25.04.08'
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
class _Rcoeffs(ADict):
|
|
@@ -31,17 +33,19 @@ class _Rcoeffs(ADict):
|
|
|
31
33
|
'''
|
|
32
34
|
try:
|
|
33
35
|
if not isinstance(coeffs, dict):
|
|
34
|
-
raise
|
|
36
|
+
raise _RsError(coeffs=type(coeffs))
|
|
35
37
|
n = 0
|
|
36
38
|
for k, d in coeffs.items():
|
|
39
|
+
if not isinstance(k, _Rkey):
|
|
40
|
+
raise _RsError(k=type(k))
|
|
37
41
|
if not isinstance(d, _Rdict):
|
|
38
|
-
raise
|
|
42
|
+
raise _RsError(k=k, d=type(d))
|
|
39
43
|
n += d.n
|
|
40
44
|
|
|
41
45
|
ADict.__init__(self, coeffs)
|
|
42
46
|
self.set_(ALorder=ALorder, n=n) # in .validate
|
|
43
47
|
except Exception as x:
|
|
44
|
-
raise
|
|
48
|
+
raise _RsError(ALorder=ALorder, cause=x)
|
|
45
49
|
|
|
46
50
|
def bnuz4(self): # in .auxilats.__main__ # PYCHOK no cover
|
|
47
51
|
# get C{(strB, number, unique, floatB)} rationals
|
|
@@ -53,8 +57,8 @@ class _Rcoeffs(ADict):
|
|
|
53
57
|
t = R._tuple
|
|
54
58
|
z += _zB(t) # Float
|
|
55
59
|
# assert R.Rdict is None
|
|
56
|
-
n +=
|
|
57
|
-
u +=
|
|
60
|
+
n += len(t)
|
|
61
|
+
u += sum(1 for f in t if f in _Cs)
|
|
58
62
|
return b, n, (n - u), z
|
|
59
63
|
|
|
60
64
|
def items(self): # string-ify keys # PYCHOK no cover
|
|
@@ -74,48 +78,48 @@ class _Rcoeffs(ADict):
|
|
|
74
78
|
# for R in self._Rtuples():
|
|
75
79
|
# assert isinstance(R, _Rtuple)
|
|
76
80
|
if aL != a or lenAux != n:
|
|
77
|
-
raise
|
|
81
|
+
raise _RsError(aL=aL, ALorder=a, lenAux=lenAux, n=n)
|
|
78
82
|
return self
|
|
79
83
|
|
|
80
84
|
|
|
81
85
|
class _Rdict(dict): # in ._CX_#, .auxLat, .rhumb.aux_
|
|
82
86
|
'''(INTERNAL) Dict of C{_Rtuple}s.
|
|
83
87
|
'''
|
|
84
|
-
n = 0 # sum(R.k_n_k[1] for
|
|
88
|
+
n = 0 # sum(R.k_n_k[1] for R in Rtuples)
|
|
85
89
|
|
|
86
90
|
def __init__(self, nt, *Rtuples):
|
|
87
91
|
'''New C{_Rdict}.
|
|
88
92
|
'''
|
|
89
93
|
if not Rtuples:
|
|
90
|
-
raise
|
|
94
|
+
raise _RsError(Rtuples=MISSING)
|
|
91
95
|
|
|
92
96
|
for R in Rtuples:
|
|
93
97
|
if not isinstance(R, _Rtuple):
|
|
94
|
-
raise
|
|
98
|
+
raise _RsError(R, R=type(R))
|
|
95
99
|
k, n, _ = R.k_n_rs
|
|
96
100
|
if k in self:
|
|
97
|
-
raise
|
|
101
|
+
raise _RsError(_duplicate_, k=k)
|
|
98
102
|
R.Rdict = self
|
|
99
103
|
self[k] = R # overwritten in self._floatuple
|
|
100
104
|
self.n += n
|
|
101
105
|
if self.n != nt:
|
|
102
|
-
raise
|
|
106
|
+
raise _RsError(n=n, nt=nt)
|
|
103
107
|
|
|
104
108
|
def _floats(self, rs):
|
|
105
109
|
# yield floats from a string of comma-separated rationals
|
|
106
110
|
def _p_q(p=NN, q=1, *x):
|
|
107
111
|
return (NN if x else p), q
|
|
108
112
|
|
|
109
|
-
_get =
|
|
110
|
-
for r in
|
|
113
|
+
_get = _Cs.get
|
|
114
|
+
for r in _MODS.basics._splituple(rs):
|
|
111
115
|
p, q = _p_q(*r.split(_SLASH_))
|
|
112
116
|
if p:
|
|
113
117
|
f = int(p) / int(q) # fractions.Fraction?
|
|
114
118
|
if not isinstance(f, float):
|
|
115
|
-
raise
|
|
116
|
-
yield _get(f, f) # from .constants
|
|
119
|
+
raise _RsError(rs, f=f, p=p, q=q, r=r)
|
|
120
|
+
yield _get(f, f) # from .constants
|
|
117
121
|
else:
|
|
118
|
-
raise
|
|
122
|
+
raise _RsError(rs, r=r)
|
|
119
123
|
|
|
120
124
|
def _floatuple(self, Rtuple):
|
|
121
125
|
# return a tuple of floats from an C{_Rtuple}
|
|
@@ -125,13 +129,24 @@ class _Rdict(dict): # in ._CX_#, .auxLat, .rhumb.aux_
|
|
|
125
129
|
# @see: <https://StackOverflow.com/questions/10632839/>
|
|
126
130
|
# and <https://realPython.com/python-flatten-list/>
|
|
127
131
|
if len(t) != n:
|
|
128
|
-
raise
|
|
129
|
-
self[k] = t
|
|
132
|
+
raise _RsError(*rs, len=len(t), n=n)
|
|
133
|
+
self[k] = t # replace _Rtuple with tuple instance
|
|
130
134
|
return t
|
|
131
135
|
|
|
132
136
|
|
|
133
|
-
class
|
|
134
|
-
'''(INTERNAL) For C{_Rdict}
|
|
137
|
+
class _Rkey(int):
|
|
138
|
+
'''(INTERNAL) For C{_Rcoeffs}, C{_Rdict} and C{_Rtuple} keys.
|
|
139
|
+
'''
|
|
140
|
+
def __new__(cls, k):
|
|
141
|
+
if not isinstance(k, int):
|
|
142
|
+
raise _RsError(k=type(k))
|
|
143
|
+
if not 0 <= k <= 8: # 0.._MODS.auxilats.auxily.Aux.N + 2
|
|
144
|
+
raise _RsError(k=k)
|
|
145
|
+
return int.__new__(cls, k)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class _RsError(_AssertionError):
|
|
149
|
+
'''(INTERNAL) For C{_Rcoeffs}, C{_Rdict or} C{_Rtuple} issues.
|
|
135
150
|
'''
|
|
136
151
|
def __init__(self, *rs, **kwds_cause): # PYCHOK no cover
|
|
137
152
|
if rs:
|
|
@@ -147,7 +162,7 @@ class _RdictError(_AssertionError):
|
|
|
147
162
|
class _Rtuple(list): # MUST be list, NOT tuple!
|
|
148
163
|
'''(INTERNAL) I{Pseudo-tuple} of float rationals used in C{_Rdict}s.
|
|
149
164
|
'''
|
|
150
|
-
Rdict = None
|
|
165
|
+
Rdict = None # set by _Rdict.__init__
|
|
151
166
|
k_n_rs = None, 0, ()
|
|
152
167
|
|
|
153
168
|
def __init__(self, k, n, *rs):
|
|
@@ -156,20 +171,26 @@ class _Rtuple(list): # MUST be list, NOT tuple!
|
|
|
156
171
|
where C{p} and C{q} are C{int} digits only.
|
|
157
172
|
'''
|
|
158
173
|
try:
|
|
174
|
+
if not isinstance(k, _Rkey):
|
|
175
|
+
raise _RsError(k=type(k))
|
|
176
|
+
if not (isinstance(n, int) and n > 0):
|
|
177
|
+
raise _RsError(n=type(n))
|
|
159
178
|
if not rs:
|
|
160
|
-
raise
|
|
179
|
+
raise _RsError(rs=MISSING)
|
|
161
180
|
for t in rs:
|
|
162
181
|
if not isinstance(t, str):
|
|
163
|
-
raise
|
|
164
|
-
if not (isinstance(n, int) and n > 0):
|
|
165
|
-
raise _RdictError(n=type(n))
|
|
182
|
+
raise _RsError(rs=type(t))
|
|
166
183
|
self.k_n_rs = k, n, rs
|
|
167
184
|
except Exception as x:
|
|
168
|
-
raise
|
|
185
|
+
raise _RsError(*rs, k=k, n=n, cause=x)
|
|
169
186
|
|
|
170
187
|
def __getitem__(self, i):
|
|
171
188
|
return self._tuple[i]
|
|
172
189
|
|
|
190
|
+
if _MODS.sys_version_info2 < (3, 0):
|
|
191
|
+
def __getslice__(self, i, j):
|
|
192
|
+
return self._tuple[slice(i, j)]
|
|
193
|
+
|
|
173
194
|
def __iter__(self):
|
|
174
195
|
return iter(self._tuple)
|
|
175
196
|
|
|
@@ -178,26 +199,24 @@ class _Rtuple(list): # MUST be list, NOT tuple!
|
|
|
178
199
|
|
|
179
200
|
@Property_RO
|
|
180
201
|
def _tuple(self):
|
|
181
|
-
# build the C{tuple} once
|
|
182
|
-
#
|
|
183
|
-
# this C{_Rlist} with the C{tuple} values
|
|
184
|
-
# for the initial __getitem__ retrieval[s]
|
|
202
|
+
# build the C{tuple} I{once} and replace
|
|
203
|
+
# C{_Rdict[key]} item with the C{tuple}
|
|
185
204
|
try:
|
|
186
|
-
k, n, rs = self.k_n_rs
|
|
205
|
+
k, n, rs = self.k_n_rs # for except ...
|
|
187
206
|
t = self.Rdict._floatuple(self)
|
|
188
|
-
|
|
207
|
+
# self[:] = t # MUST copy into self?
|
|
189
208
|
except Exception as x:
|
|
190
209
|
if len(rs) > 1 and _QUOTE3_ in str(x):
|
|
191
210
|
rs = rs[0], _ELLIPSIS4_
|
|
192
|
-
raise
|
|
211
|
+
raise _RsError(k=k, n=n, rs=rs, cause=x)
|
|
193
212
|
del self.Rdict, self.k_n_rs # trash refs
|
|
194
213
|
return t
|
|
195
214
|
|
|
196
215
|
def append(self, arg):
|
|
197
|
-
raise
|
|
216
|
+
raise _RsError(append=arg)
|
|
198
217
|
|
|
199
218
|
def extend(self, arg):
|
|
200
|
-
raise
|
|
219
|
+
raise _RsError(extend=arg)
|
|
201
220
|
|
|
202
221
|
# **) MIT License
|
|
203
222
|
#
|
pygeodesy/auxilats/__init__.py
CHANGED
|
@@ -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__ = '
|
|
32
|
+
__version__ = '25.01.15'
|
|
33
33
|
|
|
34
34
|
# **) MIT License
|
|
35
35
|
#
|
pygeodesy/auxilats/__main__.py
CHANGED
|
@@ -5,7 +5,7 @@ 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.04'
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _main(**ALorder): # PYCHOK no cover
|
|
@@ -36,7 +36,7 @@ def _main(**ALorder): # PYCHOK no cover
|
|
|
36
36
|
print(_usage(__file__))
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
from sys import argv # .internals.
|
|
39
|
+
from sys import argv # .internals._isPyChOK
|
|
40
40
|
_main(ALorder=int(argv[1])) if len(argv) == 2 and argv[1].isdigit() else _main()
|
|
41
41
|
|
|
42
42
|
# % python3.12 -m pygeodesy.auxilats 8
|
pygeodesy/auxilats/auxLat.py
CHANGED
|
@@ -18,7 +18,7 @@ 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
|
|
21
|
+
from pygeodesy.auxilats._CX_Rs import _Rdict, _Rkey, _Rtuple
|
|
22
22
|
from pygeodesy.basics import _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, \
|
|
@@ -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.01.15'
|
|
52
52
|
|
|
53
53
|
_TRIPS = 1024 # XXX 2 or 3?
|
|
54
54
|
|
|
@@ -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,6 +15,7 @@ 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
|
|
18
19
|
from pygeodesy.constants import INF, NAN, isinf, isnan, _0_0, _0_5, _1_0, \
|
|
19
20
|
_copysign_1_0, _over, _1_over
|
|
20
21
|
from pygeodesy.errors import AuxError
|
|
@@ -26,19 +27,19 @@ from pygeodesy.utily import atan1
|
|
|
26
27
|
from math import asinh, copysign
|
|
27
28
|
|
|
28
29
|
__all__ = ()
|
|
29
|
-
__version__ = '
|
|
30
|
+
__version__ = '25.01.15'
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
class Aux(object):
|
|
33
34
|
'''Enum-style Aux names.
|
|
34
35
|
'''
|
|
35
36
|
_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
|
|
37
|
+
GEOGRAPHIC = PHI = GEODETIC = _Rkey(0)
|
|
38
|
+
PARAMETRIC = BETA = REDUCED = _Rkey(1)
|
|
39
|
+
GEOCENTRIC = THETA = _Rkey(2) # all ...
|
|
40
|
+
RECTIFYING = MU = _Rkey(3) # use n^2
|
|
41
|
+
CONFORMAL = CHI = _Rkey(4) # use n
|
|
42
|
+
AUTHALIC = XI = _Rkey(5) # use n
|
|
42
43
|
N = 6
|
|
43
44
|
N2 = 36
|
|
44
45
|
|
|
@@ -228,6 +229,7 @@ def _sn(tx):
|
|
|
228
229
|
|
|
229
230
|
|
|
230
231
|
__all__ += _ALL_DOCS(Aux.__class__)
|
|
232
|
+
del _Rkey
|
|
231
233
|
|
|
232
234
|
# **) MIT License
|
|
233
235
|
#
|
pygeodesy/basics.py
CHANGED
|
@@ -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.01.17'
|
|
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
|
|
|
@@ -371,7 +396,7 @@ def isiterable(obj, strict=False):
|
|
|
371
396
|
@return: C{True} if C{iterable}, C{False} otherwise.
|
|
372
397
|
'''
|
|
373
398
|
# <https://PyPI.org/project/isiterable/>
|
|
374
|
-
return isiterabletype(obj) if strict else hasattr(obj, '__iter__') # map, range, set
|
|
399
|
+
return bool(isiterabletype(obj)) if strict else hasattr(obj, '__iter__') # map, range, set
|
|
375
400
|
|
|
376
401
|
|
|
377
402
|
def isiterablen(obj, strict=False):
|
|
@@ -383,7 +408,7 @@ def isiterablen(obj, strict=False):
|
|
|
383
408
|
@return: C{True} if C{iterable} with C{len}gth, C{False} otherwise.
|
|
384
409
|
'''
|
|
385
410
|
_has = isiterabletype if strict else hasattr
|
|
386
|
-
return _has(obj, '__len__') and _has(obj, '__getitem__')
|
|
411
|
+
return bool(_has(obj, '__len__') and _has(obj, '__getitem__'))
|
|
387
412
|
|
|
388
413
|
|
|
389
414
|
def isiterabletype(obj, method='__iter__'):
|
|
@@ -763,9 +788,13 @@ def _splituple(strs, *sep_splits): # in .mgrs, ...
|
|
|
763
788
|
'''(INTERNAL) Split a C{comma}- or C{whitespace}-separated
|
|
764
789
|
string into a C{tuple} of stripped C{str}ings.
|
|
765
790
|
'''
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
791
|
+
if sep_splits:
|
|
792
|
+
t = (t.strip() for t in strs.split(*sep_splits))
|
|
793
|
+
else:
|
|
794
|
+
t = strs.strip()
|
|
795
|
+
if t:
|
|
796
|
+
t = t.replace(_COMMA_, _SPACE_).split()
|
|
797
|
+
return tuple(t) if t else ()
|
|
769
798
|
|
|
770
799
|
|
|
771
800
|
def unsigned0(x):
|
pygeodesy/etm.py
CHANGED
|
@@ -93,7 +93,7 @@ from pygeodesy.utm import _cmlon, _LLEB, _parseUTM5, _toBand, _toXtm8, \
|
|
|
93
93
|
from math import asinh, degrees, radians, sinh, sqrt
|
|
94
94
|
|
|
95
95
|
__all__ = _ALL_LAZY.etm
|
|
96
|
-
__version__ = '
|
|
96
|
+
__version__ = '25.01.12'
|
|
97
97
|
|
|
98
98
|
_OVERFLOW = _1_EPS**2 # ~2e+31
|
|
99
99
|
_TAYTOL = pow(EPS, 0.6)
|
|
@@ -196,7 +196,7 @@ class Etm(Utm):
|
|
|
196
196
|
def _toLLEB(self, unfalse=True, **unused): # PYCHOK signature
|
|
197
197
|
'''(INTERNAL) Compute (ellipsoidal) lat- and longitude.
|
|
198
198
|
'''
|
|
199
|
-
|
|
199
|
+
d, xTM = self.datum, self.exactTM
|
|
200
200
|
# double check that this and exactTM's ellipsoid match
|
|
201
201
|
if xTM._E != d.ellipsoid: # PYCHOK no cover
|
|
202
202
|
t = repr(d.ellipsoid)
|
|
@@ -1022,7 +1022,7 @@ class ExactTransverseMercator(_NamedBase):
|
|
|
1022
1022
|
g_k += atan1d(tau), degrees(lam)
|
|
1023
1023
|
return g_k # or (g, k, lat, lon)
|
|
1024
1024
|
|
|
1025
|
-
_allPropertiesOf_n(22, ExactTransverseMercator, Property_RO) # PYCHOK assert
|
|
1025
|
+
_allPropertiesOf_n(22, ExactTransverseMercator, Property_RO) # PYCHOK assert _ROs = ...
|
|
1026
1026
|
del _0_1, _allPropertiesOf_n, EPS, _1_EPS, _EWGS84
|
|
1027
1027
|
|
|
1028
1028
|
|
pygeodesy/fmath.py
CHANGED
|
@@ -23,7 +23,7 @@ from math import fabs, sqrt # pow
|
|
|
23
23
|
import operator as _operator # in .datums, .trf, .utm
|
|
24
24
|
|
|
25
25
|
__all__ = _ALL_LAZY.fmath
|
|
26
|
-
__version__ = '
|
|
26
|
+
__version__ = '25.01.09'
|
|
27
27
|
|
|
28
28
|
# sqrt(2) - 1 <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
29
29
|
_0_4142 = 0.41421356237309504880 # ... ~ 3730904090310553 / 9007199254740992
|
|
@@ -981,7 +981,7 @@ def _root(x, p, where):
|
|
|
981
981
|
raise ValueError(_negative_)
|
|
982
982
|
except Exception as X:
|
|
983
983
|
raise _xError(X, unstr(where, x))
|
|
984
|
-
return _0_0
|
|
984
|
+
return _0_0 if p else _1_0
|
|
985
985
|
|
|
986
986
|
|
|
987
987
|
def sqrt0(x, Error=None):
|