pygeodesy 24.10.24__py2.py3-none-any.whl → 24.12.12__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.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/METADATA +6 -6
- PyGeodesy-24.12.12.dist-info/RECORD +118 -0
- {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +5 -5
- pygeodesy/__main__.py +1 -1
- pygeodesy/albers.py +5 -5
- pygeodesy/auxilats/_CX_4.py +1 -1
- pygeodesy/auxilats/_CX_6.py +1 -1
- pygeodesy/auxilats/_CX_8.py +1 -1
- pygeodesy/auxilats/_CX_Rs.py +1 -1
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +1 -1
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDLat.py +6 -6
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +55 -65
- pygeodesy/basics.py +35 -34
- pygeodesy/booleans.py +37 -37
- pygeodesy/cartesianBase.py +26 -65
- pygeodesy/clipy.py +1 -1
- pygeodesy/constants.py +7 -7
- pygeodesy/css.py +8 -9
- pygeodesy/datums.py +1 -1
- pygeodesy/deprecated/__init__.py +2 -2
- pygeodesy/deprecated/bases.py +1 -1
- pygeodesy/deprecated/classes.py +10 -10
- pygeodesy/deprecated/consterns.py +1 -1
- pygeodesy/deprecated/datum.py +1 -1
- pygeodesy/deprecated/functions.py +23 -13
- pygeodesy/deprecated/nvector.py +1 -1
- pygeodesy/deprecated/rhumbBase.py +1 -1
- pygeodesy/deprecated/rhumbaux.py +1 -1
- pygeodesy/deprecated/rhumbsolve.py +1 -1
- pygeodesy/deprecated/rhumbx.py +1 -1
- pygeodesy/dms.py +1 -1
- pygeodesy/ecef.py +63 -69
- pygeodesy/elevations.py +1 -1
- pygeodesy/ellipsoidalBase.py +106 -121
- pygeodesy/ellipsoidalBaseDI.py +115 -119
- pygeodesy/ellipsoidalExact.py +36 -38
- pygeodesy/ellipsoidalGeodSolve.py +1 -1
- pygeodesy/ellipsoidalKarney.py +1 -1
- pygeodesy/ellipsoidalNvector.py +1 -1
- pygeodesy/ellipsoidalVincenty.py +6 -5
- pygeodesy/ellipsoids.py +7 -8
- pygeodesy/elliptic.py +6 -6
- pygeodesy/epsg.py +1 -1
- pygeodesy/errors.py +25 -25
- pygeodesy/etm.py +84 -76
- pygeodesy/fmath.py +54 -51
- pygeodesy/formy.py +74 -106
- pygeodesy/frechet.py +1 -1
- pygeodesy/fstats.py +1 -1
- pygeodesy/fsums.py +82 -72
- pygeodesy/gars.py +1 -1
- pygeodesy/geodesici.py +4 -4
- pygeodesy/geodesicw.py +16 -15
- pygeodesy/geodesicx/_C4_24.py +2 -2
- pygeodesy/geodesicx/_C4_27.py +2 -2
- pygeodesy/geodesicx/_C4_30.py +2 -2
- pygeodesy/geodesicx/__init__.py +3 -3
- pygeodesy/geodesicx/__main__.py +1 -1
- pygeodesy/geodesicx/gx.py +6 -5
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxbases.py +2 -2
- pygeodesy/geodesicx/gxline.py +16 -12
- pygeodesy/geodsolve.py +8 -17
- pygeodesy/geohash.py +1 -1
- pygeodesy/geoids.py +6 -6
- pygeodesy/hausdorff.py +1 -1
- pygeodesy/heights.py +3 -3
- pygeodesy/internals.py +64 -80
- pygeodesy/interns.py +2 -3
- pygeodesy/iters.py +1 -1
- pygeodesy/karney.py +4 -4
- pygeodesy/ktm.py +20 -21
- pygeodesy/latlonBase.py +296 -346
- pygeodesy/lazily.py +15 -15
- pygeodesy/lcc.py +5 -5
- pygeodesy/ltp.py +55 -59
- pygeodesy/ltpTuples.py +208 -192
- pygeodesy/mgrs.py +9 -10
- pygeodesy/named.py +153 -3
- pygeodesy/namedTuples.py +58 -7
- pygeodesy/nvectorBase.py +122 -105
- pygeodesy/osgr.py +10 -13
- pygeodesy/points.py +1 -1
- pygeodesy/props.py +3 -3
- pygeodesy/resections.py +26 -26
- pygeodesy/rhumb/__init__.py +2 -2
- pygeodesy/rhumb/aux_.py +2 -2
- pygeodesy/rhumb/bases.py +2 -2
- pygeodesy/rhumb/ekx.py +4 -4
- pygeodesy/rhumb/solve.py +4 -4
- pygeodesy/simplify.py +291 -403
- pygeodesy/solveBase.py +1 -1
- pygeodesy/sphericalBase.py +1 -1
- pygeodesy/sphericalNvector.py +84 -127
- pygeodesy/sphericalTrigonometry.py +66 -71
- pygeodesy/streprs.py +10 -5
- pygeodesy/trf.py +1 -1
- pygeodesy/triaxials.py +23 -16
- pygeodesy/units.py +17 -17
- pygeodesy/unitsBase.py +1 -1
- pygeodesy/ups.py +4 -4
- pygeodesy/utily.py +202 -145
- pygeodesy/utm.py +10 -10
- pygeodesy/utmups.py +1 -1
- pygeodesy/utmupsBase.py +1 -1
- pygeodesy/vector2d.py +17 -17
- pygeodesy/vector3d.py +32 -23
- pygeodesy/vector3dBase.py +22 -19
- pygeodesy/webmercator.py +5 -5
- pygeodesy/wgrs.py +5 -5
- PyGeodesy-24.10.24.dist-info/RECORD +0 -118
- {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/top_level.txt +0 -0
pygeodesy/utily.py
CHANGED
|
@@ -13,35 +13,36 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
13
13
|
from pygeodesy.basics import _copysign, isinstanceof, isint, isstr, neg
|
|
14
14
|
from pygeodesy.constants import EPS, EPS0, INF, NAN, PI, PI2, PI_2, R_M, \
|
|
15
15
|
_M_KM, _M_NM, _M_SM, _0_0, _1__90, _0_5, _1_0, \
|
|
16
|
-
_N_1_0, _2__PI, _10_0, _90_0,
|
|
17
|
-
|
|
18
|
-
_float
|
|
19
|
-
_over, _umod_360, _umod_PI2
|
|
16
|
+
_N_1_0, _2__PI, _10_0, _90_0, _180_0, _N_180_0, \
|
|
17
|
+
_360_0, _400_0, isnan, isnear0, _copysign_0_0, \
|
|
18
|
+
_float, _isfinite, _over, _umod_360, _umod_PI2
|
|
20
19
|
from pygeodesy.errors import _ValueError, _xkwds, _xkwds_get1, _ALL_LAZY, _MODS
|
|
21
|
-
from pygeodesy.internals import _passargs # , _MODS?
|
|
20
|
+
from pygeodesy.internals import _passarg, _passargs # , _MODS?
|
|
22
21
|
from pygeodesy.interns import _edge_, _radians_, _semi_circular_, _SPACE_
|
|
23
22
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .errors
|
|
24
23
|
from pygeodesy.units import Degrees, Degrees_, Feet, Float, Lam, Lamd, \
|
|
25
24
|
Meter, Meter2, Radians, Radians_
|
|
26
25
|
|
|
27
|
-
from math import acos, asin, atan2, cos, degrees, fabs, radians,
|
|
26
|
+
from math import acos, asin, atan2 as _atan2, cos, degrees, fabs, radians, \
|
|
27
|
+
sin, tan as _tan # pow
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.utily
|
|
30
|
-
__version__ = '24.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
__version__ = '24.11.26'
|
|
31
|
+
|
|
32
|
+
_G_DEG = _float(_400_0 / _360_0) # grades per degree
|
|
33
|
+
_G_RAD = _float(_400_0 / PI2) # grades per radian
|
|
34
|
+
_M_CHAIN = _float( 20.1168) # meter per yard2m(1) * 22
|
|
35
|
+
_M_FATHOM = _float( 1.8288) # meter per yard2m(1) * 2 or _M_NM * 1e-3
|
|
36
|
+
_M_FOOT = _float( 0.3048) # meter per Int'l foot, 1 / 3.2808398950131 = 10_000 / (254 * 12)
|
|
37
|
+
_M_FOOT_GE = _float( 0.31608) # meter per German Fuss, 1 / 3.1637560111364
|
|
38
|
+
_M_FOOT_FR = _float( 0.3248406) # meter per French Pied-du-Roi or pied, 1 / 3.0784329298739
|
|
39
|
+
_M_FOOT_US = _float( 0.3048006096012192) # meter per US Survey foot, 1200 / 3937
|
|
40
|
+
_M_FURLONG = _float( 201.168) # meter per furlong, 220 * yard2m(1) = 10 * m2chain(1)
|
|
41
|
+
# _M_KM = _float(1000.0) # meter per kilo meter
|
|
42
|
+
# _M_NM = _float(1852.0) # meter per nautical mile
|
|
43
|
+
# _M_SM = _float(1609.344) # meter per statute mile
|
|
44
|
+
_M_TOISE = _float( 1.9490436) # meter per French toise, 6 pieds = 6 / 3.0784329298739
|
|
45
|
+
_M_YARD_UK = _float( 0.9144) # meter per yard, 254 * 12 * 3 / 10_000 = 3 * _M_FOOT
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
def _abs1nan(x):
|
|
@@ -92,7 +93,7 @@ def atan1(y, x=_1_0):
|
|
|
92
93
|
'''Return C{atan(B{y} / B{x})} angle in C{radians} M{[-PI/2..+PI/2]}
|
|
93
94
|
using C{atan2} for consistency and to avoid C{ZeroDivisionError}.
|
|
94
95
|
'''
|
|
95
|
-
return
|
|
96
|
+
return _atan2(-y, -x) if x < 0 else _atan2(y, x or _0_0) # -0. to 0.
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
def atan1d(y, x=_1_0):
|
|
@@ -104,6 +105,15 @@ def atan1d(y, x=_1_0):
|
|
|
104
105
|
return atan2d(-y, -x) if x < 0 else atan2d(y, x or _0_0) # -0. to 0.
|
|
105
106
|
|
|
106
107
|
|
|
108
|
+
def atan2(y, x):
|
|
109
|
+
'''Return C{atan2(B{y}, B{x})} in radians M{[-PI..+PI]}.
|
|
110
|
+
|
|
111
|
+
@see: I{Karney}'s C++ function U{Math.atan2d
|
|
112
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Math.html>}.
|
|
113
|
+
'''
|
|
114
|
+
return _atan2u(y, x, _passarg, PI, PI_2)
|
|
115
|
+
|
|
116
|
+
|
|
107
117
|
def atan2b(y, x):
|
|
108
118
|
'''Return C{atan2(B{y}, B{x})} in degrees M{[0..+360]}.
|
|
109
119
|
|
|
@@ -122,23 +132,30 @@ def atan2d(y, x, reverse=False):
|
|
|
122
132
|
@see: I{Karney}'s C++ function U{Math.atan2d
|
|
123
133
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Math.html>}.
|
|
124
134
|
'''
|
|
135
|
+
d = _atan2u(y, x, degrees, _180_0, _90_0)
|
|
136
|
+
return _azireversed(d) if reverse else d
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _atan2u(y, x, _2u, H, Q): # Half, Quarter turn in units
|
|
140
|
+
'''(INTERNAL) Helper for functions C{atan2} and C{atan2d}.
|
|
141
|
+
'''
|
|
125
142
|
if fabs(y) > fabs(x) > 0:
|
|
126
143
|
if y < 0: # q = 3
|
|
127
|
-
|
|
144
|
+
r = _2u(_atan2(x, -y)) - Q
|
|
128
145
|
else: # q = 2
|
|
129
|
-
|
|
146
|
+
r = Q - _2u(_atan2(x, y))
|
|
130
147
|
elif isnan(x) or isnan(y):
|
|
131
148
|
return NAN
|
|
132
149
|
elif y:
|
|
133
150
|
if x > 0: # q = 0
|
|
134
|
-
|
|
151
|
+
r = _2u(_atan2(y, x))
|
|
135
152
|
elif x < 0: # q = 1
|
|
136
|
-
|
|
153
|
+
r = _copysign(H, y) - _2u(_atan2(y, -x))
|
|
137
154
|
else: # x == 0
|
|
138
|
-
|
|
139
|
-
else:
|
|
140
|
-
|
|
141
|
-
return
|
|
155
|
+
r = _copysign(Q, y)
|
|
156
|
+
else: # preserve signBit(y) like Python's math.atan2
|
|
157
|
+
r = _copysign(H, y) if x < 0 else _0_0
|
|
158
|
+
return r
|
|
142
159
|
|
|
143
160
|
|
|
144
161
|
def _azireversed(azimuth): # in .rhumbBase
|
|
@@ -162,13 +179,11 @@ def chain2m(chains):
|
|
|
162
179
|
def circle4(earth, lat):
|
|
163
180
|
'''Get the equatorial or a parallel I{circle of latitude}.
|
|
164
181
|
|
|
165
|
-
@arg earth: The earth radius, ellipsoid or datum
|
|
166
|
-
(
|
|
167
|
-
L{Datum} or L{a_f2Tuple}).
|
|
182
|
+
@arg earth: The earth radius (C{meter}), ellipsoid or datum
|
|
183
|
+
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or L{a_f2Tuple}).
|
|
168
184
|
@arg lat: Geodetic latitude (C{degrees90}, C{str}).
|
|
169
185
|
|
|
170
|
-
@return: A L{Circle4Tuple}C{(radius, height, lat, beta)}
|
|
171
|
-
instance.
|
|
186
|
+
@return: A L{Circle4Tuple}C{(radius, height, lat, beta)}.
|
|
172
187
|
|
|
173
188
|
@raise RangeError: Latitude B{C{lat}} outside valid range and
|
|
174
189
|
L{rangerrors<pygeodesy.rangerrors>} is C{True}.
|
|
@@ -181,76 +196,78 @@ def circle4(earth, lat):
|
|
|
181
196
|
return E.circle4(lat)
|
|
182
197
|
|
|
183
198
|
|
|
184
|
-
def cot(rad, **
|
|
199
|
+
def cot(rad, **raiser_kwds):
|
|
185
200
|
'''Return the C{cotangent} of an angle in C{radians}.
|
|
186
201
|
|
|
187
202
|
@arg rad: Angle (C{radians}).
|
|
188
|
-
@kwarg
|
|
203
|
+
@kwarg raiser_kwds: Use C{B{raiser}=False} to avoid
|
|
204
|
+
ValueErrors or optionally, additional
|
|
205
|
+
ValueError keyword argments.
|
|
189
206
|
|
|
190
207
|
@return: C{cot(B{rad})}.
|
|
191
208
|
|
|
192
|
-
@raise
|
|
209
|
+
@raise Error: If L{pygeodesy.isnear0}C{(sin(B{rad})}.
|
|
193
210
|
'''
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
c = c / s # /= chokes PyChecker
|
|
199
|
-
return c
|
|
211
|
+
try:
|
|
212
|
+
return _cotu(*sincos2(rad), **raiser_kwds)
|
|
213
|
+
except ZeroDivisionError:
|
|
214
|
+
raise _valueError(cot, rad, **raiser_kwds)
|
|
200
215
|
|
|
201
216
|
|
|
202
|
-
def cot_(*rads, **
|
|
203
|
-
'''Return the C{cotangent} of angle(s) in C{
|
|
217
|
+
def cot_(*rads, **raiser_kwds):
|
|
218
|
+
'''Return the C{cotangent} of angle(s) in C{radians}.
|
|
204
219
|
|
|
205
|
-
@arg rads: One or more angles (C{radians}).
|
|
206
|
-
@kwarg error_kwds: Error to raise (C{ValueError}).
|
|
220
|
+
@arg rads: One or more angles (each in C{radians}).
|
|
207
221
|
|
|
208
222
|
@return: Yield the C{cot(B{rad})} for each angle.
|
|
209
223
|
|
|
210
|
-
@
|
|
224
|
+
@see: Function L{pygeodesy.cot} for further details.
|
|
211
225
|
'''
|
|
212
226
|
try:
|
|
213
227
|
for r in rads:
|
|
214
|
-
yield
|
|
215
|
-
except
|
|
216
|
-
raise _valueError(cot_, r, **
|
|
228
|
+
yield _cotu(*sincos2(r), **raiser_kwds)
|
|
229
|
+
except ZeroDivisionError:
|
|
230
|
+
raise _valueError(cot_, r, **raiser_kwds)
|
|
217
231
|
|
|
218
232
|
|
|
219
|
-
def cotd(deg, **
|
|
233
|
+
def cotd(deg, **raiser_kwds):
|
|
220
234
|
'''Return the C{cotangent} of an angle in C{degrees}.
|
|
221
235
|
|
|
222
236
|
@arg deg: Angle (C{degrees}).
|
|
223
|
-
@kwarg
|
|
237
|
+
@kwarg raiser_kwds: Use C{B{raiser}=False} to avoid
|
|
238
|
+
ValueErrors or optionally, additional
|
|
239
|
+
ValueError keyword argments.
|
|
224
240
|
|
|
225
241
|
@return: C{cot(B{deg})}.
|
|
226
242
|
|
|
227
|
-
@raise
|
|
243
|
+
@raise Error: If L{pygeodesy.isnear0}C{(sin(B{deg})}.
|
|
228
244
|
'''
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
c = c / s # /= chokes PyChecker
|
|
234
|
-
elif s < 0:
|
|
235
|
-
c = -c # negate-0
|
|
236
|
-
return c
|
|
245
|
+
try:
|
|
246
|
+
return _cotu(*sincos2d(deg), **raiser_kwds)
|
|
247
|
+
except ZeroDivisionError:
|
|
248
|
+
raise _valueError(cotd, deg, **raiser_kwds)
|
|
237
249
|
|
|
238
250
|
|
|
239
|
-
def cotd_(*degs, **
|
|
251
|
+
def cotd_(*degs, **raiser_kwds):
|
|
240
252
|
'''Return the C{cotangent} of angle(s) in C{degrees}.
|
|
241
253
|
|
|
242
|
-
@arg degs: One or more angles (C{degrees}).
|
|
243
|
-
@kwarg error_kwds: Error to raise (C{ValueError}).
|
|
254
|
+
@arg degs: One or more angles (each in C{degrees}).
|
|
244
255
|
|
|
245
256
|
@return: Yield the C{cot(B{deg})} for each angle.
|
|
246
257
|
|
|
247
|
-
@
|
|
258
|
+
@see: Function L{pygeodesy.cotd} for further details.
|
|
248
259
|
'''
|
|
249
260
|
try:
|
|
250
261
|
for d in degs:
|
|
251
|
-
yield
|
|
252
|
-
except
|
|
253
|
-
raise _valueError(cotd_, d, **
|
|
262
|
+
yield _cotu(*sincos2d(d), **raiser_kwds)
|
|
263
|
+
except ZeroDivisionError:
|
|
264
|
+
raise _valueError(cotd_, d, **raiser_kwds)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _cotu(s, c, **raiser_kwds):
|
|
268
|
+
'''(INTERNAL) Helper for functions C{cot}, C{cotd}, C{cot_} and C{cotd_}.
|
|
269
|
+
'''
|
|
270
|
+
return _tanu(c, s, **raiser_kwds)
|
|
254
271
|
|
|
255
272
|
|
|
256
273
|
def degrees90(rad):
|
|
@@ -290,30 +307,27 @@ def degrees2grades(deg):
|
|
|
290
307
|
|
|
291
308
|
@return: Angle (C{grades}).
|
|
292
309
|
'''
|
|
293
|
-
return Degrees(deg) *
|
|
310
|
+
return Float(grades=Degrees(deg) * _G_DEG)
|
|
294
311
|
|
|
295
312
|
|
|
296
313
|
def degrees2m(deg, radius=R_M, lat=0):
|
|
297
|
-
'''Convert an angle to a distance along the equator or
|
|
298
|
-
|
|
314
|
+
'''Convert an angle to a distance along the equator or along a parallel
|
|
315
|
+
at (geodetic) latitude.
|
|
299
316
|
|
|
300
317
|
@arg deg: The angle (C{degrees}).
|
|
301
|
-
@kwarg radius: Mean earth radius, ellipsoid or datum
|
|
302
|
-
(
|
|
303
|
-
L{Datum} or L{a_f2Tuple}).
|
|
318
|
+
@kwarg radius: Mean earth radius (C{meter}), an ellipsoid or datum
|
|
319
|
+
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or L{a_f2Tuple}).
|
|
304
320
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
305
321
|
|
|
306
|
-
@return: Distance (C{meter}, same units as B{C{radius}}
|
|
307
|
-
|
|
308
|
-
near-polar B{C{lat}}.
|
|
322
|
+
@return: Distance (C{meter}, same units as B{C{radius}} or polar and
|
|
323
|
+
equatorial radii) or C{0.0} for near-polar B{C{lat}}.
|
|
309
324
|
|
|
310
325
|
@raise RangeError: Latitude B{C{lat}} outside valid range and
|
|
311
326
|
L{rangerrors<pygeodesy.rangerrors>} is C{True}.
|
|
312
327
|
|
|
313
328
|
@raise TypeError: Invalid B{C{radius}}.
|
|
314
329
|
|
|
315
|
-
@raise ValueError: Invalid B{C{deg}}, B{C{radius}} or
|
|
316
|
-
B{C{lat}}.
|
|
330
|
+
@raise ValueError: Invalid B{C{deg}}, B{C{radius}} or B{C{lat}}.
|
|
317
331
|
|
|
318
332
|
@see: Function L{radians2m} and L{m2degrees}.
|
|
319
333
|
'''
|
|
@@ -349,9 +363,9 @@ def ft2m(feet, usurvey=False, pied=False, fuss=False):
|
|
|
349
363
|
|
|
350
364
|
@raise ValueError: Invalid B{C{feet}}.
|
|
351
365
|
'''
|
|
352
|
-
return Meter(Feet(feet) * (
|
|
353
|
-
(_M_FOOT_FR
|
|
354
|
-
(_M_FOOT_GE
|
|
366
|
+
return Meter(Feet(feet) * (_M_FOOT_US if usurvey else
|
|
367
|
+
(_M_FOOT_FR if pied else
|
|
368
|
+
(_M_FOOT_GE if fuss else _M_FOOT))))
|
|
355
369
|
|
|
356
370
|
|
|
357
371
|
def furlong2m(furlongs):
|
|
@@ -373,7 +387,7 @@ def grades(rad):
|
|
|
373
387
|
|
|
374
388
|
@return: Angle (C{grades}).
|
|
375
389
|
'''
|
|
376
|
-
return Float(grades=
|
|
390
|
+
return Float(grades=Radians(rad) * _G_RAD)
|
|
377
391
|
|
|
378
392
|
|
|
379
393
|
def grades400(rad):
|
|
@@ -383,7 +397,7 @@ def grades400(rad):
|
|
|
383
397
|
|
|
384
398
|
@return: Angle, wrapped (C{grades}).
|
|
385
399
|
'''
|
|
386
|
-
return Float(grades400=(
|
|
400
|
+
return Float(grades400=wrapPI2(rad) * _G_RAD)
|
|
387
401
|
|
|
388
402
|
|
|
389
403
|
def grades2degrees(gon):
|
|
@@ -393,7 +407,7 @@ def grades2degrees(gon):
|
|
|
393
407
|
|
|
394
408
|
@return: Angle (C{degrees}).
|
|
395
409
|
'''
|
|
396
|
-
return Degrees(Float(gon=gon)
|
|
410
|
+
return Degrees(Float(gon=gon) / _G_DEG)
|
|
397
411
|
|
|
398
412
|
|
|
399
413
|
def grades2radians(gon):
|
|
@@ -403,7 +417,7 @@ def grades2radians(gon):
|
|
|
403
417
|
|
|
404
418
|
@return: Angle (C{radians}).
|
|
405
419
|
'''
|
|
406
|
-
return Radians(Float(gon=gon)
|
|
420
|
+
return Radians(Float(gon=gon) / _G_RAD)
|
|
407
421
|
|
|
408
422
|
|
|
409
423
|
def km2m(km):
|
|
@@ -437,13 +451,12 @@ def m2chain(meter):
|
|
|
437
451
|
|
|
438
452
|
|
|
439
453
|
def m2degrees(distance, radius=R_M, lat=0):
|
|
440
|
-
'''Convert a distance to an angle along the equator or
|
|
441
|
-
|
|
454
|
+
'''Convert a distance to an angle along the equator or along a parallel
|
|
455
|
+
at (geodetic) latitude.
|
|
442
456
|
|
|
443
457
|
@arg distance: Distance (C{meter}, same units as B{C{radius}}).
|
|
444
|
-
@kwarg radius: Mean earth radius, ellipsoid or datum
|
|
445
|
-
|
|
446
|
-
L{a_f2Tuple}).
|
|
458
|
+
@kwarg radius: Mean earth radius (C{meter}), an ellipsoid or datum
|
|
459
|
+
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or L{a_f2Tuple}).
|
|
447
460
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
448
461
|
|
|
449
462
|
@return: Angle (C{degrees}) or C{INF} for near-polar B{C{lat}}.
|
|
@@ -453,8 +466,7 @@ def m2degrees(distance, radius=R_M, lat=0):
|
|
|
453
466
|
|
|
454
467
|
@raise TypeError: Invalid B{C{radius}}.
|
|
455
468
|
|
|
456
|
-
@raise ValueError: Invalid B{C{distance}}, B{C{radius}}
|
|
457
|
-
or B{C{lat}}.
|
|
469
|
+
@raise ValueError: Invalid B{C{distance}}, B{C{radius}} or B{C{lat}}.
|
|
458
470
|
|
|
459
471
|
@see: Function L{m2radians} and L{degrees2m}.
|
|
460
472
|
'''
|
|
@@ -492,9 +504,9 @@ def m2ft(meter, usurvey=False, pied=False, fuss=False):
|
|
|
492
504
|
'''
|
|
493
505
|
# * 3.2808333333333333, US Survey 3937 / 1200
|
|
494
506
|
# * 3.2808398950131235, Int'l 10_000 / (254 * 12)
|
|
495
|
-
return Float(feet=Meter(meter) / (
|
|
496
|
-
(_M_FOOT_FR
|
|
497
|
-
(_M_FOOT_GE
|
|
507
|
+
return Float(feet=Meter(meter) / (_M_FOOT_US if usurvey else
|
|
508
|
+
(_M_FOOT_FR if pied else
|
|
509
|
+
(_M_FOOT_GE if fuss else _M_FOOT))))
|
|
498
510
|
|
|
499
511
|
|
|
500
512
|
def m2furlong(meter):
|
|
@@ -534,13 +546,12 @@ def m2NM(meter):
|
|
|
534
546
|
|
|
535
547
|
|
|
536
548
|
def m2radians(distance, radius=R_M, lat=0):
|
|
537
|
-
'''Convert a distance to an angle along the equator or along
|
|
538
|
-
|
|
549
|
+
'''Convert a distance to an angle along the equator or along a parallel
|
|
550
|
+
at (geodetic) latitude.
|
|
539
551
|
|
|
540
552
|
@arg distance: Distance (C{meter}, same units as B{C{radius}}).
|
|
541
|
-
@kwarg radius: Mean earth radius, ellipsoid or datum
|
|
542
|
-
|
|
543
|
-
L{a_f2Tuple}).
|
|
553
|
+
@kwarg radius: Mean earth radius (C{meter}, an ellipsoid or datum
|
|
554
|
+
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or L{a_f2Tuple}).
|
|
544
555
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
545
556
|
|
|
546
557
|
@return: Angle (C{radians}) or C{INF} for near-polar B{C{lat}}.
|
|
@@ -550,8 +561,7 @@ def m2radians(distance, radius=R_M, lat=0):
|
|
|
550
561
|
|
|
551
562
|
@raise TypeError: Invalid B{C{radius}}.
|
|
552
563
|
|
|
553
|
-
@raise ValueError: Invalid B{C{distance}}, B{C{radius}}
|
|
554
|
-
or B{C{lat}}.
|
|
564
|
+
@raise ValueError: Invalid B{C{distance}}, B{C{radius}} or B{C{lat}}.
|
|
555
565
|
|
|
556
566
|
@see: Function L{m2degrees} and L{radians2m}.
|
|
557
567
|
'''
|
|
@@ -610,26 +620,23 @@ def NM2m(nm):
|
|
|
610
620
|
|
|
611
621
|
|
|
612
622
|
def radians2m(rad, radius=R_M, lat=0):
|
|
613
|
-
'''Convert an angle to a distance along the equator or
|
|
614
|
-
|
|
623
|
+
'''Convert an angle to a distance along the equator or along a parallel
|
|
624
|
+
at (geodetic) latitude.
|
|
615
625
|
|
|
616
626
|
@arg rad: The angle (C{radians}).
|
|
617
|
-
@kwarg radius: Mean earth radius
|
|
618
|
-
(
|
|
619
|
-
L{Datum} or L{a_f2Tuple}).
|
|
627
|
+
@kwarg radius: Mean earth radius (C{meter}) or an ellipsoid or datum
|
|
628
|
+
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or L{a_f2Tuple}).
|
|
620
629
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
621
630
|
|
|
622
|
-
@return: Distance (C{meter}, same units as B{C{radius}}
|
|
623
|
-
|
|
624
|
-
near-polar B{C{lat}}.
|
|
631
|
+
@return: Distance (C{meter}, same units as B{C{radius}} or polar and
|
|
632
|
+
equatorial radii) or C{0.0} for near-polar B{C{lat}}.
|
|
625
633
|
|
|
626
634
|
@raise RangeError: Latitude B{C{lat}} outside valid range and
|
|
627
635
|
L{rangerrors<pygeodesy.rangerrors>} is C{True}.
|
|
628
636
|
|
|
629
637
|
@raise TypeError: Invalid B{C{radius}}.
|
|
630
638
|
|
|
631
|
-
@raise ValueError: Invalid B{C{rad}}, B{C{radius}} or
|
|
632
|
-
B{C{lat}}.
|
|
639
|
+
@raise ValueError: Invalid B{C{rad}}, B{C{radius}} or B{C{lat}}.
|
|
633
640
|
|
|
634
641
|
@see: Function L{degrees2m} and L{m2radians}.
|
|
635
642
|
'''
|
|
@@ -832,41 +839,75 @@ def tan_2(rad, **semi): # edge=1
|
|
|
832
839
|
_SPACE_(_MODS.streprs.Fmt.SQUARE(**semi), _edge_)
|
|
833
840
|
raise _ValueError(n, rad, txt=_semi_circular_)
|
|
834
841
|
|
|
835
|
-
return
|
|
842
|
+
return _tan(rad * _0_5) if _isfinite(rad) else NAN
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
def tan(rad, **raiser_kwds):
|
|
846
|
+
'''Return the C{tangent} of an angle in C{radians}.
|
|
847
|
+
|
|
848
|
+
@arg rad: Angle (C{radians}).
|
|
849
|
+
@kwarg raiser_kwds: Use C{B{raiser}=False} to avoid
|
|
850
|
+
ValueErrors or optionally, additional
|
|
851
|
+
ValueError keyword argments.
|
|
852
|
+
|
|
853
|
+
@return: C{tan(B{rad})}.
|
|
854
|
+
|
|
855
|
+
@raise Error: If L{pygeodesy.isnear0}C{(cos(B{rad})}.
|
|
856
|
+
'''
|
|
857
|
+
try:
|
|
858
|
+
return _tanu(*sincos2(rad), **raiser_kwds)
|
|
859
|
+
except ZeroDivisionError:
|
|
860
|
+
raise _valueError(tan, rad, **raiser_kwds)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def tan_(*rads, **raiser_kwds):
|
|
864
|
+
'''Return the C{tangent} of angle(s) in C{radians}.
|
|
865
|
+
|
|
866
|
+
@arg rads: One or more angles (each in C{radians}).
|
|
867
|
+
|
|
868
|
+
@return: Yield the C{tan(B{rad})} for each angle.
|
|
869
|
+
|
|
870
|
+
@see: Function L{pygeodesy.tan} for futher details.
|
|
871
|
+
'''
|
|
872
|
+
try:
|
|
873
|
+
for r in rads:
|
|
874
|
+
yield _tanu(*sincos2(r), **raiser_kwds)
|
|
875
|
+
except ZeroDivisionError:
|
|
876
|
+
raise _valueError(tan_, r, **raiser_kwds)
|
|
836
877
|
|
|
837
878
|
|
|
838
|
-
def tand(deg, **
|
|
879
|
+
def tand(deg, **raiser_kwds):
|
|
839
880
|
'''Return the C{tangent} of an angle in C{degrees}.
|
|
840
881
|
|
|
841
882
|
@arg deg: Angle (C{degrees}).
|
|
842
|
-
@kwarg
|
|
883
|
+
@kwarg raiser_kwds: Use C{B{raiser}=False} to avoid
|
|
884
|
+
ValueErrors or optionally, additional
|
|
885
|
+
ValueError keyword argments.
|
|
843
886
|
|
|
844
887
|
@return: C{tan(B{deg})}.
|
|
845
888
|
|
|
846
|
-
@raise
|
|
889
|
+
@raise Error: If L{pygeodesy.isnear0}C{(cos(B{deg})}.
|
|
847
890
|
'''
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
s = s / c # /= chokes PyChecker
|
|
853
|
-
elif c < 0:
|
|
854
|
-
s = -s # negate-0
|
|
855
|
-
return s
|
|
891
|
+
try:
|
|
892
|
+
return _tanu(*sincos2d(deg), **raiser_kwds)
|
|
893
|
+
except ZeroDivisionError:
|
|
894
|
+
raise _valueError(tand, deg, **raiser_kwds)
|
|
856
895
|
|
|
857
896
|
|
|
858
|
-
def tand_(*degs, **
|
|
897
|
+
def tand_(*degs, **raiser_kwds):
|
|
859
898
|
'''Return the C{tangent} of angle(s) in C{degrees}.
|
|
860
899
|
|
|
861
|
-
@arg degs: One or more angles (C{degrees}).
|
|
862
|
-
@kwarg error_kwds: Error to raise (C{ValueError}).
|
|
900
|
+
@arg degs: One or more angles (each in C{degrees}).
|
|
863
901
|
|
|
864
902
|
@return: Yield the C{tan(B{deg})} for each angle.
|
|
865
903
|
|
|
866
|
-
@
|
|
904
|
+
@see: Function L{pygeodesy.tand} for futher details.
|
|
867
905
|
'''
|
|
868
|
-
|
|
869
|
-
|
|
906
|
+
try:
|
|
907
|
+
for d in degs:
|
|
908
|
+
yield _tanu(*sincos2d(d), **raiser_kwds)
|
|
909
|
+
except ZeroDivisionError:
|
|
910
|
+
raise _valueError(tand_, d, **raiser_kwds)
|
|
870
911
|
|
|
871
912
|
|
|
872
913
|
def tanPI_2_2(rad):
|
|
@@ -876,8 +917,20 @@ def tanPI_2_2(rad):
|
|
|
876
917
|
|
|
877
918
|
@return: M{tan((rad + PI/2) / 2)} (C{float}).
|
|
878
919
|
'''
|
|
879
|
-
return
|
|
880
|
-
|
|
920
|
+
return _tan((rad + PI_2) * _0_5) if _isfinite(rad) else (
|
|
921
|
+
NAN if isnan(rad) else _copysign(_90_0, rad))
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
def _tanu(s, c, raiser=True, **unused):
|
|
925
|
+
'''(INTERNAL) Helper for functions C{_cotu}, C{tan}, C{tan_}, C{tand} and C{tand_}.
|
|
926
|
+
'''
|
|
927
|
+
if s:
|
|
928
|
+
if raiser and isnear0(c):
|
|
929
|
+
raise ZeroDivisionError()
|
|
930
|
+
s = _over(s, c)
|
|
931
|
+
elif c < 0:
|
|
932
|
+
s = -s # negate-0
|
|
933
|
+
return s
|
|
881
934
|
|
|
882
935
|
|
|
883
936
|
def toise2m(toises):
|
|
@@ -980,11 +1033,11 @@ def unrollPI(rad1, rad2, wrap=True):
|
|
|
980
1033
|
return r, rad2
|
|
981
1034
|
|
|
982
1035
|
|
|
983
|
-
def _valueError(where, x, **kwds):
|
|
984
|
-
'''(INTERNAL) Return a C{_ValueError}.
|
|
1036
|
+
def _valueError(where, x, raiser=True, **kwds):
|
|
1037
|
+
'''(INTERNAL) Return a C{_ValueError} or C{None}.
|
|
985
1038
|
'''
|
|
986
1039
|
t = _MODS.streprs.Fmt.PAREN(where.__name__, x)
|
|
987
|
-
return _ValueError(t, **kwds)
|
|
1040
|
+
return _ValueError(t, **kwds) if raiser else None
|
|
988
1041
|
|
|
989
1042
|
|
|
990
1043
|
class _Wrap(object):
|
|
@@ -1100,8 +1153,7 @@ def wrap90(deg):
|
|
|
1100
1153
|
|
|
1101
1154
|
@return: Degrees, wrapped (C{degrees90}).
|
|
1102
1155
|
'''
|
|
1103
|
-
|
|
1104
|
-
return (w - _180_0) if w > 90 else ((w + _180_0) if w < -90 else w)
|
|
1156
|
+
return _wrapu(wrap180(deg), _180_0, _90_0)
|
|
1105
1157
|
|
|
1106
1158
|
|
|
1107
1159
|
def wrap180(deg):
|
|
@@ -1113,9 +1165,9 @@ def wrap180(deg):
|
|
|
1113
1165
|
'''
|
|
1114
1166
|
d = float(deg)
|
|
1115
1167
|
w = _umod_360(d)
|
|
1116
|
-
if w >
|
|
1168
|
+
if w > _180_0:
|
|
1117
1169
|
w -= _360_0
|
|
1118
|
-
elif d < 0 and w ==
|
|
1170
|
+
elif d < 0 and w == _180_0:
|
|
1119
1171
|
w = -w
|
|
1120
1172
|
return w
|
|
1121
1173
|
|
|
@@ -1163,8 +1215,7 @@ def wrapPI_2(rad):
|
|
|
1163
1215
|
|
|
1164
1216
|
@return: Radians, wrapped (C{radiansPI_2}).
|
|
1165
1217
|
'''
|
|
1166
|
-
|
|
1167
|
-
return (w - PI) if w > PI_2 else ((w + PI) if w < (-PI_2) else w)
|
|
1218
|
+
return _wrapu(wrapPI(rad), PI, PI_2)
|
|
1168
1219
|
|
|
1169
1220
|
|
|
1170
1221
|
# def wraplatlon(lat, lon):
|
|
@@ -1199,6 +1250,12 @@ def wrap_normal(*normal):
|
|
|
1199
1250
|
# return wrapPI_2(phi), wrapPI(lam)
|
|
1200
1251
|
|
|
1201
1252
|
|
|
1253
|
+
def _wrapu(w, H, Q):
|
|
1254
|
+
'''(INTERNAL) Helper for functions C{wrap180} and C{wrapPI}.
|
|
1255
|
+
'''
|
|
1256
|
+
return (w - H) if w > Q else ((w + H) if w < (-Q) else w)
|
|
1257
|
+
|
|
1258
|
+
|
|
1202
1259
|
def yard2m(yards):
|
|
1203
1260
|
'''Convert I{UK} yards to meter.
|
|
1204
1261
|
|
|
@@ -1212,7 +1269,7 @@ def yard2m(yards):
|
|
|
1212
1269
|
|
|
1213
1270
|
# **) MIT License
|
|
1214
1271
|
#
|
|
1215
|
-
# Copyright (C) 2016-
|
|
1272
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1216
1273
|
#
|
|
1217
1274
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1218
1275
|
# copy of this software and associated documentation files (the "Software"),
|