pygeodesy 25.4.8__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 +30 -27
  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 +9 -9
  8. pygeodesy/auxilats/__init__.py +3 -3
  9. pygeodesy/auxilats/__main__.py +8 -6
  10. pygeodesy/auxilats/auxAngle.py +2 -2
  11. pygeodesy/auxilats/auxLat.py +5 -5
  12. pygeodesy/auxilats/auxily.py +5 -3
  13. pygeodesy/azimuthal.py +7 -6
  14. pygeodesy/basics.py +31 -17
  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 +7 -7
  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 +78 -77
  40. pygeodesy/gars.py +4 -3
  41. pygeodesy/geodesici.py +15 -14
  42. pygeodesy/geodesicw.py +34 -32
  43. pygeodesy/geodesicx/__init__.py +1 -1
  44. pygeodesy/geodesicx/__main__.py +11 -9
  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 +5 -5
  50. pygeodesy/geoids.py +34 -31
  51. pygeodesy/hausdorff.py +17 -13
  52. pygeodesy/heights.py +2 -4
  53. pygeodesy/internals.py +28 -44
  54. pygeodesy/interns.py +10 -7
  55. pygeodesy/iters.py +8 -8
  56. pygeodesy/karney.py +68 -62
  57. pygeodesy/ktm.py +5 -5
  58. pygeodesy/latlonBase.py +14 -18
  59. pygeodesy/lazily.py +65 -63
  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 +7 -7
  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.4.8.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +27 -23
  93. pygeodesy-25.4.25.dist-info/RECORD +118 -0
  94. pygeodesy-25.4.8.dist-info/RECORD +0 -118
  95. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
  96. {pygeodesy-25.4.8.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,11 +48,20 @@ 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
  ============
@@ -83,15 +85,16 @@ 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
@@ -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.2 (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,
@@ -140,20 +143,20 @@ 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
145
  U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/utilities.html>} 2.3), all in 64-bit on
143
- macOS 15.4 Sequoia.
146
+ macOS 15.4.1 Sequoia.
144
147
 
145
148
  All tests ran with and without C{lazy import} for Python 3 and with command line option C{-W default} and
146
149
  env variable C{PYGEODESY_WARNINGS=on} for all Python versions. The results of those tests are included in
147
150
  the distribution files.
148
151
 
