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.
Files changed (96) hide show
  1. pygeodesy/__init__.py +35 -31
  2. pygeodesy/__main__.py +3 -3
  3. pygeodesy/albers.py +29 -36
  4. pygeodesy/auxilats/_CX_4.py +2 -2
  5. pygeodesy/auxilats/_CX_6.py +2 -2
  6. pygeodesy/auxilats/_CX_8.py +2 -2
  7. pygeodesy/auxilats/_CX_Rs.py +59 -40
  8. pygeodesy/auxilats/__init__.py +3 -3
  9. pygeodesy/auxilats/__main__.py +9 -7
  10. pygeodesy/auxilats/auxAngle.py +2 -2
  11. pygeodesy/auxilats/auxLat.py +13 -13
  12. pygeodesy/auxilats/auxily.py +13 -9
  13. pygeodesy/azimuthal.py +7 -6
  14. pygeodesy/basics.py +65 -22
  15. pygeodesy/booleans.py +12 -10
  16. pygeodesy/cartesianBase.py +21 -20
  17. pygeodesy/clipy.py +11 -10
  18. pygeodesy/constants.py +11 -10
  19. pygeodesy/css.py +14 -11
  20. pygeodesy/datums.py +8 -8
  21. pygeodesy/deprecated/bases.py +2 -2
  22. pygeodesy/deprecated/classes.py +2 -2
  23. pygeodesy/deprecated/consterns.py +4 -4
  24. pygeodesy/dms.py +8 -8
  25. pygeodesy/ecef.py +10 -7
  26. pygeodesy/elevations.py +9 -8
  27. pygeodesy/ellipsoidalBase.py +19 -8
  28. pygeodesy/ellipsoidalBaseDI.py +17 -15
  29. pygeodesy/ellipsoidalNvector.py +6 -3
  30. pygeodesy/ellipsoidalVincenty.py +4 -1
  31. pygeodesy/ellipsoids.py +167 -138
  32. pygeodesy/elliptic.py +9 -9
  33. pygeodesy/errors.py +44 -43
  34. pygeodesy/etm.py +9 -9
  35. pygeodesy/fmath.py +10 -9
  36. pygeodesy/formy.py +11 -12
  37. pygeodesy/frechet.py +216 -109
  38. pygeodesy/fstats.py +5 -4
  39. pygeodesy/fsums.py +107 -122
  40. pygeodesy/gars.py +7 -7
  41. pygeodesy/geodesici.py +15 -14
  42. pygeodesy/geodesicw.py +34 -32
  43. pygeodesy/geodesicx/__init__.py +1 -1
  44. pygeodesy/geodesicx/__main__.py +12 -10
  45. pygeodesy/geodesicx/gx.py +30 -33
  46. pygeodesy/geodesicx/gxarea.py +2 -2
  47. pygeodesy/geodesicx/gxline.py +5 -5
  48. pygeodesy/geodsolve.py +18 -17
  49. pygeodesy/geohash.py +7 -8
  50. pygeodesy/geoids.py +35 -34
  51. pygeodesy/hausdorff.py +17 -13
  52. pygeodesy/heights.py +2 -4
  53. pygeodesy/internals.py +31 -46
  54. pygeodesy/interns.py +12 -9
  55. pygeodesy/iters.py +8 -8
  56. pygeodesy/karney.py +73 -66
  57. pygeodesy/ktm.py +5 -5
  58. pygeodesy/latlonBase.py +14 -18
  59. pygeodesy/lazily.py +73 -74
  60. pygeodesy/lcc.py +11 -9
  61. pygeodesy/ltp.py +8 -7
  62. pygeodesy/ltpTuples.py +2 -2
  63. pygeodesy/mgrs.py +7 -6
  64. pygeodesy/named.py +47 -31
  65. pygeodesy/nvectorBase.py +7 -7
  66. pygeodesy/osgr.py +9 -8
  67. pygeodesy/points.py +12 -10
  68. pygeodesy/props.py +25 -25
  69. pygeodesy/resections.py +11 -10
  70. pygeodesy/rhumb/__init__.py +1 -1
  71. pygeodesy/rhumb/aux_.py +14 -14
  72. pygeodesy/rhumb/bases.py +22 -20
  73. pygeodesy/rhumb/ekx.py +6 -6
  74. pygeodesy/rhumb/solve.py +15 -15
  75. pygeodesy/solveBase.py +3 -3
  76. pygeodesy/sphericalBase.py +6 -6
  77. pygeodesy/sphericalNvector.py +6 -5
  78. pygeodesy/sphericalTrigonometry.py +8 -7
  79. pygeodesy/streprs.py +14 -14
  80. pygeodesy/trf.py +14 -12
  81. pygeodesy/triaxials.py +29 -26
  82. pygeodesy/units.py +5 -4
  83. pygeodesy/unitsBase.py +5 -4
  84. pygeodesy/ups.py +3 -3
  85. pygeodesy/utily.py +4 -4
  86. pygeodesy/utmups.py +4 -4
  87. pygeodesy/utmupsBase.py +88 -18
  88. pygeodesy/vector2d.py +18 -11
  89. pygeodesy/vector3d.py +7 -6
  90. pygeodesy/webmercator.py +6 -5
  91. pygeodesy/wgrs.py +6 -5
  92. {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +35 -31
  93. pygeodesy-25.4.25.dist-info/RECORD +118 -0
  94. pygeodesy-25.1.9.dist-info/RECORD +0 -118
  95. {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
  96. {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  u'''A pure Python implementation of geodesy tools for various ellipsoidal and spherical earth
5
- models using precision trigonometric, vector-based, exact, elliptic, iterative and approximate
5
+ models using precision exact, elliptic, trigonometric, vector-based, iterative and approximate
6
6
  methods for geodetic (lat-/longitude), geocentric (U{ECEF<https://WikiPedia.org/wiki/ECEF>}
7
7
  cartesian) and certain U{triaxial ellipsoidal<https://GeographicLib.SourceForge.io/1.44/triaxial.html>}
8
8
  coordinates.
@@ -17,14 +17,7 @@ and a geocentric B{C{Cartesian}} class with methods and functions to compute dis
17
17
  forward and reverse azimuth, initial and final bearing, intermediate and nearest points, intersections of geodesic,
18
18
  great circle and rhumb lines, circle intersections and secants, U{3-point resections
19
19
  <https://WikiPedia.org/wiki/Position_resection_and_intersection>}, triangulation, trilateration (by intersection,
20
- by overlap and in 3-D), conversions and unrolling, among other things. For more information and further details see
21
- the U{documentation<https://mrJean1.GitHub.io/PyGeodesy>}, the descriptions of U{Latitude/Longitude
22
- <https://www.Movable-Type.co.UK/scripts/latlong.html>}, U{Vincenty
23
- <https://www.Movable-Type.co.UK/scripts/latlong-vincenty.html>} and U{Vector-based
24
- <https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>} geodesy, the original U{JavaScript source
25
- <https://GitHub.com/ChrisVeness/geodesy>} or U{docs<https://www.Movable-Type.co.UK/scripts/geodesy/docs>}
26
- and I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>} and C++ U{GeographicLib
27
- <https://GeographicLib.SourceForge.io/C++/doc/index.html>}.
20
+ by overlap and in 3-D), conversions and unrolling, among other things.
28
21
 
29
22
  Also included are modules for conversions to and from U{Cassini-Soldner
30
23
  <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1CassiniSoldner.html>},
@@ -55,16 +48,25 @@ points (or a U{NumPy array<https://docs.SciPy.org/doc/numpy/reference/generated/
55
48
  including implementations of the U{Ramer-Douglas-Peucker<https://WikiPedia.org/wiki/
56
49
  Ramer-Douglas-Peucker_algorithm>}, the U{Visvalingam-Whyatt<https://hydra.Hull.ac.UK/
57
50
  resources/hull:8338>} and the U{Reumann-Witkam<https://psimpl.SourceForge.net/reumann-witkam.html>}
58
- algorithms and modified versions of the former. Other classes provide I{boolean} operations between
59
- (composite) polygons or U{interpolate <https://docs.SciPy.org/doc/scipy/reference/interpolate.html>}
60
- the L{height<pygeodesy.heights>} of C{LatLon} points and L{Geoid<pygeodesy.geoids>} models, compute
61
- various U{Fréchet<https://WikiPedia.org/wiki/Frechet_distance>} or U{Hausdorff<https://WikiPedia.org/
62
- wiki/Hausdorff_distance>} distances.
51
+ algorithms and modified versions of the former.
52
+
53
+ Plus modules and classes to U{interpolate<https://docs.SciPy.org/doc/scipy/reference/interpolate.html>} the
54
+ L{height<pygeodesy.heights>} of C{LatLon} points and L{Geoid<pygeodesy.geoids>} models, compute various U{Fréchet
55
+ <https://WikiPedia.org/wiki/Frechet_distance>} or U{Hausdorff<https://WikiPedia.org/wiki/Hausdorff_distance>}
56
+ distances or perform I{boolean} operations between (composite) polygons.
57
+
58
+ For further details see the U{documentation<https://mrJean1.GitHub.io/PyGeodesy>}, the descriptions of
59
+ U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}, U{Vincenty
60
+ <https://www.Movable-Type.co.UK/scripts/latlong-vincenty.html>} and U{Vector-based
61
+ <https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>} geodesy, the original U{JavaScript source
62
+ <https://GitHub.com/ChrisVeness/geodesy>} or U{docs<https://www.Movable-Type.co.UK/scripts/geodesy/docs>}
63
+ and I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>} and C++ U{GeographicLib
64
+ <https://GeographicLib.SourceForge.io/C++/doc/index.html>}.
63
65
 
64
66
  Installation
65
67
  ============
66
68
 
67
- To install PyGeodesy, type C{python[3] -m pip install pygeodesy} or C{python[3] -m easy_install
69
+ To install C{pygeodesy}, type C{python[3] -m pip install pygeodesy} or C{python[3] -m easy_install
68
70
  pygeodesy} in a terminal or command window.
69
71
 
70
72
  If the wheel C{pygeodesy-yy.m.d-py2.py3-none-any.whl} is missing in U{PyPI Download files<https://
@@ -76,22 +78,23 @@ Alternatively, download C{pygeodesy-yy.m.d.tar.gz} from U{PyPI<https://PyPI.org/
76
78
  or U{GitHub<https://GitHub.com/mrJean1/PyGeodesy>}, C{unzip} the downloaded file, C{cd} to
77
79
  directory C{pygeodesy-yy.m.d} and type C{python[3] setup.py install}.
78
80
 
79
- To run all PyGeodesy tests, type C{python[3] test/run.py} or type C{python[3] test/unitTestSuite.py}
81
+ To run all C{pygeodesy} tests, type C{python[3] test/run.py} or type C{python[3] test/unitTestSuite.py}
80
82
  before or after installation.
81
83
 
82
84
  Dependencies
83
85
  ============
84
86
 
85
87
  Installation of I{Karney}'s Python package U{geographiclib<https://PyPI.org/project/geographiclib>}
86
- is optional, but required to use modules L{ellipsoidalKarney} and L{css}, L{azimuthal} classes
87
- L{EquidistantKarney} and L{GnomonicKarney} and the L{HeightIDWkarney} interpolator.
88
+ is optional, but required for module L{ellipsoidalKarney}, L{azimuthal} classes L{EquidistantKarney}
89
+ and L{GnomonicKarney} and the L{HeightIDWkarney} interpolator.
88
90
 
89
91
  Both U{numpy<https://PyPI.org/project/numpy>} and U{scipy<https://PyPI.org/project/scipy>} must be
90
92
  installed for most L{Geoid...<pygeodesy.geoids>} and L{Height...<pygeodesy.heights>} interpolators,
91
93
  except L{GeoidKarney} and the L{HeightIDW...<pygeodesy.heights>} ones.
92
94
 
93
- Functions and C{LatLon} methods L{circin6}, L{circum3}, L{circum4_}, L{soddy4}, L{trilaterate3d2} do and
94
- C{trilaterate5} and modules L{auxilats} and L{rhumb} may require U{numpy<https://PyPI.org/project/numpy>}.
95
+ Functions and C{LatLon} methods L{circin6}, L{circum3}, L{circum4_} and L{soddy4} and functions
96
+ L{triaxum5} and L{trilaterate3d2} require U{numpy<https://PyPI.org/project/numpy>} to be installed,
97
+ modules L{auxilats} and L{rhumb} may need U{numpy<https://PyPI.org/project/numpy>}.
95
98
 
96
99
  Modules L{ellipsoidalGeodSolve} and L{geodsolve} and L{azimuthal} classes L{EquidistantGeodSolve}
97
100
  and L{GnomonicGeodSolve} depend on I{Karney}'s C++ utility U{GeodSolve
@@ -113,7 +116,7 @@ env variable C{PYGEODESY_RHUMBSOLVE} or with property L{Ellipsoid.rhumbsolve}.
113
116
  Documentation
114
117
  =============
115
118
 
116
- In addition to the C{pygeodesy} package, the U{PyGeodesy<https://PyPI.org/project/pygeodesy>}
119
+ In addition to the C{pygeodesy} package, the U{pygeodesy<https://PyPI.org/project/pygeodesy>}
117
120
  U{distribution files<https://GitHub.com/mrJean1/PyGeodesy/tree/master/dist>} contain the tests,
118
121
  the test results (on macOS only) and the complete U{documentation<https://mrJean1.GitHub.io/PyGeodesy>}
119
122
  (generated by U{Epydoc<https://PyPI.org/project/epydoc>} using command line:
@@ -122,7 +125,7 @@ C{epydoc --html --no-private --no-source --name=pygeodesy --url=... -v pygeodesy
122
125
  Tests
123
126
  =====
124
127
 
125
- The tests ran with Python 3.13.1 (with U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0),
128
+ The tests ran with Python 3.13.3 (with U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0),
126
129
  Python 3.12.7 (with U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0,
127
130
  U{numpy<https://PyPI.org/project/numpy>} 2.1.0, U{scipy<https://PyPI.org/project/scipy>} 1.14.1,
128
131
  U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
@@ -139,20 +142,21 @@ U{numpy<https://PyPI.org/project/numpy>} 1.16.6, U{scipy<https://PyPI.org/projec
139
142
  U{GeoConvert<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
140
143
  U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3,
141
144
  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 macOS 14.6.1 Sonoma.
145
+ U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3), all in 64-bit on
146
+ macOS 15.4.1 Sequoia.
143
147
 
144
148
  All tests ran with and without C{lazy import} for Python 3 and with command line option C{-W default} and
145
149
  env variable C{PYGEODESY_WARNINGS=on} for all Python versions. The results of those tests are included in
146
150
  the distribution files.
147
151
 
148
152
  Test coverage has been measured with U{coverage<https://PyPI.org/project/coverage>} 7.6.1 using Python
149
- 3.13.1, 3.12.7, 3.11.5 and 3.10.8. The complete coverage report in HTML and a PDF summary are included in
153
+ 3.13.3, 3.12.7, 3.11.5 and 3.10.8. The complete coverage report in HTML and a PDF summary are included in
150
154
  the distribution files.
151
155
 
152
- Python 3.13.1, 3.12.7, 3.11.5 and 3.10.8 run on Apple M1 Silicon (C{arm64}), I{natively}. Python 2.7.18 runs
156
+ Python 3.13.3, 3.12.7, 3.11.5 and 3.10.8 run on Apple M4 Si (C{arm64}), I{natively}. Python 2.7.18 runs
153
157
  on Intel (C{x86_64}) or Intel I{emulation} ("C{arm64_x86_64}", see function L{machine<pygeodesy.machine>}).
154
158
 
155
- The tests also ran with Python 3.13.1 (and U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on
159
+ The tests also ran with Python 3.13.3 (and U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on
156
160
  U{Debian 12<https://Cirrus-CI.com/github/mrJean1/PyGeodesy/master>} in 64-bit only, with Python 3.12.5 (and
157
161
  U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on U{Windows 2019Server
158
162
  <https://CI.AppVeyor.com/project/mrJean1/pygeodesy>} in 64-bit only and with Python 2.7.18 (and U{geographiclib
@@ -162,7 +166,7 @@ in 64- and 32-bit.
162
166
  A single-File and single-Directory application with C{pygeodesy} has been bundled using U{PyInstaller
163
167
  <https://PyPI.org/project/pyinstaller>} 3.4 and 64-bit Python 3.7.3 on macOS 10.13.6 High Sierra.
164
168
 
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,
169
+ Previously, the tests were run with Python 3.13.0-2, 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
170
  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
171
  2.7.13) (and U{geographiclib <https://PyPI.org/project/geographiclib>} 1.52, U{numpy<https://PyPI.org/project/numpy>}
168
172
  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 +175,7 @@ U{PyPy<https://PyPy.org>} 7.3.12 (Python 3.10.12), 7.3.1 (Python 3.6.9) and U{Py
171
175
  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
176
  <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
177
  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-5 Sonoma, 13.0-5.2 Ventura, 12.1-6 Monterey, 11.0-5.2-6.1
178
+ <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
179
  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
180
  10.11 El Capitan and/or MacOS X 10.10 Yosemite, with U{Pythonista<https://OMZ-Software.com/pythonista>}3.2 (with
177
181
  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 +190,7 @@ All Python source code has been statically U{checked<https://GitHub.com/ActiveSt
186
190
  Python/546532_PyChecker_postprocessor>} with U{PyChecker<https://PyPI.org/project/pychecker>}, U{PyFlakes
187
191
  <https://PyPI.org/project/pyflakes>}, U{PyCodeStyle<https://PyPI.org/project/pycodestyle>} (formerly Pep8) and
188
192
  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 14.6.1 Sonoma.
193
+ using Python 3.11.5, both in 64-bit on macOS 15.4.1 Sequoia.
190
194
 
191
195
  For a summary of all I{Karney}-based functionality in C{pygeodesy}, see module U{karney
192
196
  <https://mrJean1.GitHub.io/PyGeodesy/docs/pygeodesy.karney-module.html>}.
@@ -582,7 +586,7 @@ if _init__all__ and not _lazy_import2: # import and set __all__
582
586
  raise ImportError('missing %s%s: %s' % (_attribute_, s, t))
583
587
  ns.extend(attrs)
584
588
  # XXX if ps: # check that mod is a _pygeodesy_ module
585
- # XXX m = globalocals[mod] # assert(_DUNDER_nameof(m) == mod)
589
+ # XXX m = globalocals[mod] # assert(typename(m) == mod)
586
590
  # XXX f = getattr(m, _dunder_file_, _NN)
587
591
  # XXX d = _os_path.dirname(_os_path.abspath(f)) if f else pygeodesy_abspath
588
592
  # XXX p = getattr(m, _dunder_package_, _NN) or _pygeodesy_
@@ -598,7 +602,7 @@ else:
598
602
 
599
603
  from pygeodesy.internals import _version2, _DOT_ # PYCHOK import
600
604
  # from pygeodesy.interns import _DOT_ # from .internals
601
- __version__ = '25.01.09'
605
+ __version__ = '25.04.25'
602
606
  # see setup.py for similar logic
603
607
  version = _DOT_(*_version2(__version__, n=3))
604
608
 
pygeodesy/__main__.py CHANGED
@@ -5,7 +5,7 @@ u'''Print L{pygeodesy} version, etc. using C{python -m pygeodesy}.
5
5
  '''
6
6
 
7
7
  __all__ = ()
8
- __version__ = '24.10.14'
8
+ __version__ = '25.04.12'
9
9
 
10
10
  from os.path import basename, dirname
11
11
 
@@ -16,7 +16,7 @@ def _main(): # PYCHOK no cover
16
16
  from pygeodesy import constants, _isfrozen, pygeodesy_abspath, version
17
17
  from pygeodesy.basics import _xcoverage,_xgeographiclib, _xnumpy, _xscipy
18
18
  from pygeodesy.internals import _name_version, printf, _usage, _versions
19
- from pygeodesy.interns import NN, _COMMASPACE_, _DEPRECATED_, _DOT_, _DUNDER_all_, \
19
+ from pygeodesy.interns import NN, _COMMASPACE_, _DALL_, _DEPRECATED_, _DOT_, \
20
20
  _EQUAL_, _pygeodesy_abspath_, _version_
21
21
  from pygeodesy.lazily import _all_deprecates, _all_imports, isLazy
22
22
 
@@ -28,7 +28,7 @@ def _main(): # PYCHOK no cover
28
28
  ('isLazy', isLazy),
29
29
  ('_isfrozen', _isfrozen),
30
30
  ('_floats', len(constants._floats)),
31
- (_DUNDER_all_, len(_all_imports())),
31
+ (_DALL_, len(_all_imports())),
32
32
  (_DEPRECATED_, len(_all_deprecates()))))
33
33
 
34
34
  def _nv(_xpkg, p):
pygeodesy/albers.py CHANGED
@@ -15,7 +15,7 @@ and the Albers Conical Equal-Area examples on pp 291-294.
15
15
  # make sure int/int division yields float quotient, see .basics
16
16
  from __future__ import division as _; del _ # PYCHOK semicolon
17
17
 
18
- from pygeodesy.basics import neg, neg_
18
+ from pygeodesy.basics import _isin, neg, neg_
19
19
  from pygeodesy.constants import EPS0, EPS02, _EPSqrt as _TOL, \
20
20
  _0_0, _0_5, _1_0, _N_1_0, _2_0, \
21
21
  _N_2_0, _4_0, _6_0, _90_0, _N_90_0
@@ -38,10 +38,10 @@ from pygeodesy.utily import atan1, atan1d, atan2, degrees360, sincos2, \
38
38
  from math import atanh, degrees, fabs, radians, sqrt
39
39
 
40
40
  __all__ = _ALL_LAZY.albers
41
- __version__ = '24.11.24'
41
+ __version__ = '25.04.14'
42
42
 
43
43
  _k1_ = 'k1'
44
- _NUMIT = 8 # XXX 4?
44
+ _NUMIT = 9 # XXX 4?
45
45
  _NUMIT0 = 41 # XXX 21?
46
46
  _TERMS = 31 # XXX 16?
47
47
  _TOL0 = sqrt3(_TOL)
@@ -115,7 +115,7 @@ class _AlbersBase(_NamedBase):
115
115
  '''(INTERNAL) New C{AlbersEqualArea...} instance.
116
116
  '''
117
117
  qZ = self._qZ
118
- if datum not in (None, self._datum):
118
+ if not _isin(datum, None, self._datum):
119
119
  self._datum = _ellipsoidal_datum(datum, **name)
120
120
  qZ = _qZx(self)
121
121
  elif qZ is None:
@@ -143,10 +143,8 @@ class _AlbersBase(_NamedBase):
143
143
  ca2, ta2 = _ct2(sa2, ca2)
144
144
 
145
145
  par1 = fabs(ta1 - ta2) < EPS02 # ta1 == ta2
146
- if par1 or polar:
147
- ta0, C = ta2, _1_0
148
- else:
149
- ta0, C = self._ta0C2(ca1, sa1, ta1, ca2, sa2, ta2)
146
+ ta0, C = (ta2, _1_0) if par1 or polar else \
147
+ self._ta0C2(ca1, sa1, ta1, ca2, sa2, ta2)
150
148
 
151
149
  self._lat0 = _Lat(lat0=self._sign * atan1d(ta0))
152
150
  self._m02 = m02 = _1_x21(E.f1 * ta0)
@@ -155,8 +153,8 @@ class _AlbersBase(_NamedBase):
155
153
  self._polar = True
156
154
  # self._nrho0 = self._m0 = _0_0
157
155
  else: # m0 = nrho0 / E.a
158
- self._m0 = sqrt(m02)
159
- self._nrho0 = self._m0 * E.a
156
+ self._m0 = t = sqrt(m02)
157
+ self._nrho0 = t * E.a
160
158
  t = self._txi0 = self._txif(ta0)
161
159
  h = hypot1(t)
162
160
  s = self._sxi0 = t / h
@@ -476,12 +474,13 @@ class _AlbersBase(_NamedBase):
476
474
  axi, bxi, sxi = self._a_b_sxi3((ca1, sa1, ta1, scb12),
477
475
  (ca2, sa2, ta2, scb22))
478
476
 
479
- dsxi = ((esa12 / esa1_2) + _DatanheE(sa2, sa1, E)) * dsn_2 / self._qx
480
- C = _Fsum1f_(sxi * dtb12 / dsxi, scb22, scb12).fover(scb22 * scb12 * _2_0)
477
+ dsxi = ((esa12 / esa1_2) + _DatanheE(sa2, sa1, E)) * dsn_2 / self._qx
478
+ C = _Fsum1f_(sxi * dtb12 / dsxi, scb22, scb12).fover(scb22 * scb12 * _2_0)
481
479
 
482
480
  S = _Fsum1f_(sa1, sa2, sa12)
483
481
  axi *= (S * e2 + _1).fover(S + _1, raiser=False)
484
- bxi *= _Fsum1f_(sa1, sa2, esa12).fover(esa1_2) * e2 + _D2atanheE(sa1, sa2, E) * E.e21
482
+ bxi *= _Fsum1f_( sa1, sa2, esa12).fover(esa1_2) * e2 + \
483
+ _D2atanheE(sa1, sa2, E) * E.e21
485
484
  s1_qZ = (axi * self._qZ - bxi) * dsn_2 / dtb12
486
485
  ta0 = self._ta0(s1_qZ, (ta1 + ta2) * _0_5, E)
487
486
  return ta0, C
@@ -489,23 +488,19 @@ class _AlbersBase(_NamedBase):
489
488
  def _tanf(self, txi): # in .Ellipsoid.auxAuthalic
490
489
  '''(INTERNAL) Function M{tan-phi from tan-xi}.
491
490
  '''
492
- tol = _tol(_TOL, txi)
493
- e2 = self.ellipsoid.e2
494
- qx = self._qx
495
-
496
- ta = txi
497
- _Ta2 = Fsum(ta).fsum2f_
498
- _txif = self._txif
499
- _1 = _1_0
491
+ e2 = self.ellipsoid.e2
492
+ ta = txi
493
+ tol = _tol(_TOL, ta)
494
+ _Ta2 = Fsum(ta).fsum2f_
500
495
  for self._iteration in range(1, _NUMIT): # max 2, mean 1.99
501
496
  # dtxi / dta = (scxi / sca)^3 * 2 * (1 - e^2)
502
497
  # / (qZ * (1 - e^2 * sa^2)^2)
503
- ta2 = ta**2
504
- sca2 = _1 + ta2
505
- txia = _txif(ta)
506
- s3qx = sqrt3(sca2 / (txia**2 + _1)) * qx # * _1_x21(txia)
507
- eta2 = (_1 - e2 * ta2 / sca2)**2
508
- ta, d = _Ta2((txi - txia) * s3qx * eta2)
498
+ ta2 = ta**2
499
+ sca2 = _1_0 + ta2
500
+ txia = self._txif(ta)
501
+ s3 = sqrt3(sca2 / (txia**2 + _1_0)) # * _1_x21(txia)
502
+ s3 *= (e2 * ta2 / sca2 - _1_0)**2 * self._qx
503
+ ta, d = _Ta2((txi - txia) * s3)
509
504
  if fabs(d) < tol:
510
505
  return ta
511
506
  raise AlbersError(Fmt.no_convergence(d, tol), txt=repr(self))
@@ -546,20 +541,18 @@ class _AlbersBase(_NamedBase):
546
541
  '''(INTERNAL) Function M{tan-xi from tan-phi}.
547
542
  '''
548
543
  E = self.ellipsoid
549
- _1 = _1_0
550
-
551
544
  ca2 = _1_x21(ta)
552
545
  sa = sqrt(ca2) * fabs(ta) # enforce odd parity
553
- sa1 = _1 + sa
546
+ sa1 = _1_0 + sa
554
547
 
555
548
  es1 = sa * E.e2
556
- es1m1 = sa1 * (_1 - es1)
557
- es1p1 = sa1 / (_1 + es1)
558
- es2m1 = _1 - sa * es1
549
+ es1m1 = sa1 * (_1_0 - es1)
550
+ es1p1 = sa1 / (_1_0 + es1)
551
+ es2m1 = _1_0 - sa * es1
559
552
  es2m1a = es2m1 * E.e21 # e2m
560
- s = sqrt((ca2 / (es1p1 * es2m1a) + _atanheE(ca2 / es1m1, E))
561
- * (es1m1 / es2m1a + _atanheE(es1p1, E)))
562
- t = _Fsum1f_(sa / es2m1, _atanheE(sa, E)).fover(s)
553
+ s = ca2 / (es1p1 * es2m1a) + _atanheE(ca2 / es1m1, E)
554
+ s *= es1m1 / es2m1a + _atanheE( es1p1, E)
555
+ t = _Fsum1f_( sa / es2m1, _atanheE( sa, E)).fover(sqrt(s))
563
556
  return neg(t) if ta < 0 else t
564
557
 
565
558
 
@@ -6,13 +6,13 @@ u'''Coefficients for C{_AUXLATITUDE_ORDER} 4 from I{Karney}'s C++ class U{AuxLat
6
6
  transcoded to a Python C{_Rdict[auxout][auxin]} of C{_Rtuple}s.
7
7
 
8
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>.
9
+ MIT/X11 License. For more information, see <https://GeographicLib.SourceForge.io>.
10
10
  '''
11
11
  from pygeodesy.auxilats.auxily import Aux
12
12
  from pygeodesy.auxilats._CX_Rs import _Rcoeffs, _Rdict, _Rtuple
13
13
 
14
14
  __all__ = ()
15
- __version__ = '24.09.03'
15
+ __version__ = '25.04.09'
16
16
 
17
17
  _coeffs_4 = _Rcoeffs(4, { # GEOGRAPHICLIB_AUXLATITUDE_ORDER == 4
18
18
  Aux.PHI: _Rdict(38,
@@ -6,13 +6,13 @@ u'''Coefficients for C{_AUXLATITUDE_ORDER} 6 from I{Karney}'s C++ class U{AuxLat
6
6
  transcoded to a Python C{_Rdict[auxout][auxin]} of C{_Rtuple}s.
7
7
 
8
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>.
9
+ MIT/X11 License. For more information, see <https://GeographicLib.SourceForge.io>.
10
10
  '''
11
11
  from pygeodesy.auxilats.auxily import Aux
12
12
  from pygeodesy.auxilats._CX_Rs import _Rcoeffs, _Rdict, _Rtuple
13
13
 
14
14
  __all__ = ()
15
- __version__ = '24.09.02'
15
+ __version__ = '25.04.09'
16
16
 
17
17
  _coeffs_6 = _Rcoeffs(6, { # GEOGRAPHICLIB_AUXLATITUDE_ORDER == 6
18
18
  Aux.PHI: _Rdict(78,
@@ -6,13 +6,13 @@ u'''Coefficients for C{_AUXLATITUDE_ORDER} 8 from I{Karney}'s C++ class U{AuxLat
6
6
  transcoded to a Python C{_Rdict[auxout][auxin]} of C{_Rtuple}s.
7
7
 
8
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>.
9
+ MIT/X11 License. For more information, see <https://GeographicLib.SourceForge.io>.
10
10
  '''
11
11
  from pygeodesy.auxilats.auxily import Aux
12
12
  from pygeodesy.auxilats._CX_Rs import _Rcoeffs, _Rdict, _Rtuple
13
13
 
14
14
  __all__ = ()
15
- __version__ = '24.09.03'
15
+ __version__ = '25.04.09'
16
16
 
17
17
  _coeffs_8 = _Rcoeffs(8, { # GEOGRAPHICLIB_AUXLATITUDE_ORDER == 8
18
18
  Aux.PHI: _Rdict(132,
@@ -6,13 +6,15 @@ Python versions of coefficients from I{Karney}'s C++ class U{AuxLatitude
6
6
  <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1AuxLatitude.html>}.
7
7
 
8
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>.
9
+ MIT/X11 License. For more information, see <https://GeographicLib.SourceForge.io>.
10
10
  '''
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.constants import _floats
14
+ # from pygeodesy.basics import _splituple # _MODS
15
+ from pygeodesy.constants import _floats as _constants_floats
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__ = '24.09.04'
25
+ __version__ = '25.04.11'
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 _RdictError(coeffs=type(coeffs))
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 _RdictError(k=k, d=type(d))
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 _RdictError(ALorder=ALorder, cause=x)
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 += len(t)
57
- u += sum(1 for f in t if f in _floats)
60
+ n += len(t)
61
+ u += sum(1 for f in t if f in _constants_floats)
58
62
  return b, n, (n - u), z
59
63
 
60
64
  def items(self): # string-ify keys # PYCHOK no cover
@@ -70,68 +74,79 @@ class _Rcoeffs(ADict):
70
74
 
71
75
  def _validate(self, aL, lenAux):
72
76
  # in .auxily.Aux._CXcoeffs(al, Aux.len(aL))
73
- a, n = self.ALorder, self.n # PYCHOK Adict!
77
+ a, n = self.ALorder, self.n # PYCHOK ADict!
74
78
  # for R in self._Rtuples():
75
79
  # assert isinstance(R, _Rtuple)
76
80
  if aL != a or lenAux != n:
77
- raise _RdictError(aL=aL, ALorder=a, lenAux=lenAux, n=n)
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 r in Rtuples)
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 _RdictError(Rtuples=MISSING)
94
+ raise _RsError(Rtuples=MISSING)
91
95
 
92
96
  for R in Rtuples:
93
97
  if not isinstance(R, _Rtuple):
94
- raise _RdictError(R, R=type(R))
98
+ raise _RsError(R, R=type(R))
95
99
  k, n, _ = R.k_n_rs
96
100
  if k in self:
97
- raise _RdictError(_duplicate_, k=k)
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 _RdictError(n=n, nt=nt)
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 = _floats.get
110
- for r in NN(*rs.split()).split(_COMMA_):
113
+ _get = _constants_floats.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 _RdictError(rs, f=f, p=p, q=q, r=r)
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 _RdictError(rs, r=r)
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}
122
126
  k, n, rs = Rtuple.k_n_rs
123
127
  t = tuple(f for m in map(self._floats, rs)
124
- for f in m) # ... yield f
128
+ for f in m) # == yield f
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 _RdictError(*rs, len=len(t), n=n)
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 _RdictError(_AssertionError):
134
- '''(INTERNAL) For C{_Rdict} issues.
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 _RdictError(rs=MISSING)
179
+ raise _RsError(rs=MISSING)
161
180
  for t in rs:
162
181
  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))
182
+ raise _RsError(rs=type(t))
166
183
  self.k_n_rs = k, n, rs
167
184
  except Exception as x:
168
- raise _RdictError(*rs, k=k, n=n, cause=x)
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): # PYCHOK 3 args
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, 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]
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
- self[:] = t # MUST copy into self!
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 _RdictError(k=k, n=n, rs=rs, cause=x)
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 _RdictError(append=arg)
216
+ raise _RsError(append=arg)
198
217
 
199
218
  def extend(self, arg):
200
- raise _RdictError(extend=arg)
219
+ raise _RsError(extend=arg)
201
220
 
202
221
  # **) MIT License
203
222
  #
@@ -14,8 +14,8 @@ License. For more information, see the U{GeographicLib<https://GeographicLib.So
14
14
  @note: Class L{AuxDST} requires U{numpy<https://PyPI.org/project/numpy>} to be installed, version 1.16
15
15
  or newer.
16
16
 
17
- @see: U{Auxiliary latitudes<https:#GeographicLib.SourceForge.io/C++/doc/auxlat.html>} and
18
- U{On auxiliary latitudes<https:#ArXiv.org/abs/2212.05818>}.
17
+ @see: U{Auxiliary latitudes<https://GeographicLib.SourceForge.io/C++/doc/auxlat.html>} and
18
+ U{On auxiliary latitudes<https://ArXiv.org/abs/2212.05818>}.
19
19
  '''
20
20
 
21
21
  from pygeodesy.auxilats.auxAngle import AuxAngle, AuxBeta, AuxChi, AuxMu, \
@@ -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.09.04'
32
+ __version__ = '25.04.14'
33
33
 
34
34
  # **) MIT License
35
35
  #