pygeodesy 24.3.24__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PyGeodesy-24.3.24.dist-info/METADATA +272 -0
- PyGeodesy-24.3.24.dist-info/RECORD +115 -0
- PyGeodesy-24.3.24.dist-info/WHEEL +6 -0
- PyGeodesy-24.3.24.dist-info/top_level.txt +1 -0
- pygeodesy/LICENSE +21 -0
- pygeodesy/__init__.py +615 -0
- pygeodesy/__main__.py +103 -0
- pygeodesy/albers.py +867 -0
- pygeodesy/auxilats/_CX_4.py +218 -0
- pygeodesy/auxilats/_CX_6.py +314 -0
- pygeodesy/auxilats/_CX_8.py +475 -0
- pygeodesy/auxilats/__init__.py +54 -0
- pygeodesy/auxilats/__main__.py +86 -0
- pygeodesy/auxilats/auxAngle.py +548 -0
- pygeodesy/auxilats/auxDLat.py +302 -0
- pygeodesy/auxilats/auxDST.py +296 -0
- pygeodesy/auxilats/auxLat.py +848 -0
- pygeodesy/auxilats/auxily.py +272 -0
- pygeodesy/azimuthal.py +1150 -0
- pygeodesy/basics.py +892 -0
- pygeodesy/booleans.py +2031 -0
- pygeodesy/cartesianBase.py +1062 -0
- pygeodesy/clipy.py +704 -0
- pygeodesy/constants.py +516 -0
- pygeodesy/css.py +660 -0
- pygeodesy/datums.py +752 -0
- pygeodesy/deprecated/__init__.py +61 -0
- pygeodesy/deprecated/bases.py +40 -0
- pygeodesy/deprecated/classes.py +262 -0
- pygeodesy/deprecated/consterns.py +54 -0
- pygeodesy/deprecated/datum.py +40 -0
- pygeodesy/deprecated/functions.py +375 -0
- pygeodesy/deprecated/nvector.py +48 -0
- pygeodesy/deprecated/rhumbBase.py +32 -0
- pygeodesy/deprecated/rhumbaux.py +33 -0
- pygeodesy/deprecated/rhumbsolve.py +33 -0
- pygeodesy/deprecated/rhumbx.py +33 -0
- pygeodesy/dms.py +986 -0
- pygeodesy/ecef.py +1348 -0
- pygeodesy/elevations.py +279 -0
- pygeodesy/ellipsoidalBase.py +1224 -0
- pygeodesy/ellipsoidalBaseDI.py +913 -0
- pygeodesy/ellipsoidalExact.py +343 -0
- pygeodesy/ellipsoidalGeodSolve.py +343 -0
- pygeodesy/ellipsoidalKarney.py +403 -0
- pygeodesy/ellipsoidalNvector.py +685 -0
- pygeodesy/ellipsoidalVincenty.py +590 -0
- pygeodesy/ellipsoids.py +2476 -0
- pygeodesy/elliptic.py +1198 -0
- pygeodesy/epsg.py +243 -0
- pygeodesy/errors.py +804 -0
- pygeodesy/etm.py +1190 -0
- pygeodesy/fmath.py +1013 -0
- pygeodesy/formy.py +1818 -0
- pygeodesy/frechet.py +865 -0
- pygeodesy/fstats.py +760 -0
- pygeodesy/fsums.py +1898 -0
- pygeodesy/gars.py +358 -0
- pygeodesy/geodesicw.py +581 -0
- pygeodesy/geodesicx/_C4_24.py +1699 -0
- pygeodesy/geodesicx/_C4_27.py +2395 -0
- pygeodesy/geodesicx/_C4_30.py +3301 -0
- pygeodesy/geodesicx/__init__.py +48 -0
- pygeodesy/geodesicx/__main__.py +91 -0
- pygeodesy/geodesicx/gx.py +1382 -0
- pygeodesy/geodesicx/gxarea.py +535 -0
- pygeodesy/geodesicx/gxbases.py +154 -0
- pygeodesy/geodesicx/gxline.py +669 -0
- pygeodesy/geodsolve.py +426 -0
- pygeodesy/geohash.py +914 -0
- pygeodesy/geoids.py +1884 -0
- pygeodesy/hausdorff.py +892 -0
- pygeodesy/heights.py +1155 -0
- pygeodesy/interns.py +687 -0
- pygeodesy/iters.py +545 -0
- pygeodesy/karney.py +919 -0
- pygeodesy/ktm.py +633 -0
- pygeodesy/latlonBase.py +1766 -0
- pygeodesy/lazily.py +960 -0
- pygeodesy/lcc.py +684 -0
- pygeodesy/ltp.py +1107 -0
- pygeodesy/ltpTuples.py +1563 -0
- pygeodesy/mgrs.py +721 -0
- pygeodesy/named.py +1324 -0
- pygeodesy/namedTuples.py +683 -0
- pygeodesy/nvectorBase.py +695 -0
- pygeodesy/osgr.py +781 -0
- pygeodesy/points.py +1686 -0
- pygeodesy/props.py +628 -0
- pygeodesy/resections.py +1048 -0
- pygeodesy/rhumb/__init__.py +46 -0
- pygeodesy/rhumb/aux_.py +397 -0
- pygeodesy/rhumb/bases.py +1148 -0
- pygeodesy/rhumb/ekx.py +563 -0
- pygeodesy/rhumb/solve.py +572 -0
- pygeodesy/simplify.py +647 -0
- pygeodesy/solveBase.py +472 -0
- pygeodesy/sphericalBase.py +724 -0
- pygeodesy/sphericalNvector.py +1264 -0
- pygeodesy/sphericalTrigonometry.py +1447 -0
- pygeodesy/streprs.py +627 -0
- pygeodesy/trf.py +2079 -0
- pygeodesy/triaxials.py +1484 -0
- pygeodesy/units.py +969 -0
- pygeodesy/unitsBase.py +349 -0
- pygeodesy/ups.py +538 -0
- pygeodesy/utily.py +1231 -0
- pygeodesy/utm.py +762 -0
- pygeodesy/utmups.py +318 -0
- pygeodesy/utmupsBase.py +517 -0
- pygeodesy/vector2d.py +785 -0
- pygeodesy/vector3d.py +968 -0
- pygeodesy/vector3dBase.py +1049 -0
- pygeodesy/webmercator.py +383 -0
- pygeodesy/wgrs.py +439 -0
pygeodesy/constants.py
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
u'''Single-instance C{float} and C{int} constants across C{pygeodesy} modules and
|
|
4
|
+
related functions L{pygeodesy.float_}, L{pygeodesy.isclose}, L{pygeodesy.isfinite},
|
|
5
|
+
L{pygeodesy.isinf}, L{pygeodesy.isint0}, L{pygeodesy.isnan}, L{pygeodesy.isnear0},
|
|
6
|
+
L{pygeodesy.isnear1}, L{pygeodesy.isnear90}, L{pygeodesy.isneg0}, L{pygeodesy.isninf},
|
|
7
|
+
L{pygeodesy.isnon0} and L{pygeodesy.remainder}.
|
|
8
|
+
'''
|
|
9
|
+
# make sure int/int division yields float quotient, see .basics
|
|
10
|
+
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
11
|
+
|
|
12
|
+
from pygeodesy.basics import _0_0, _copysign, isbool, iscomplex, isint, _ALL_LAZY
|
|
13
|
+
from pygeodesy.errors import _xError, _xError2, _xkwds_get, _xkwds_item2
|
|
14
|
+
from pygeodesy.interns import _INF_, _NAN_, _UNDER_
|
|
15
|
+
# from pygeodesy.lazily import _ALL_LAZY # from .basics
|
|
16
|
+
# from pygeodesy.streprs import Fmt # from .unitsBase
|
|
17
|
+
from pygeodesy.unitsBase import Float, Int, Radius, Fmt
|
|
18
|
+
|
|
19
|
+
from math import fabs, isinf, isnan, pi as _PI, sqrt
|
|
20
|
+
try:
|
|
21
|
+
from math import inf as _inf, nan as _nan # PYCHOK Python 3+
|
|
22
|
+
except ImportError: # Python 2-
|
|
23
|
+
_inf, _nan = float(_INF_), float(_NAN_)
|
|
24
|
+
|
|
25
|
+
__all__ = _ALL_LAZY.constants
|
|
26
|
+
__version__ = '24.03.15'
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _copysign_0_0(y):
|
|
30
|
+
'''(INTERNAL) copysign(0.0, y), only C{float}.
|
|
31
|
+
'''
|
|
32
|
+
return _N_0_0 if y < 0 else _0_0
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _copysign_1_0(y):
|
|
36
|
+
'''(INTERNAL) copysign(1.0, y), only C{float}.
|
|
37
|
+
'''
|
|
38
|
+
return _N_1_0 if y < 0 else _1_0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _copysignINF(y):
|
|
42
|
+
'''(INTERNAL) copysign(INF, y), only C{float}.
|
|
43
|
+
'''
|
|
44
|
+
return NINF if y < 0 else INF
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _Float(**name_arg):
|
|
48
|
+
'''(INTERNAL) New named, cached C{Float}.
|
|
49
|
+
'''
|
|
50
|
+
n, arg = _xkwds_item2(name_arg)
|
|
51
|
+
return Float(_float(arg), name=n)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _Radius(**name_arg):
|
|
55
|
+
'''(INTERNAL) New named, cached C{Radius}.
|
|
56
|
+
'''
|
|
57
|
+
n, arg = _xkwds_item2(name_arg)
|
|
58
|
+
return Radius(_float(arg), name=n)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def float_(*fs, **sets): # sets=False
|
|
62
|
+
'''Get scalars as C{float} or I{intern}'ed C{float}.
|
|
63
|
+
|
|
64
|
+
@arg fs: One more values (C{scalar}), all positional.
|
|
65
|
+
@kwarg sets: Use C{B{sets}=True} to C{intern} each
|
|
66
|
+
B{C{fs}}, otherwise don't C{intern}.
|
|
67
|
+
|
|
68
|
+
@return: A single C{float} if only one B{C{fs}} is
|
|
69
|
+
given, otherwise a tuple of C{float}s.
|
|
70
|
+
|
|
71
|
+
@raise TypeError: Some B{C{fs}} is not C{scalar}.
|
|
72
|
+
'''
|
|
73
|
+
fl = []
|
|
74
|
+
_a = fl.append
|
|
75
|
+
_f = _floats.setdefault if _xkwds_get(sets, sets=False) else \
|
|
76
|
+
_floats.get
|
|
77
|
+
try:
|
|
78
|
+
for i, f in enumerate(fs):
|
|
79
|
+
f = float(f)
|
|
80
|
+
_a(_f(f, f))
|
|
81
|
+
except Exception as x:
|
|
82
|
+
E, t = _xError2(x)
|
|
83
|
+
fs_i = Fmt.SQUARE(fs=i)
|
|
84
|
+
raise E(fs_i, f, txt=t)
|
|
85
|
+
return fl[0] if len(fl) == 1 else tuple(fl)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _float(f): # in .datums, .ellipsoids, ...
|
|
89
|
+
'''(INTERNAL) Cache initial C{float}s.
|
|
90
|
+
'''
|
|
91
|
+
f = float(f)
|
|
92
|
+
return _floats.setdefault(f, f) # PYCHOK del _floats
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def float0_(*xs):
|
|
96
|
+
'''Yield C{B{x}s} as a non-NEG0 C{float}.
|
|
97
|
+
'''
|
|
98
|
+
for x in xs:
|
|
99
|
+
yield float(x) if x else _0_0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _float0(f): # in .resections, .vector3dBase, ...
|
|
103
|
+
'''(INTERNAL) Return C{float(B{f})} or C{INT0}.
|
|
104
|
+
'''
|
|
105
|
+
if f:
|
|
106
|
+
f = float(f)
|
|
107
|
+
f = _floats.get(f, f)
|
|
108
|
+
elif f is not INT0:
|
|
109
|
+
f = float(f) or _0_0 # force None, NN error
|
|
110
|
+
return f
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _floatuple(*fs):
|
|
114
|
+
'''(INTERNAL) Cache a tuple of C{float}s.
|
|
115
|
+
'''
|
|
116
|
+
return tuple(map(_float, fs))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
from math import log2 as _log2
|
|
121
|
+
except ImportError: # Python 3.3-
|
|
122
|
+
from math import log as _log
|
|
123
|
+
|
|
124
|
+
def _log2(x): # in .rhumb.aux_, .auxilats.auxLat
|
|
125
|
+
return _log(x, 2)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _naninf(p, *xs):
|
|
129
|
+
'''(INTERNAL) Return C{NAN}, C{NINF} or C{INF}.
|
|
130
|
+
'''
|
|
131
|
+
for x in xs:
|
|
132
|
+
p *= x # fmath.fprod(xs)
|
|
133
|
+
return _copysignINF(p) if isfinite(p) else p
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _over(p, q):
|
|
137
|
+
'''(INTERNAL) Return C{B{p} / B{q}} avoiding C{ZeroDivisionError} exceptions.
|
|
138
|
+
'''
|
|
139
|
+
try:
|
|
140
|
+
return (p / q)
|
|
141
|
+
except ZeroDivisionError:
|
|
142
|
+
return (_copysignINF(p) if isfinite(p) else NAN) if p else p
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _1_over(x):
|
|
146
|
+
'''(INTERNAL) Return reciprocal C{1 / B{x}} avoiding C{ZeroDivisionError} exceptions.
|
|
147
|
+
'''
|
|
148
|
+
try:
|
|
149
|
+
return _1_0 / float(x)
|
|
150
|
+
except ZeroDivisionError:
|
|
151
|
+
return NINF if isneg0(x) else INF
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
_floats = {} # PYCHOK floats cache, in .__main__
|
|
155
|
+
# _float = float # PYCHOK expected
|
|
156
|
+
# del _floats # XXX zap floats cache never
|
|
157
|
+
|
|
158
|
+
_0_0 = _float( _0_0) # PYCHOK expected
|
|
159
|
+
_0_0_1T = _0_0, # PYCHOK 1-tuple
|
|
160
|
+
_0_0_9T = _0_0_1T * 9 # PYCHOK 9-tuple
|
|
161
|
+
_0_0001 = _float( 0.0001) # PYCHOK expected
|
|
162
|
+
_0_001 = _float( 0.001) # PYCHOK expected
|
|
163
|
+
_0_01 = _float( 0.01) # PYCHOK expected
|
|
164
|
+
_0_1 = _float( 0.1) # PYCHOK expected
|
|
165
|
+
_0_125 = _float( 0.125) # PYCHOK expected
|
|
166
|
+
_0_25 = _float( 0.25) # PYCHOK expected
|
|
167
|
+
_0_5 = _float( 0.5) # PYCHOK expected
|
|
168
|
+
_1_0 = _float( 1) # PYCHOK expected
|
|
169
|
+
_1_0_1T = _1_0, # PYCHOK 1-tuple
|
|
170
|
+
_1_5 = _float( 1.5) # PYCHOK expected
|
|
171
|
+
_1_75 = _float( 1.75) # PYCHOK expected
|
|
172
|
+
_2_0 = _float( 2) # PYCHOK expected
|
|
173
|
+
_3_0 = _float( 3) # PYCHOK expected
|
|
174
|
+
_4_0 = _float( 4) # PYCHOK expected
|
|
175
|
+
_5_0 = _float( 5) # PYCHOK expected
|
|
176
|
+
_6_0 = _float( 6) # PYCHOK expected
|
|
177
|
+
_8_0 = _float( 8) # PYCHOK expected
|
|
178
|
+
_9_0 = _float( 9) # PYCHOK expected
|
|
179
|
+
_10_0 = _float( 10) # PYCHOK expected
|
|
180
|
+
_16_0 = _float( 16) # PYCHOK expected
|
|
181
|
+
_32_0 = _float( 32) # PYCHOK expected
|
|
182
|
+
_60_0 = _float( 60) # PYCHOK expected
|
|
183
|
+
_90_0 = _float( 90) # PYCHOK expected
|
|
184
|
+
_100_0 = _float( 100) # PYCHOK expected
|
|
185
|
+
_180_0 = _float( 180) # PYCHOK expected
|
|
186
|
+
_270_0 = _float( 270) # PYCHOK expected
|
|
187
|
+
_360_0 = _float( 360) # PYCHOK expected
|
|
188
|
+
_400_0 = _float( 400) # PYCHOK expected
|
|
189
|
+
_720_0 = _float( 720) # PYCHOK expected
|
|
190
|
+
_1000_0 = _float(1000) # PYCHOK expected
|
|
191
|
+
_3600_0 = _float(3600) # PYCHOK expected
|
|
192
|
+
|
|
193
|
+
_N_0_0 = float( '-0.0') # PYCHOK NOT _float!
|
|
194
|
+
_N_0_5 = _float( -_0_5) # PYCHOK expected
|
|
195
|
+
_N_1_0 = _float( -_1_0) # PYCHOK expected
|
|
196
|
+
_N_2_0 = _float( -_2_0) # PYCHOK expected
|
|
197
|
+
_N_90_0 = _float( -_90_0) # PYCHOK expected
|
|
198
|
+
_N_180_0 = _float(-_180_0) # PYCHOK expected
|
|
199
|
+
|
|
200
|
+
_M_KM = _1000_0 # meter per Kilo meter, see .utily
|
|
201
|
+
_M_NM = _float(1852.0) # meter per Nautical Mile, exactly
|
|
202
|
+
_M_SM = _float(1609.344) # meter per Statute Mile
|
|
203
|
+
|
|
204
|
+
try:
|
|
205
|
+
from sys import float_info as _f_i
|
|
206
|
+
# @see: <https://NumPy.org/doc/stable/reference/generated/numpy.finfo.html>
|
|
207
|
+
DIG = Int( DIG =_f_i.dig) # PYCHOK system's float decimal digits
|
|
208
|
+
EPS = _Float(EPS =_f_i.epsilon) # PYCHOK system's EPSilon
|
|
209
|
+
MANT_DIG = Int( MANT_DIG=_f_i.mant_dig) # PYCHOK system's float mantissa bits
|
|
210
|
+
MAX = _Float(MAX =_f_i.max) # PYCHOK system's MAX float 1.7976931348623157e+308
|
|
211
|
+
MAX_EXP = Int( MAX_EXP =_f_i.max_exp) # PYTHON system's max base 2 exponent
|
|
212
|
+
MIN = _Float(MIN =_f_i.min) # PYCHOK system's MIN float 2.2250738585072014e-308
|
|
213
|
+
MIN_EXP = Int( MIN_EXP =_f_i.min_exp) # PYTHON system's min base 2 exponent
|
|
214
|
+
# RADIX = Int( RADIX =_f_i.radix) # PYTHON system's float base
|
|
215
|
+
del _f_i
|
|
216
|
+
except ImportError: # PYCHOK no cover
|
|
217
|
+
DIG = Int( DIG =15) # PYCHOK system's 64-bit float decimal digits
|
|
218
|
+
EPS = _Float(EPS =2.220446049250313e-16) # PYCHOK EPSilon 2**-52, M{EPS +/- 1 != 1}
|
|
219
|
+
MANT_DIG = Int( MANT_DIG=53) # PYCHOK float mantissa bits ≈ 53 (C{int})
|
|
220
|
+
MAX = _Float(MAX =pow(_2_0, 1023) * (_2_0 - EPS)) # PYCHOK ≈ 10**308
|
|
221
|
+
MAX_EXP = Int( MAX_ESP =_log2(MAX)) # 308 base 10
|
|
222
|
+
MIN = _Float(MIN =pow(_2_0, -1021)) # PYCHOK ≈ 10**-308
|
|
223
|
+
MIN_EXP = Int(MIN_EXP =_log2(MIN)) # -307 base 10
|
|
224
|
+
# RADIX = Int(Radix =2) # base
|
|
225
|
+
|
|
226
|
+
EPS0 = _Float( EPS0 = EPS**2) # PYCHOK near-/non-zero comparison 4.930381e-32, or EPS or EPS_2
|
|
227
|
+
EPS02 = _Float( EPS02 = EPS**4) # PYCHOK near-zero-squared comparison 2.430865e-63
|
|
228
|
+
EPS_2 = _Float( EPS_2 = EPS / _2_0) # PYCHOK ≈ 1.110223024625e-16
|
|
229
|
+
EPS1 = _Float( EPS1 =_1_0 - EPS) # PYCHOK ≈ 0.9999999999999998
|
|
230
|
+
EPS2 = _Float( EPS2 = EPS * _2_0) # PYCHOK ≈ 4.440892098501e-16
|
|
231
|
+
EPS4 = _Float( EPS4 = EPS * _4_0) # PYCHOK ≈ 8.881784197001e-16
|
|
232
|
+
# _1EPS = _Float(_1EPS =_1_0 + EPS) # PYCHOK ≈ 1.0000000000000002
|
|
233
|
+
_1_EPS = _Float(_1_EPS =_1_0 / EPS) # PYCHOK = 4503599627370496.0
|
|
234
|
+
# _2_EPS = _Float(_2_EPS =_2_0 / EPS) # PYCHOK = 9007199254740992.0
|
|
235
|
+
_EPS2e4 = _Float(_EPS2e4 = EPS2 * 1.e4) # PYCHOK ≈ 4.440892098501e-12
|
|
236
|
+
_EPS4e8 = _Float(_EPS4e8 = EPS4 * 1.e8) # PYCHOK ≈ 8.881784197001e-08
|
|
237
|
+
_EPSmin = _Float(_EPSmin = sqrt(MIN)) # PYCHOK = 1.49166814624e-154
|
|
238
|
+
_EPSqrt = _Float(_EPSqrt = sqrt(EPS)) # PYCHOK = 1.49011611938e5-08
|
|
239
|
+
_EPStol = _Float(_EPStol =_EPSqrt * _0_1) # PYCHOK = 1.49011611938e5-09 == sqrt(EPS * _0_01)
|
|
240
|
+
|
|
241
|
+
_89_999_ = _Float(_89_999_= EPS1 * _90_0) # just below 90.0
|
|
242
|
+
# <https://Numbers.Computation.Free.FR/Constants/Miscellaneous/digits.html>
|
|
243
|
+
_1__90 = _Float(_1__90 =_1_0 / _90_0) # PYCHOK = 0.011_111_111_111_111_111_111_111_111_111_111_111_111_111_111_11111
|
|
244
|
+
_2__PI = _Float(_2__PI =_2_0 / _PI) # PYCHOK = 0.636_619_772_367_581_343_075_535_053_490_057_448_137_838_582_96182
|
|
245
|
+
|
|
246
|
+
_1_16th = _Float(_1_16th =_1_0 / _16_0) # PYCHOK in .ellipsoids, .karney
|
|
247
|
+
_1_64th = _Float(_1_64th =_1_0 / 64) # PYCHOK in .elliptic, pow(2.0, -6)
|
|
248
|
+
_1_3rd = _Float(_1_3rd =_1_0 / _3_0) # PYCHOK in .fmath
|
|
249
|
+
_1_6th = _Float(_1_6th =_1_0 / _6_0) # PYCHOK in .fmath
|
|
250
|
+
_2_3rd = _Float(_2_3rd =_2_0 / _3_0) # PYCHOK in .fmath
|
|
251
|
+
|
|
252
|
+
_K0_UTM = _Float(_K0_UTM = 0.9996) # PYCHOK in .etm, .ktm, .utm, UTM scale at central meridian
|
|
253
|
+
# sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
254
|
+
# 1.414213562373095_048_801_688_724_209_698_078_569_671_875_376_948_073_176_679_737_99
|
|
255
|
+
# _1SQRT2= _Float(_1SQRT2 =sqrt(_2_0) + 1)
|
|
256
|
+
_SQRT2_2 = _Float(_SQRT2_2=sqrt(_0_5)) # PYCHOK = 0.707106781186547_6 == sqrt(2) / 2
|
|
257
|
+
|
|
258
|
+
INF = Float(INF =_inf) # PYCHOK INFinity, see function L{isinf}, L{isfinite}, NOT _Float!
|
|
259
|
+
INT0 = Int( INT0= 0) # PYCHOK unique int(0) instance, see .fsums, useZ=False
|
|
260
|
+
NAN = Float(NAN =_nan) # PYCHOK Not-A-Number, see function L{isnan}, NOT _Float!
|
|
261
|
+
NEG0 = Float(NEG0=_N_0_0) # PYCHOK NEGative 0.0, see function L{isneg0}, NOT _Float!
|
|
262
|
+
NINF = Float(NINF=-INF) # PYCHOK Negative INFinity, NOT _Float!
|
|
263
|
+
|
|
264
|
+
PI = _Float(PI =_PI) # 3.1415_9265_3589_7932_3846_2643_3832_795
|
|
265
|
+
PI2 = _Float(PI2 =_PI * _2_0) # PYCHOK Two PI, M{PI * 2} aka I{Tau}
|
|
266
|
+
PI_2 = _Float(PI_2 =_PI / _2_0) # PYCHOK Half PI, M{PI / 2}
|
|
267
|
+
PI3 = _Float(PI3 =_PI * _3_0) # PYCHOK Three PI, M{PI * 3}
|
|
268
|
+
PI3_2 = _Float(PI3_2=_PI * _1_5) # PYCHOK PI and a half, M{PI * 3 / 2}
|
|
269
|
+
PI_3 = _Float(PI_3 =_PI / _3_0) # PYCHOK One third PI, M{PI / 3}
|
|
270
|
+
PI4 = _Float(PI4 =_PI * _4_0) # PYCHOK Four PI, M{PI * 4}
|
|
271
|
+
PI_4 = _Float(PI_4 =_PI / _4_0) # PYCHOK Quarter PI, M{PI / 4}
|
|
272
|
+
|
|
273
|
+
R_MA = _Radius(R_MA=6378137.0) # PYCHOK equatorial earth radius (C{meter}), WGS84, EPSG:3785
|
|
274
|
+
R_MB = _Radius(R_MB=6356752.3) # PYCHOK polar earth radius (C{meter}), WGS84, EPSG:3785
|
|
275
|
+
R_M = _Radius(R_M =6371008.771415) # PYCHOK mean, spherical earth radius (C{meter})
|
|
276
|
+
R_KM = _Radius(R_KM=R_M / _M_KM) # PYCHOK mean, spherical earth radius (C{KM}, Kilo meter)
|
|
277
|
+
R_NM = _Radius(R_NM=R_M / _M_NM) # PYCHOK mean, spherical earth radius (C{NM}, nautical miles)
|
|
278
|
+
R_SM = _Radius(R_SM=R_M / _M_SM) # PYCHOK mean, spherical earth radius (C{SM}, statute miles)
|
|
279
|
+
# See <https://www.EdWilliams.org/avform.htm>, <https://www.DTIC.mil/dtic/tr/fulltext/u2/a216843.pdf>
|
|
280
|
+
# and <https://GitHub.com/NASA/MultiDop/blob/master/src/share/man/man3/geog_lib.3> based on the
|
|
281
|
+
# International Standard Nautical Mile of 1,852 meter (1' latitude)
|
|
282
|
+
R_FM = _Radius(R_FM=6371000.0) # PYCHOK former FAI Sphere earth radius (C{meter})
|
|
283
|
+
R_GM = _Radius(R_GM=6371230.0) # PYCHOK avg. radius, distance to geoid surface (C{meter})
|
|
284
|
+
# <http://Wiki.GIS.com/wiki/index.php/Ellipsoidal_quadratic_mean_radius>
|
|
285
|
+
R_QM = _Radius(R_QM=6372797.560856) # PYCHOK earth' quadratic mean radius (C{meter})
|
|
286
|
+
# Rtri= _Radius(Rtri=6372797.5559594) # PYCHOK Rtriaxial quadratic mean radius (C{meter}), WGS84
|
|
287
|
+
# Rbi = _Radius(Rbi =6367453.6345163) # PYCHOK Rbiaxial quadratic mean radius (C{meter}), WGS84
|
|
288
|
+
R_VM = _Radius(R_VM=6366707.0194937) # PYCHOK aViation/naVigation earth radius (C{meter})
|
|
289
|
+
# R_AU= Meter( R_AU=149597870700.0) # PYCHOK <https://WikiPedia.org/wiki/Astronomical_unit>
|
|
290
|
+
|
|
291
|
+
_INF_NAN_NINF = INF, NAN, NINF
|
|
292
|
+
_pos_self = _1_0.__pos__() is _1_0 # PYCHOK in .fsums, .vector3dBase
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _0_0s(n):
|
|
296
|
+
'''(INTERNAL) Return an C{B{n}-tuple} of C{_0_0} zeros.
|
|
297
|
+
'''
|
|
298
|
+
return _0_0_9T[:n] if 0 <= n <= len(_0_0_9T) else (_0_0_1T * n)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
from math import isclose as _isclose
|
|
303
|
+
except ImportError: # Python 3.4-
|
|
304
|
+
|
|
305
|
+
def _isclose(a, b, rel_tol=1e-9, abs_tol=0):
|
|
306
|
+
'''Mimick Python 3.5+ C{math.isclose}.
|
|
307
|
+
'''
|
|
308
|
+
t, d = abs_tol, fabs(a - b)
|
|
309
|
+
if d > t:
|
|
310
|
+
r = max(fabs(a), fabs(b)) * rel_tol
|
|
311
|
+
t = max(r, t)
|
|
312
|
+
return d <= t
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def isclose(a, b, rel_tol=1e-12, abs_tol=EPS0):
|
|
316
|
+
'''Like C{math.isclose}, but with defaults such
|
|
317
|
+
that C{isclose(0, EPS0)} is C{True} by default.
|
|
318
|
+
'''
|
|
319
|
+
return _isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
try:
|
|
323
|
+
from math import isfinite as _isfinite # in .ellipsoids, ...
|
|
324
|
+
except ImportError: # Python 3.1-
|
|
325
|
+
|
|
326
|
+
def _isfinite(x):
|
|
327
|
+
'''Mimick Python 3.2+ C{math.isfinite}.
|
|
328
|
+
'''
|
|
329
|
+
return not (isinf(x) or isnan(x))
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def isfinite(obj):
|
|
333
|
+
'''Check a finite C{scalar} or C{complex} value.
|
|
334
|
+
|
|
335
|
+
@arg obj: Value (C{scalar} or C{complex}).
|
|
336
|
+
|
|
337
|
+
@return: C{False} if B{C{obj}} is C{INF}, C{NINF}
|
|
338
|
+
or C{NAN}, C{True} otherwise.
|
|
339
|
+
|
|
340
|
+
@raise TypeError: Non-scalar and non-complex B{C{obj}}.
|
|
341
|
+
'''
|
|
342
|
+
try:
|
|
343
|
+
return (obj not in _INF_NAN_NINF) and _isfinite(obj)
|
|
344
|
+
except Exception as x:
|
|
345
|
+
if iscomplex(obj): # _isfinite(complex) thows TypeError
|
|
346
|
+
return isfinite(obj.real) and isfinite(obj.imag)
|
|
347
|
+
raise _xError(x, Fmt.PAREN(isfinite.__name__, obj))
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def isint0(obj, both=False):
|
|
351
|
+
'''Check for L{INT0} or C{int(0)} value.
|
|
352
|
+
|
|
353
|
+
@arg obj: The object (any C{type}).
|
|
354
|
+
@kwarg both: If C{true}, also check C{float(0)} (C{bool}).
|
|
355
|
+
|
|
356
|
+
@return: C{True} if B{C{obj}} is L{INT0}, C{int(0)} or
|
|
357
|
+
C{float(0)}, C{False} otherwise.
|
|
358
|
+
'''
|
|
359
|
+
return (obj is INT0 or obj is int(0) or bool(both and
|
|
360
|
+
(not obj) and isint(obj, both=True))) and not isbool(obj)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def isnear0(x, eps0=EPS0):
|
|
364
|
+
'''Is B{C{x}} near I{zero} within a tolerance?
|
|
365
|
+
|
|
366
|
+
@arg x: Value (C{scalar}).
|
|
367
|
+
@kwarg eps0: Near-I{zero} tolerance (C{EPS0}).
|
|
368
|
+
|
|
369
|
+
@return: C{True} if C{abs(B{x}) < B{eps0}},
|
|
370
|
+
C{False} otherwise.
|
|
371
|
+
|
|
372
|
+
@see: Function L{isnon0}.
|
|
373
|
+
'''
|
|
374
|
+
return bool(eps0 > x > -eps0)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def isnear1(x, eps1=EPS0):
|
|
378
|
+
'''Is B{C{x}} near I{one} within a tolerance?
|
|
379
|
+
|
|
380
|
+
@arg x: Value (C{scalar}).
|
|
381
|
+
@kwarg eps1: Near-I{one} tolerance (C{EPS0}).
|
|
382
|
+
|
|
383
|
+
@return: C{isnear0(B{x} - 1, eps0=B{eps1})}.
|
|
384
|
+
|
|
385
|
+
@see: Function L{isnear0}.
|
|
386
|
+
'''
|
|
387
|
+
return bool(eps1 > (x - _1_0) > -eps1)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def isnear90(x, eps90=EPS0):
|
|
391
|
+
'''Is B{C{x}} near I{90} within a tolerance?
|
|
392
|
+
|
|
393
|
+
@arg x: Value (C{scalar}).
|
|
394
|
+
@kwarg eps90: Near-I{90} tolerance (C{EPS0}).
|
|
395
|
+
|
|
396
|
+
@return: C{isnear0(B{x} - 90, eps0=eps90)}.
|
|
397
|
+
|
|
398
|
+
@see: Function L{isnear0}.
|
|
399
|
+
'''
|
|
400
|
+
return bool(eps90 > (x - _90_0) > -eps90)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def isneg0(x):
|
|
404
|
+
'''Check for L{NEG0}, negative C{0.0}.
|
|
405
|
+
|
|
406
|
+
@arg x: Value (C{scalar}).
|
|
407
|
+
|
|
408
|
+
@return: C{True} if B{C{x}} is C{NEG0} or C{-0.0},
|
|
409
|
+
C{False} otherwise.
|
|
410
|
+
'''
|
|
411
|
+
return (not x) and _copysign(1, x) < 0
|
|
412
|
+
# and str(x).startswith(_MINUS_)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def isninf(x):
|
|
416
|
+
'''Check for L{NINF}, negative C{INF}.
|
|
417
|
+
|
|
418
|
+
@arg x: Value (C{scalar}).
|
|
419
|
+
|
|
420
|
+
@return: C{True} if B{C{x}} is C{NINF} or C{-inf},
|
|
421
|
+
C{False} otherwise.
|
|
422
|
+
'''
|
|
423
|
+
return x is NINF or (x < 0 and not isfinite(x))
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def isnon0(x, eps0=EPS0):
|
|
427
|
+
'''Is B{C{x}} non-zero with a tolerance?
|
|
428
|
+
|
|
429
|
+
@arg x: Value (C{scalar}).
|
|
430
|
+
@kwarg eps0: Non-zero tolerance (C{EPS0}).
|
|
431
|
+
|
|
432
|
+
@return: C{True} if C{abs(B{x}) > B{eps0}},
|
|
433
|
+
C{False} otherwise.
|
|
434
|
+
|
|
435
|
+
@see: Function L{isnear0}.
|
|
436
|
+
'''
|
|
437
|
+
return not bool(eps0 > x > -eps0) # not isnear0
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def _off90(lat):
|
|
441
|
+
'''(INTERNAL) Off 90.0 for .gars and .wgrs.
|
|
442
|
+
'''
|
|
443
|
+
return max(min(lat, _89_999_), -_89_999_)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
from math import remainder
|
|
448
|
+
except ImportError: # Python 3.6-
|
|
449
|
+
from math import fmod as _fmod
|
|
450
|
+
|
|
451
|
+
def remainder(x, y):
|
|
452
|
+
'''Mimick Python 3.7+ C{math.remainder}.
|
|
453
|
+
'''
|
|
454
|
+
if isnan(y):
|
|
455
|
+
x = NAN
|
|
456
|
+
elif x and not isnan(x):
|
|
457
|
+
y = fabs(y)
|
|
458
|
+
x = _fmod(x, y)
|
|
459
|
+
h = _0_5 * y
|
|
460
|
+
if x >= h:
|
|
461
|
+
x -= y
|
|
462
|
+
elif x < -h:
|
|
463
|
+
x += y
|
|
464
|
+
return x # keep signed 0.0
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def _umod_360(deg):
|
|
468
|
+
'''(INTERNAL) Non-negative C{deg} modulo 360, basic C{.utily.wrap360}.
|
|
469
|
+
'''
|
|
470
|
+
return (deg % _360_0) or _0_0
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def _umod_PI2(rad):
|
|
474
|
+
'''(INTERNAL) Non-negative C{rad} modulo PI2, basic C{.utily.wrapPI2}.
|
|
475
|
+
'''
|
|
476
|
+
return (rad % PI2) or _0_0
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
if __name__ == '__main__':
|
|
480
|
+
|
|
481
|
+
from pygeodesy import itemsorted, printf
|
|
482
|
+
|
|
483
|
+
t = n = v = []
|
|
484
|
+
for n, v in itemsorted(locals()):
|
|
485
|
+
if isinstance(v, (Float, Int, Radius)):
|
|
486
|
+
printf('%9s: %r', n, v.toRepr(std=False))
|
|
487
|
+
if v.name != n:
|
|
488
|
+
raise AssertionError('%r != %r' % (n, v))
|
|
489
|
+
if v.name is not n:
|
|
490
|
+
raise AssertionError('%r is not %r' % (n, v))
|
|
491
|
+
if not n.startswith(_UNDER_):
|
|
492
|
+
t.append(n)
|
|
493
|
+
t.append(float_.__name__)
|
|
494
|
+
printf('__all__ = %r', tuple(t))
|
|
495
|
+
|
|
496
|
+
# **) MIT License
|
|
497
|
+
#
|
|
498
|
+
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
499
|
+
#
|
|
500
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
501
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
502
|
+
# to deal in the Software without restriction, including without limitation
|
|
503
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
504
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
505
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
506
|
+
#
|
|
507
|
+
# The above copyright notice and this permission notice shall be included
|
|
508
|
+
# in all copies or substantial portions of the Software.
|
|
509
|
+
#
|
|
510
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
511
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
512
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
513
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
514
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
515
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
516
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|