149
152
  Test coverage has been measured with U{coverage<https://PyPI.org/project/coverage>} 7.6.1 using Python
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
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
151
154
  the distribution files.
152
155
 
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
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
154
157
  on Intel (C{x86_64}) or Intel I{emulation} ("C{arm64_x86_64}", see function L{machine<pygeodesy.machine>}).
155
158
 
156
- The tests also ran with Python 3.13.2 (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
157
160
  U{Debian 12<https://Cirrus-CI.com/github/mrJean1/PyGeodesy/master>} in 64-bit only, with Python 3.12.5 (and
158
161
  U{geographiclib<https://PyPI.org/project/geographiclib>} 2.0) on U{Windows 2019Server
159
162
  <https://CI.AppVeyor.com/project/mrJean1/pygeodesy>} in 64-bit only and with Python 2.7.18 (and U{geographiclib
@@ -163,7 +166,7 @@ in 64- and 32-bit.
163
166
  A single-File and single-Directory application with C{pygeodesy} has been bundled using U{PyInstaller
164
167
  <https://PyPI.org/project/pyinstaller>} 3.4 and 64-bit Python 3.7.3 on macOS 10.13.6 High Sierra.
165
168
 
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,
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,
167
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
168
171
  2.7.13) (and U{geographiclib <https://PyPI.org/project/geographiclib>} 1.52, U{numpy<https://PyPI.org/project/numpy>}
169
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,
@@ -187,7 +190,7 @@ All Python source code has been statically U{checked<https://GitHub.com/ActiveSt
187
190
  Python/546532_PyChecker_postprocessor>} with U{PyChecker<https://PyPI.org/project/pychecker>}, U{PyFlakes
188
191
  <https://PyPI.org/project/pyflakes>}, U{PyCodeStyle<https://PyPI.org/project/pycodestyle>} (formerly Pep8) and
189
192
  U{McCabe<https://PyPI.org/project/mccabe>} using Python 2.7.18 and with U{Flake8<https://PyPI.org/project/flake8>}
190
- using Python 3.11.5, both in 64-bit on macOS 15.4 Sequoia.
193
+ using Python 3.11.5, both in 64-bit on macOS 15.4.1 Sequoia.
191
194
 
192
195
  For a summary of all I{Karney}-based functionality in C{pygeodesy}, see module U{karney
193
196
  <https://mrJean1.GitHub.io/PyGeodesy/docs/pygeodesy.karney-module.html>}.
@@ -583,7 +586,7 @@ if _init__all__ and not _lazy_import2: # import and set __all__
583
586
  raise ImportError('missing %s%s: %s' % (_attribute_, s, t))
584
587
  ns.extend(attrs)
585
588
  # XXX if ps: # check that mod is a _pygeodesy_ module
586
- # XXX m = globalocals[mod] # assert(_DUNDER_nameof(m) == mod)
589
+ # XXX m = globalocals[mod] # assert(typename(m) == mod)
587
590
  # XXX f = getattr(m, _dunder_file_, _NN)
588
591
  # XXX d = _os_path.dirname(_os_path.abspath(f)) if f else pygeodesy_abspath
589
592
  # XXX p = getattr(m, _dunder_package_, _NN) or _pygeodesy_
@@ -599,7 +602,7 @@ else:
599
602
 
600
603
  from pygeodesy.internals import _version2, _DOT_ # PYCHOK import
601
604
  # from pygeodesy.interns import _DOT_ # from .internals
602
- __version__ = '25.04.08'
605
+ __version__ = '25.04.25'
603
606
  # see setup.py for similar logic
604
607
  version = _DOT_(*_version2(__version__, n=3))
605
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,13 @@ 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
14
  # from pygeodesy.basics import _splituple # _MODS
15
- from pygeodesy.constants import _floats as _Cs
15
+ from pygeodesy.constants import _floats as _constants_floats
16
16
  from pygeodesy.errors import _AssertionError, _MODS
17
17
  # from pygeodesy.internals import _sizeof # _MODS
18
18
  from pygeodesy.interns import NN, MISSING, _COMMA_, _duplicate_, _NL_, \
@@ -22,7 +22,7 @@ from pygeodesy.named import ADict, Property_RO
22
22
  # from pygeodesy.props import Property_RO # from .named
23
23
 
24
24
  __all__ = ()
25
- __version__ = '25.04.08'
25
+ __version__ = '25.04.11'
26
26
 
27
27
 
28
28
  class _Rcoeffs(ADict):
@@ -58,7 +58,7 @@ class _Rcoeffs(ADict):
58
58
  z += _zB(t) # Float
59
59
  # assert R.Rdict is None
60
60
  n += len(t)
61
- u += sum(1 for f in t if f in _Cs)
61
+ u += sum(1 for f in t if f in _constants_floats)
62
62
  return b, n, (n - u), z
63
63
 
64
64
  def items(self): # string-ify keys # PYCHOK no cover
@@ -74,7 +74,7 @@ class _Rcoeffs(ADict):
74
74
 
75
75
  def _validate(self, aL, lenAux):
76
76
  # in .auxily.Aux._CXcoeffs(al, Aux.len(aL))
77
- a, n = self.ALorder, self.n # PYCHOK Adict!
77
+ a, n = self.ALorder, self.n # PYCHOK ADict!
78
78
  # for R in self._Rtuples():
79
79
  # assert isinstance(R, _Rtuple)
80
80
  if aL != a or lenAux != n:
@@ -110,7 +110,7 @@ class _Rdict(dict): # in ._CX_#, .auxLat, .rhumb.aux_
110
110
  def _p_q(p=NN, q=1, *x):
111
111
  return (NN if x else p), q
112
112
 
113
- _get = _Cs.get
113
+ _get = _constants_floats.get
114
114
  for r in _MODS.basics._splituple(rs):
115
115
  p, q = _p_q(*r.split(_SLASH_))
116
116
  if p:
@@ -125,7 +125,7 @@ class _Rdict(dict): # in ._CX_#, .auxLat, .rhumb.aux_
125
125
  # return a tuple of floats from an C{_Rtuple}
126
126
  k, n, rs = Rtuple.k_n_rs
127
127
  t = tuple(f for m in map(self._floats, rs)
128
- for f in m) # ... yield f
128
+ for f in m) # == yield f
129
129
  # @see: <https://StackOverflow.com/questions/10632839/>
130
130
  # and <https://realPython.com/python-flatten-list/>
131
131
  if len(t) != n:
@@ -188,8 +188,8 @@ class _Rtuple(list): # MUST be list, NOT tuple!
188
188
  return self._tuple[i]
189
189
 
190
190
  if _MODS.sys_version_info2 < (3, 0):
191
- def __getslice__(self, i, j):
192
- return self._tuple[slice(i, j)]
191
+ def __getslice__(self, *i_j): # PYCHOK 3 args
192
+ return self._tuple[slice(*i_j)]
193
193
 
194
194
  def __iter__(self):
195
195
  return iter(self._tuple)
@@ -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__ = '25.01.15'
32
+ __version__ = '25.04.14'
33
33
 
34
34
  # **) MIT License
35
35
  #
@@ -5,23 +5,22 @@ u'''Print L{auxilats} version, etc. using C{python -m pygeodesy.auxilats}.
5
5
  '''
6
6
 
7
7
  __all__ = ()
8
- __version__ = '25.04.04'
8
+ __version__ = '25.04.14'
9
9
 
10
10
 
11
11
  def _main(**ALorder): # PYCHOK no cover
12
12
 
13
13
  try:
14
- from pygeodesy import auxilats
14
+ from pygeodesy import ADict, auxilats
15
15
  from pygeodesy.internals import _fper, _name_version, \
16
16
  printf, _versions
17
- from pygeodesy.interns import _COMMASPACE_, _EQUAL_
17
+ from pygeodesy.interns import _COMMASPACE_
18
18
 
19
19
  A = auxilats.AuxLat(**ALorder)
20
20
  Cx = A._CXcoeffs # PropertyRO: Adict of _Rdicts
21
21
  b, n, u, z = Cx.bnuz4()
22
- p = 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())
22
+ p = ADict(ALorder=A.ALorder, CXb=b, CXb_z=_fper(b, z),
23
+ CXn=n, CXu=u, CXu_n=_fper(u, n))._toL()
25
24
  try:
26
25
  import geographiclib
27
26
  p.append(_name_version(geographiclib))
@@ -39,6 +38,9 @@ def _main(**ALorder): # PYCHOK no cover
39
38
  from sys import argv # .internals._isPyChOK
40
39
  _main(ALorder=int(argv[1])) if len(argv) == 2 and argv[1].isdigit() else _main()
41
40
 
41
+ # % python3.13 -m pygeodesy.auxilats
42
+ # pygeodesy.auxilats 25.04.14: ALorder=6, CXb=11099, CXb_z=64.1%, CXn=522, CXu=448, CXu_n=85.8%, geographiclib 2.0 (pygeodesy 25.4.24 Python 3.13.3 64bit arm64 macOS 15.4)
43
+
42
44
  # % python3.12 -m pygeodesy.auxilats 8
43
45
  # pygeodesy.auxilats 24.09.04: ALorder=8, CXb=20310, CXb_z=71.5%, CXn=888, CXu=780, CXu_n=87.8%, geographiclib 2.0 (pygeodesy 24.9.9 Python 3.12.5 64bit arm64 macOS 14.6.1)
44
46
 
@@ -32,7 +32,7 @@ from pygeodesy.utily import atan2, atan2d, sincos2, sincos2d
32
32
  from math import asinh, copysign, degrees, fabs, radians, sinh
33
33
 
34
34
  __all__ = ()
35
- __version__ = '24.11.24'
35
+ __version__ = '25.04.14'
36
36
 
37
37
  _0_INF_NAN_NINF = (0, _0_0) + _INF_NAN_NINF
38
38
  _MAX_2 = MAX * _0_5 # PYCHOK used!
@@ -207,7 +207,7 @@ class AuxAngle(_Named):
207
207
  def _copy_2(self, which):
208
208
  '''(INTERNAL) Copy for I{dyadic} operators.
209
209
  '''
210
- return _Named.copy(self, deep=False, name=which.__name__)
210
+ return _Named.copy(self, deep=False, name__=which)
211
211
 
212
212
  def _copy_r2(self, other, which):
213
213
  '''(INTERNAL) Copy for I{reverse-dyadic} operators.
@@ -9,8 +9,8 @@ Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-2024) and lice
9
9
  under the MIT/X11 License. For more information, see the U{GeographicLib
10
10
  <https://GeographicLib.SourceForge.io>} documentation.
11
11
 
12
- @see: U{Auxiliary latitudes<https:#GeographicLib.SourceForge.io/C++/doc/auxlat.html>}
13
- U{On auxiliary latitudes<https:#ArXiv.org/abs/2212.05818>}.
12
+ @see: U{Auxiliary latitudes<https://GeographicLib.SourceForge.io/C++/doc/auxlat.html>}
13
+ U{On auxiliary latitudes<https://ArXiv.org/abs/2212.05818>}.
14
14
  '''
15
15
  # make sure int/int division yields float quotient, see .basics
16
16
  from __future__ import division as _; del _ # PYCHOK semicolon
@@ -19,7 +19,7 @@ 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
21
  from pygeodesy.auxilats._CX_Rs import _Rdict, _Rkey, _Rtuple
22
- from pygeodesy.basics import _reverange, _xinstanceof, _passarg
22
+ from pygeodesy.basics import _isin, _reverange, _xinstanceof, _passarg
23
23
  from pygeodesy.constants import INF, MAX_EXP, MIN_EXP, NAN, PI_2, PI_4, _EPSqrt, \
24
24
  _0_0, _0_0s, _0_1, _0_5, _1_0, _2_0, _3_0, _360_0, \
25
25
  _log2, _over, isfinite, isinf, isnan
@@ -48,7 +48,7 @@ except ImportError: # Python 3.11-
48
48
  return pow(_2_0, x)
49
49
 
50
50
  __all__ = ()
51
- __version__ = '25.01.15'
51
+ __version__ = '25.04.14'
52
52
 
53
53
  _TRIPS = 1024 # XXX 2 or 3?
54
54
 
@@ -90,7 +90,7 @@ class AuxLat(AuxAngle):
90
90
  else:
91
91
  name = NN
92
92
  try:
93
- if a_earth not in (_EWGS84, _WGS84):
93
+ if not _isin(a_earth, _EWGS84, _WGS84):
94
94
  n = _name__(name, name__=AuxLat)
95
95
  if b is f is None:
96
96
  E = _ellipsoidal_datum(a_earth, name=n).ellipsoid # XXX raiser=_earth_
@@ -16,10 +16,12 @@ from __future__ import division as _; del _ # PYCHOK semicolon
16
16
 
17
17
  # from pygeodesy import auxilats # _MODS
18
18
  from pygeodesy.auxilats._CX_Rs import _Rkey
19
+ from pygeodesy.basics import _isin, typename
19
20
  from pygeodesy.constants import INF, NAN, isinf, isnan, _0_0, _0_5, _1_0, \
20
21
  _copysign_1_0, _over, _1_over
21
22
  from pygeodesy.errors import AuxError
22
23
  from pygeodesy.fmath import hypot1 as _sc, hypot2_
24
+ # from pygeodesy.internals import typename # from .basics
23
25
  from pygeodesy.interns import NN, _DOT_, _UNDER_ # PYCHOK used!
24
26
  from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS # PYCHOK used!
25
27
  from pygeodesy.utily import atan1
@@ -27,7 +29,7 @@ from pygeodesy.utily import atan1
27
29
  from math import asinh, copysign
28
30
 
29
31
  __all__ = ()
30
- __version__ = '25.01.15'
32
+ __version__ = '25.04.14'
31
33
 
32
34
 
33
35
  class Aux(object):
@@ -58,7 +60,7 @@ class Aux(object):
58
60
  _coeffs = Aux._coeffs[aL]
59
61
  except KeyError:
60
62
  try: # from pygeodesy.auxilats._CX_x import _coeffs_x as _coeffs
61
- _CX_x = _DOT_(_MODS.auxilats.__name__, _UNDER_('_CX', aL))
63
+ _CX_x = _DOT_(typename(_MODS.auxilats), _UNDER_('_CX', aL))
62
64
  _coeffs = _MODS.getattr(_CX_x, _UNDER_('_coeffs', aL))
63
65
  except (AttributeError, ImportError, KeyError, TypeError) as x:
64
66
  raise AuxError(ALorder=aL, cause=x)
@@ -92,7 +94,7 @@ class Aux(object):
92
94
  return (auxout - auxin) if max(auxin, auxout) < Aux.MU else None
93
95
 
94
96
  def use_n2(self, aux):
95
- return aux not in (Aux.CHI, Aux.XI)
97
+ return not _isin(aux, Aux.CHI, Aux.XI)
96
98
 
97
99
  Aux = Aux() # PYCHOK singleton
98
100
 
pygeodesy/azimuthal.py CHANGED
@@ -42,19 +42,20 @@ altitude in Earth radii<https://WikiPedia.org/wiki/Azimuthal_equidistant_project
42
42
  # make sure int/int division yields float quotient, see .basics
43
43
  from __future__ import division as _; del _ # PYCHOK semicolon
44
44
 
45
- # from pygeodesy.basics import _xinstanceof # from .ellipsoidalBase
45
+ # from pygeodesy.basics import _isin, _xinstanceof # from .ellipsoidalBase
46
46
  from pygeodesy.constants import EPS, EPS0, EPS1, NAN, isnon0, _umod_360, \
47
47
  _EPStol, _0_0, _0_1, _0_5, _1_0, _N_1_0, _2_0
48
48
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB, \
49
- _xinstanceof
49
+ _isin, _xinstanceof
50
50
  from pygeodesy.datums import _spherical_datum, _WGS84
51
51
  from pygeodesy.errors import _ValueError, _xdatum, _xkwds
52
52
  from pygeodesy.fmath import euclid, fdot_, hypot as _hypot, Fsum
53
53
  # from pygeodesy.fsums import Fsum # from .fmath
54
54
  # from pygeodesy.formy import antipode # _MODS
55
+ # from pygeodesy.internals import typename # from .karney
55
56
  from pygeodesy.interns import _azimuth_, _datum_, _lat_, _lon_, _scale_, \
56
57
  _SPACE_, _x_, _y_
57
- from pygeodesy.karney import _norm180
58
+ from pygeodesy.karney import _norm180, typename
58
59
  from pygeodesy.latlonBase import _MODS, LatLonBase as _LLB
59
60
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _FOR_DOCS # ALL_MODS
60
61
  from pygeodesy.named import _name__, _name2__, _NamedBase, _NamedTuple, _Pass
@@ -70,7 +71,7 @@ from pygeodesy.utily import asin1, atan1, atan2, atan2b, atan2d, \
70
71
  from math import acos, degrees, fabs, sin, sqrt
71
72
 
72
73
  __all__ = _ALL_LAZY.azimuthal
73
- __version__ = '24.11.24'
74
+ __version__ = '25.04.14'
74
75
 
75
76
  _EPS_K = _EPStol * _0_1 # Karney's eps_ or _EPSmin * _0_1?
76
77
  _over_horizon_ = 'over horizon'
@@ -112,7 +113,7 @@ class _AzimuthalBase(_NamedBase):
112
113
 
113
114
  @raise TypeError: Invalid B{C{datum}}.
114
115
  '''
115
- if datum not in (None, self._datum):
116
+ if not _isin(datum, None, self._datum):
116
117
  self._datum = _spherical_datum(datum, **name)
117
118
  if name:
118
119
  self.name = name
@@ -1088,7 +1089,7 @@ class Stereographic(_AzimuthalBase):
1088
1089
  def k0(self, factor):
1089
1090
  '''Set the central scale factor (C{scalar}).
1090
1091
  '''
1091
- n = Stereographic.k0.fget.__name__ # 'k0', name__=Stereographic.k0.fget
1092
+ n = typename(Stereographic.k0.fget) # 'k0', name__=Stereographic.k0.fget
1092
1093
  self._k0 = Scalar_(factor, name=n, low=EPS, high=2) # XXX high=1, 2, other?
1093
1094
  self._k02 = self._k0 * _2_0
1094
1095