pygeodesy 25.1.9__py2.py3-none-any.whl → 25.4.25__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygeodesy/__init__.py +35 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +59 -40
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +9 -7
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +13 -13
- pygeodesy/auxilats/auxily.py +13 -9
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +65 -22
- pygeodesy/booleans.py +12 -10
- pygeodesy/cartesianBase.py +21 -20
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +10 -7
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +167 -138
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +9 -9
- pygeodesy/fmath.py +10 -9
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +107 -122
- pygeodesy/gars.py +7 -7
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +12 -10
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +7 -8
- pygeodesy/geoids.py +35 -34
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +31 -46
- pygeodesy/interns.py +12 -9
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +73 -66
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +14 -18
- pygeodesy/lazily.py +73 -74
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +8 -7
- pygeodesy/ltpTuples.py +2 -2
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +47 -31
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +11 -10
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +14 -14
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +88 -18
- pygeodesy/vector2d.py +18 -11
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +35 -31
- pygeodesy-25.4.25.dist-info/RECORD +118 -0
- pygeodesy-25.1.9.dist-info/RECORD +0 -118
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/elliptic.py
CHANGED
|
@@ -75,7 +75,7 @@ U{22<https://DLMF.NIST.gov/22>}.
|
|
|
75
75
|
# make sure int/int division yields float quotient, see .basics
|
|
76
76
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
77
77
|
|
|
78
|
-
from pygeodesy.basics import copysign0, map2, neg, neg_
|
|
78
|
+
from pygeodesy.basics import copysign0, map2, neg, neg_, typename
|
|
79
79
|
from pygeodesy.constants import EPS, INF, NAN, PI, PI_2, PI_4, _0_0, \
|
|
80
80
|
_0_25, _0_5, _1_0, _2_0, _N_2_0, _3_0, \
|
|
81
81
|
_4_0, _6_0, _8_0, _64_0, _180_0, _360_0, \
|
|
@@ -84,9 +84,9 @@ from pygeodesy.constants import EPS, INF, NAN, PI, PI_2, PI_4, _0_0, \
|
|
|
84
84
|
# from pygeodesy.errors import _ValueError # from .fmath
|
|
85
85
|
from pygeodesy.fmath import favg, hypot1, zqrt, _ValueError
|
|
86
86
|
from pygeodesy.fsums import Fsum, _sum
|
|
87
|
-
from pygeodesy.internals import
|
|
88
|
-
from pygeodesy.interns import NN, _delta_, _DOT_, _f_, _invalid_, \
|
|
89
|
-
|
|
87
|
+
# from pygeodesy.internals import typename # from .basics
|
|
88
|
+
from pygeodesy.interns import NN, _delta_, _DOT_, _f_, _invalid_, _invokation_, \
|
|
89
|
+
_negative_, _SPACE_
|
|
90
90
|
from pygeodesy.karney import _K_2_0, _norm180, _signBit, _sincos2
|
|
91
91
|
# from pygeodesy.lazily import _ALL_LAZY # from .named
|
|
92
92
|
from pygeodesy.named import _Named, _NamedTuple, _ALL_LAZY, Fmt, unstr
|
|
@@ -99,7 +99,7 @@ from math import asin, asinh, atan, ceil, cosh, fabs, floor, radians, \
|
|
|
99
99
|
sin, sinh, sqrt, tan, tanh # tan as _tan
|
|
100
100
|
|
|
101
101
|
__all__ = _ALL_LAZY.elliptic
|
|
102
|
-
__version__ = '
|
|
102
|
+
__version__ = '25.04.14'
|
|
103
103
|
|
|
104
104
|
_TolRD = zqrt(EPS * 0.002)
|
|
105
105
|
_TolRF = zqrt(EPS * 0.030)
|
|
@@ -678,7 +678,7 @@ class Elliptic(_Named):
|
|
|
678
678
|
return (deltaX(sn, cn, dn) + phi) * cX / PI_2
|
|
679
679
|
# fall through
|
|
680
680
|
elif cn is None or dn is None:
|
|
681
|
-
n = NN(_f_, deltaX
|
|
681
|
+
n = NN(_f_, typename(deltaX)[5:])
|
|
682
682
|
raise _ellipticError(n, sn, cn, dn)
|
|
683
683
|
|
|
684
684
|
if _signBit(cn): # enforce usual trig-like symmetries
|
|
@@ -1063,7 +1063,7 @@ def _deltaX(sn, cn, dn, cX, fX):
|
|
|
1063
1063
|
return r - atan2(sn, cn)
|
|
1064
1064
|
|
|
1065
1065
|
except Exception as e:
|
|
1066
|
-
n = NN(_delta_, fX
|
|
1066
|
+
n = NN(_delta_, typename(fX)[1:])
|
|
1067
1067
|
raise _ellipticError(n, sn, cn, dn, cause=e)
|
|
1068
1068
|
|
|
1069
1069
|
|
|
@@ -1075,8 +1075,8 @@ def _ellipticError(where, *args, **kwds_cause_txt):
|
|
|
1075
1075
|
|
|
1076
1076
|
x, t, kwds = _x_t_kwds(**kwds_cause_txt)
|
|
1077
1077
|
|
|
1078
|
-
n =
|
|
1079
|
-
n = _DOT_(Elliptic
|
|
1078
|
+
n = typename(where, where)
|
|
1079
|
+
n = _DOT_(typename(Elliptic), n)
|
|
1080
1080
|
n = _SPACE_(_invokation_, n)
|
|
1081
1081
|
u = unstr(n, *args, **kwds)
|
|
1082
1082
|
return EllipticError(u, cause=x, txt=t)
|
pygeodesy/errors.py
CHANGED
|
@@ -11,25 +11,26 @@ chaining}, use command line option C{python -X dev} I{OR} set env variable
|
|
|
11
11
|
C{PYTHONDEVMODE=1} or to any non-empty string I{OR} set env variable
|
|
12
12
|
C{PYGEODESY_EXCEPTION_CHAINING=std} or to any non-empty string.
|
|
13
13
|
'''
|
|
14
|
-
# from pygeodesy
|
|
14
|
+
# from pygeodesy import basics as _basics # _MODS.into
|
|
15
15
|
# from pygeodesy.ellipsoidalBase import CartesianEllipsoidalBase, LatLonEllipsoidalBase # _MODS
|
|
16
16
|
# from pygeodesy import errors # _MODS, _MODS.getattr
|
|
17
|
-
from pygeodesy.internals import
|
|
17
|
+
from pygeodesy.internals import _envPYGEODESY, _plural, _tailof, typename
|
|
18
18
|
from pygeodesy.interns import MISSING, NN, _a_, _an_, _and_, _clip_, _COLON_, _COLONSPACE_, \
|
|
19
19
|
_COMMASPACE_, _datum_, _ELLIPSIS_, _ellipsoidal_, _incompatible_, \
|
|
20
20
|
_invalid_, _keyword_, _LatLon_, _len_, _not_, _or_, _SPACE_, \
|
|
21
21
|
_specified_, _UNDER_, _vs_, _with_
|
|
22
22
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYTHON_X_DEV
|
|
23
|
-
# from pygeodesy import streprs as _streprs # _MODS
|
|
23
|
+
# from pygeodesy import streprs as _streprs # _MODS.into
|
|
24
24
|
# from pygeodesy.unitsBase import Str # _MODS
|
|
25
25
|
# from pygeodesy.vector3dBase import Vector3dBase # _MODS
|
|
26
26
|
|
|
27
27
|
from copy import copy as _copy
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.errors # _ALL_DOCS('_InvalidError', '_IsnotError') _under
|
|
30
|
-
__version__ = '
|
|
30
|
+
__version__ = '25.04.21'
|
|
31
31
|
|
|
32
32
|
_argument_ = 'argument'
|
|
33
|
+
_basics = _MODS.into(basics=__name__)
|
|
33
34
|
_box_ = 'box'
|
|
34
35
|
_expected_ = 'expected'
|
|
35
36
|
_limiterrors = True # in .formy
|
|
@@ -43,7 +44,7 @@ try:
|
|
|
43
44
|
_exception_chaining = None # not available
|
|
44
45
|
_ = Exception().__cause__ # Python 3.9+ exception chaining
|
|
45
46
|
|
|
46
|
-
if _PYTHON_X_DEV or
|
|
47
|
+
if _PYTHON_X_DEV or _envPYGEODESY('EXCEPTION_CHAINING'): # == _std_
|
|
47
48
|
_exception_chaining = True # turned on, std
|
|
48
49
|
raise AttributeError() # allow exception chaining
|
|
49
50
|
|
|
@@ -143,8 +144,8 @@ def _TypesError(name, value, *Types, **kwds):
|
|
|
143
144
|
'''
|
|
144
145
|
# no longer C{class _TypesError} to avoid missing value
|
|
145
146
|
# argument errors in _XError line ...E = Error(str(e))
|
|
146
|
-
t =
|
|
147
|
-
return _TypeError(name, value, txt=t, **kwds)
|
|
147
|
+
t = _an(_or(*map(typename, Types, Types)))
|
|
148
|
+
return _TypeError(name, value, txt=_not_(t), **kwds)
|
|
148
149
|
|
|
149
150
|
|
|
150
151
|
class _UnexpectedError(TypeError): # note, a TypeError!
|
|
@@ -240,12 +241,12 @@ class LenError(_ValueError): # in .ecef, .fmath, .heights, .iters, .named
|
|
|
240
241
|
(C{keyword arguments}).
|
|
241
242
|
'''
|
|
242
243
|
def _ns_vs_txt_x(cause=None, txt=_invalid_, **kwds):
|
|
243
|
-
ns, vs = zip(*
|
|
244
|
+
ns, vs = zip(*_basics.itemsorted(kwds)) # unzip
|
|
244
245
|
return ns, vs, txt, cause
|
|
245
246
|
|
|
246
247
|
ns, vs, txt, x = _ns_vs_txt_x(**lens_txt)
|
|
247
248
|
ns = _COMMASPACE_.join(ns)
|
|
248
|
-
t = _streprs.Fmt.PAREN(where
|
|
249
|
+
t = _streprs.Fmt.PAREN(typename(where), ns)
|
|
249
250
|
vs = _vs__.join(map(str, vs))
|
|
250
251
|
t = _SPACE_(t, _len_, vs)
|
|
251
252
|
_ValueError.__init__(self, t, txt=txt, cause=x)
|
|
@@ -379,8 +380,8 @@ def _and_or(last, *words):
|
|
|
379
380
|
def crosserrors(raiser=None):
|
|
380
381
|
'''Report or ignore vectorial cross product errors.
|
|
381
382
|
|
|
382
|
-
@kwarg raiser: Use C{True} to throw
|
|
383
|
-
L{CrossError} exceptions
|
|
383
|
+
@kwarg raiser: Use C{True} to throw, C{False} to ignore
|
|
384
|
+
L{CrossError} exceptions or C{None} to
|
|
384
385
|
leave the setting unchanged.
|
|
385
386
|
|
|
386
387
|
@return: Previous setting (C{bool}).
|
|
@@ -389,8 +390,8 @@ def crosserrors(raiser=None):
|
|
|
389
390
|
'''
|
|
390
391
|
V = _MODS.vector3dBase.Vector3dBase
|
|
391
392
|
t = V._crosserrors # XXX class attr!
|
|
392
|
-
if raiser
|
|
393
|
-
V._crosserrors = raiser
|
|
393
|
+
if raiser is not None:
|
|
394
|
+
V._crosserrors = bool(raiser)
|
|
394
395
|
return t
|
|
395
396
|
|
|
396
397
|
|
|
@@ -419,7 +420,7 @@ def _error_init(Error, inst, args, fmt_name_value='%s (%r)', txt_not_=NN,
|
|
|
419
420
|
t, n = (), len(args)
|
|
420
421
|
if n > 2:
|
|
421
422
|
t = _fmtuple(zip(args[0::2], args[1::2]))
|
|
422
|
-
s =
|
|
423
|
+
s = _basics.isodd(n)
|
|
423
424
|
if s: # XXX _xzip(..., strict=s)
|
|
424
425
|
t += args[-1:]
|
|
425
426
|
elif n == 2:
|
|
@@ -427,11 +428,11 @@ def _error_init(Error, inst, args, fmt_name_value='%s (%r)', txt_not_=NN,
|
|
|
427
428
|
elif n: # == 1
|
|
428
429
|
t = str(args[0]),
|
|
429
430
|
if kwds:
|
|
430
|
-
t += _fmtuple(
|
|
431
|
+
t += _fmtuple(_basics.itemsorted(kwds))
|
|
431
432
|
t = _or(*t) if t else _SPACE_(_name_value_, MISSING)
|
|
432
433
|
|
|
433
434
|
x = _not_(txt_not_) if txt_not_ else (txt if txt__ is None
|
|
434
|
-
else
|
|
435
|
+
else typename(txt__))
|
|
435
436
|
if x is not None:
|
|
436
437
|
x = str(x) or (str(cause) if cause else _invalid_)
|
|
437
438
|
C = _COMMASPACE_ if _COLON_ in t else _COLONSPACE_
|
|
@@ -447,9 +448,10 @@ def _error_init(Error, inst, args, fmt_name_value='%s (%r)', txt_not_=NN,
|
|
|
447
448
|
def _error_under(inst):
|
|
448
449
|
'''(INTERNAL) Remove leading underscore from instance' class name.
|
|
449
450
|
'''
|
|
450
|
-
|
|
451
|
+
t = type(inst)
|
|
452
|
+
n = typename(t) # _tailof?
|
|
451
453
|
if n.startswith(_UNDER_):
|
|
452
|
-
|
|
454
|
+
t.__name__ = n.lstrip(_UNDER_)
|
|
453
455
|
return inst
|
|
454
456
|
|
|
455
457
|
|
|
@@ -469,7 +471,7 @@ def exception_chaining(exc=None):
|
|
|
469
471
|
non-empty value prior to C{import pygeodesy}.
|
|
470
472
|
'''
|
|
471
473
|
return _exception_chaining if exc is None else \
|
|
472
|
-
getattr(exc, '__cause__', None)
|
|
474
|
+
getattr(exc, '__cause__', None) # _DCAUSE_
|
|
473
475
|
|
|
474
476
|
|
|
475
477
|
def _incompatible(this):
|
|
@@ -504,9 +506,9 @@ def isError(exc):
|
|
|
504
506
|
def _X(exc):
|
|
505
507
|
X = type(exc)
|
|
506
508
|
m = X.__module__
|
|
507
|
-
return
|
|
509
|
+
return _basics.issubclassof(X, *_XErrors) or \
|
|
508
510
|
((m is __name__ or m == __name__) and
|
|
509
|
-
_tailof(X
|
|
511
|
+
_tailof(typename(X)).startswith(_UNDER_))
|
|
510
512
|
|
|
511
513
|
return True if isinstance(exc, _XErrors) else (
|
|
512
514
|
_X(exc) if isinstance(exc, Exception) else None)
|
|
@@ -527,23 +529,23 @@ def _IsnotError(*types__, **name_value_Error_cause): # name=value [, Error=Type
|
|
|
527
529
|
n, v = _xkwds_item2(kwds)
|
|
528
530
|
|
|
529
531
|
n = _streprs.Fmt.PARENSPACED(n, repr(v))
|
|
530
|
-
t =
|
|
531
|
-
return _XError(E, n, txt=t, cause=x)
|
|
532
|
+
t = _an(_or(*map(typename, types__, types__))) if types__ else _specified_
|
|
533
|
+
return _XError(E, n, txt=_not_(t), cause=x)
|
|
532
534
|
|
|
533
535
|
|
|
534
536
|
def limiterrors(raiser=None):
|
|
535
537
|
'''Get/set the throwing of L{LimitError}s.
|
|
536
538
|
|
|
537
|
-
@kwarg raiser:
|
|
538
|
-
ignore L{LimitError} exceptions
|
|
539
|
+
@kwarg raiser: Use C{True} to raise, C{False} to
|
|
540
|
+
ignore L{LimitError} exceptions or
|
|
539
541
|
C{None} to leave the setting unchanged.
|
|
540
542
|
|
|
541
543
|
@return: Previous setting (C{bool}).
|
|
542
544
|
'''
|
|
543
545
|
global _limiterrors
|
|
544
546
|
t = _limiterrors
|
|
545
|
-
if raiser
|
|
546
|
-
_limiterrors = raiser
|
|
547
|
+
if raiser is not None:
|
|
548
|
+
_limiterrors = bool(raiser)
|
|
547
549
|
return t
|
|
548
550
|
|
|
549
551
|
|
|
@@ -576,16 +578,16 @@ def _parseX(parser, *args, **Error_name_values): # name=value[, ..., Error=Pars
|
|
|
576
578
|
def rangerrors(raiser=None):
|
|
577
579
|
'''Get/set the throwing of L{RangeError}s.
|
|
578
580
|
|
|
579
|
-
@kwarg raiser:
|
|
580
|
-
L{RangeError} exceptions
|
|
581
|
+
@kwarg raiser: Use C{True} to raise or C{False} to ignore
|
|
582
|
+
L{RangeError} exceptions or C{None} to leave
|
|
581
583
|
the setting unchanged.
|
|
582
584
|
|
|
583
585
|
@return: Previous setting (C{bool}).
|
|
584
586
|
'''
|
|
585
587
|
global _rangerrors
|
|
586
588
|
t = _rangerrors
|
|
587
|
-
if raiser
|
|
588
|
-
_rangerrors = raiser
|
|
589
|
+
if raiser is not None:
|
|
590
|
+
_rangerrors = bool(raiser)
|
|
589
591
|
return t
|
|
590
592
|
|
|
591
593
|
|
|
@@ -648,7 +650,7 @@ def _xcallable(**names_callables):
|
|
|
648
650
|
'''
|
|
649
651
|
for n, c in names_callables.items():
|
|
650
652
|
if not callable(c):
|
|
651
|
-
raise _TypeError(n, c, txt_not_=callable
|
|
653
|
+
raise _TypeError(n, c, txt_not_=typename(callable)) # txt__
|
|
652
654
|
|
|
653
655
|
|
|
654
656
|
def _xdatum(datum1, datum2, Error=None):
|
|
@@ -685,9 +687,8 @@ def _xellipsoidall(point): # ... elel, see _xellipsoidal
|
|
|
685
687
|
m = _MODS.ellipsoidalBase
|
|
686
688
|
ll = isinstance(point, m.LatLonEllipsoidalBase)
|
|
687
689
|
if not ll:
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
m.LatLonEllipsoidalBase, point=point)
|
|
690
|
+
_basics._xinstanceof(m.CartesianEllipsoidalBase,
|
|
691
|
+
m.LatLonEllipsoidalBase, point=point)
|
|
691
692
|
return ll
|
|
692
693
|
|
|
693
694
|
|
|
@@ -734,7 +735,7 @@ def _xError2(exc): # in .constants, .fsums, .lazily, .vector2d
|
|
|
734
735
|
elif x is None:
|
|
735
736
|
E = _AssertionError
|
|
736
737
|
else: # get _Error from Error
|
|
737
|
-
n = NN(_UNDER_, _tailof(type(exc)
|
|
738
|
+
n = NN(_UNDER_, _tailof(typename(type(exc))))
|
|
738
739
|
E = _MODS.getattr(__name__, n, _NotImplementedError)
|
|
739
740
|
x = E is not _NotImplementedError
|
|
740
741
|
return E, (str(exc) if x else repr(exc))
|
|
@@ -783,9 +784,9 @@ except AttributeError:
|
|
|
783
784
|
# for n, v in kwds.items():
|
|
784
785
|
# b = getattr(inst, n, None)
|
|
785
786
|
# if b is None: # invalid bool attr
|
|
786
|
-
# t = _SPACE_(_EQUAL_(n, repr(v)), 'for', inst
|
|
787
|
+
# t = _SPACE_(_EQUAL_(n, repr(v)), 'for', typename(type(inst)) # XXX .classname
|
|
787
788
|
# raise _AttributeError(t, txt_not_='applicable')
|
|
788
|
-
# if v
|
|
789
|
+
# if _basics.isbool(v) and v != b:
|
|
789
790
|
# setattr(inst, NN(_UNDER_, n), v)
|
|
790
791
|
|
|
791
792
|
|
|
@@ -819,7 +820,7 @@ def _xkwds_get(kwds, **name_default):
|
|
|
819
820
|
# '''
|
|
820
821
|
# if not isinstance(kwds, dict):
|
|
821
822
|
# raise _xAssertionError(_xkwds_get_, kwds)
|
|
822
|
-
# for n, v in
|
|
823
|
+
# for n, v in _basics.itemsorted(names_defaults):
|
|
823
824
|
# yield kwds.get(n, v)
|
|
824
825
|
|
|
825
826
|
|
|
@@ -886,7 +887,7 @@ def _Xorder(_Coeffs, Error, **Xorder): # in .auxLat, .ktm, .rhumb.bases, .rhumb
|
|
|
886
887
|
'''(INTERNAL) Validate C{RAorder} or C{TMorder}.
|
|
887
888
|
'''
|
|
888
889
|
X, m = _xkwds_item2(Xorder)
|
|
889
|
-
if m in _Coeffs and
|
|
890
|
+
if m in _Coeffs and _basics.isint(m):
|
|
890
891
|
return m
|
|
891
892
|
t = sorted(map(str, _Coeffs.keys()))
|
|
892
893
|
raise Error(X, m, txt_not_=_or(*t))
|
|
@@ -908,9 +909,9 @@ def _xsError(X, xs, i, x, *n, **kwds): # in .fmath, ._fstats, .fsums
|
|
|
908
909
|
def _xStrError(*Refs, **name_value_Error): # in .gars, .geohash, .wgrs
|
|
909
910
|
'''(INTERNAL) Create a C{TypeError} for C{Garef}, C{Geohash}, C{Wgrs}.
|
|
910
911
|
'''
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
return _IsnotError(*
|
|
912
|
+
s = typename(_MODS.unitsBase.Str)
|
|
913
|
+
t = tuple(map(typename, Refs)) + (s, _LatLon_, 'LatLon*Tuple')
|
|
914
|
+
return _IsnotError(*t, **name_value_Error)
|
|
914
915
|
|
|
915
916
|
# **) MIT License
|
|
916
917
|
#
|
pygeodesy/etm.py
CHANGED
|
@@ -63,7 +63,7 @@ which maintains accuracy near C{phi = pi/2}. Such changes are noted in the code
|
|
|
63
63
|
# make sure int/int division yields float quotient, see .basics
|
|
64
64
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
65
65
|
|
|
66
|
-
from pygeodesy.basics import map1, neg, neg_, _xinstanceof
|
|
66
|
+
from pygeodesy.basics import _isin, map1, neg, neg_, _xinstanceof
|
|
67
67
|
from pygeodesy.constants import EPS, EPS02, PI_2, PI_4, _K0_UTM, \
|
|
68
68
|
_1_EPS, _0_0, _0_1, _0_5, _1_0, _2_0, \
|
|
69
69
|
_3_0, _90_0, isnear0, isnear90
|
|
@@ -74,9 +74,9 @@ from pygeodesy.datums import _ellipsoidal_datum, _WGS84, _EWGS84
|
|
|
74
74
|
# from pygeodesy.errors import _incompatible # from .named
|
|
75
75
|
# from pygeodesy.fsums import Fsum # from .fmath
|
|
76
76
|
from pygeodesy.fmath import cbrt, hypot, hypot1, hypot2, Fsum
|
|
77
|
-
from pygeodesy.interns import _COMMASPACE_, _near_, _SPACE_, _spherical_
|
|
78
|
-
from pygeodesy.karney import _K_2_4, _copyBit, _diff182, _fix90, \
|
|
79
|
-
|
|
77
|
+
from pygeodesy.interns import _COMMASPACE_, _DMAIN_, _near_, _SPACE_, _spherical_
|
|
78
|
+
from pygeodesy.karney import _K_2_4, _copyBit, _diff182, _fix90, _norm2, \
|
|
79
|
+
_norm180, _tand, _unsigned2
|
|
80
80
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
|
|
81
81
|
from pygeodesy.named import callername, _incompatible, _NamedBase, \
|
|
82
82
|
_ALL_LAZY, _MODS
|
|
@@ -93,7 +93,7 @@ from pygeodesy.utm import _cmlon, _LLEB, _parseUTM5, _toBand, _toXtm8, \
|
|
|
93
93
|
from math import asinh, degrees, radians, sinh, sqrt
|
|
94
94
|
|
|
95
95
|
__all__ = _ALL_LAZY.etm
|
|
96
|
-
__version__ = '
|
|
96
|
+
__version__ = '25.04.14'
|
|
97
97
|
|
|
98
98
|
_OVERFLOW = _1_EPS**2 # ~2e+31
|
|
99
99
|
_TAYTOL = pow(EPS, 0.6)
|
|
@@ -196,7 +196,7 @@ class Etm(Utm):
|
|
|
196
196
|
def _toLLEB(self, unfalse=True, **unused): # PYCHOK signature
|
|
197
197
|
'''(INTERNAL) Compute (ellipsoidal) lat- and longitude.
|
|
198
198
|
'''
|
|
199
|
-
|
|
199
|
+
d, xTM = self.datum, self.exactTM
|
|
200
200
|
# double check that this and exactTM's ellipsoid match
|
|
201
201
|
if xTM._E != d.ellipsoid: # PYCHOK no cover
|
|
202
202
|
t = repr(d.ellipsoid)
|
|
@@ -268,7 +268,7 @@ class ExactTransverseMercator(_NamedBase):
|
|
|
268
268
|
self.raiser = True
|
|
269
269
|
|
|
270
270
|
TM = ExactTransverseMercator
|
|
271
|
-
if datum
|
|
271
|
+
if not _isin(datum, None, TM._datum, TM._E):
|
|
272
272
|
self.datum = datum # invokes ._resets
|
|
273
273
|
if lon0 or lon0 != TM._lon0:
|
|
274
274
|
self.lon0 = lon0
|
|
@@ -1022,7 +1022,7 @@ class ExactTransverseMercator(_NamedBase):
|
|
|
1022
1022
|
g_k += atan1d(tau), degrees(lam)
|
|
1023
1023
|
return g_k # or (g, k, lat, lon)
|
|
1024
1024
|
|
|
1025
|
-
_allPropertiesOf_n(22, ExactTransverseMercator, Property_RO) # PYCHOK assert
|
|
1025
|
+
_allPropertiesOf_n(22, ExactTransverseMercator, Property_RO) # PYCHOK assert _ROs = ...
|
|
1026
1026
|
del _0_1, _allPropertiesOf_n, EPS, _1_EPS, _EWGS84
|
|
1027
1027
|
|
|
1028
1028
|
|
|
@@ -1101,7 +1101,7 @@ def toEtm8(latlon, lon=None, datum=None, Etm=Etm, falsed=True,
|
|
|
1101
1101
|
n, latlon, d.exactTM, Error=ETMError)
|
|
1102
1102
|
|
|
1103
1103
|
|
|
1104
|
-
if __name__ ==
|
|
1104
|
+
if __name__ == _DMAIN_: # MCCABE 16
|
|
1105
1105
|
|
|
1106
1106
|
def _main():
|
|
1107
1107
|
|
pygeodesy/fmath.py
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
u'''Utilities
|
|
4
|
+
u'''Utilities for precision floating point summation, multiplication,
|
|
5
|
+
C{fused-multiply-add}, polynomials, roots, etc.
|
|
5
6
|
'''
|
|
6
7
|
# make sure int/int division yields float quotient, see .basics
|
|
7
8
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
8
9
|
|
|
9
10
|
from pygeodesy.basics import _copysign, copysign0, isbool, isint, isscalar, \
|
|
10
|
-
len2, map1, _xiterable
|
|
11
|
+
len2, map1, _xiterable, typename
|
|
11
12
|
from pygeodesy.constants import EPS0, EPS02, EPS1, NAN, PI, PI_2, PI_4, \
|
|
12
13
|
_0_0, _0_125, _1_6th, _0_25, _1_3rd, _0_5, _1_0, \
|
|
13
14
|
_1_5, _copysign_0_0, isfinite, remainder
|
|
14
15
|
from pygeodesy.errors import _IsnotError, LenError, _TypeError, _ValueError, \
|
|
15
16
|
_xError, _xkwds, _xkwds_pop2, _xsError
|
|
16
17
|
from pygeodesy.fsums import _2float, Fsum, fsum, _isFsum_2Tuple, Fmt, unstr
|
|
18
|
+
# from pygeodesy.internals import typename # from .basics
|
|
17
19
|
from pygeodesy.interns import MISSING, _negative_, _not_scalar_
|
|
18
20
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
19
21
|
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
@@ -23,10 +25,10 @@ from math import fabs, sqrt # pow
|
|
|
23
25
|
import operator as _operator # in .datums, .trf, .utm
|
|
24
26
|
|
|
25
27
|
__all__ = _ALL_LAZY.fmath
|
|
26
|
-
__version__ = '25.
|
|
28
|
+
__version__ = '25.04.18'
|
|
27
29
|
|
|
28
30
|
# sqrt(2) - 1 <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
29
|
-
_0_4142 = 0.41421356237309504880 #
|
|
31
|
+
_0_4142 = 0.41421356237309504880 # ~ 3_730_904_090_310_553 / 9_007_199_254_740_992
|
|
30
32
|
_2_3rd = _1_3rd * 2
|
|
31
33
|
_h_lt_b_ = 'abs(h) < abs(b)'
|
|
32
34
|
|
|
@@ -294,9 +296,8 @@ def euclid(x, y):
|
|
|
294
296
|
@see: Function L{euclid_}.
|
|
295
297
|
'''
|
|
296
298
|
x, y = abs(x), abs(y) # NOT fabs!
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return x + y * _0_4142 # * _0_5 before 20.10.02
|
|
299
|
+
return (x + y * _0_4142) if x > y else \
|
|
300
|
+
(y + x * _0_4142) # * _0_5 before 20.10.02
|
|
300
301
|
|
|
301
302
|
|
|
302
303
|
def euclid_(*xs):
|
|
@@ -656,7 +657,7 @@ def fpowers(x, n, alts=0):
|
|
|
656
657
|
@raise ValueError: Non-finite B{C{x}} or invalid B{C{n}}.
|
|
657
658
|
'''
|
|
658
659
|
if not isint(n):
|
|
659
|
-
raise _IsnotError(int
|
|
660
|
+
raise _IsnotError(typename(int), n=n)
|
|
660
661
|
elif n < 1:
|
|
661
662
|
raise _ValueError(n=n)
|
|
662
663
|
|
|
@@ -736,7 +737,7 @@ def frange(start, number, step=1):
|
|
|
736
737
|
numpy/reference/generated/numpy.arange.html>}.
|
|
737
738
|
'''
|
|
738
739
|
if not isint(number):
|
|
739
|
-
raise _IsnotError(int
|
|
740
|
+
raise _IsnotError(typename(int), number=number)
|
|
740
741
|
for i in range(number):
|
|
741
742
|
yield start + (step * i)
|
|
742
743
|
|
pygeodesy/formy.py
CHANGED
|
@@ -6,25 +6,24 @@ u'''Formulary of basic geodesy functions and approximations.
|
|
|
6
6
|
# make sure int/int division yields float quotient, see .basics
|
|
7
7
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
from pygeodesy.basics import _copysign, _isin # _args_kwds_count2
|
|
10
10
|
# from pygeodesy.cartesianBase import CartesianBase # _MODS
|
|
11
11
|
from pygeodesy.constants import EPS, EPS0, EPS1, PI, PI2, PI3, PI_2, R_M, \
|
|
12
12
|
_0_0s, float0_, isnon0, remainder, _umod_PI2, \
|
|
13
13
|
_0_0, _0_125, _0_25, _0_5, _1_0, _2_0, _4_0, \
|
|
14
|
-
_90_0, _180_0, _360_0
|
|
14
|
+
_90_0, _180_0, _360_0
|
|
15
15
|
from pygeodesy.datums import Datum, Ellipsoid, _ellipsoidal_datum, \
|
|
16
16
|
_mean_radius, _spherical_datum, _WGS84, _EWGS84
|
|
17
17
|
# from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # from .datums
|
|
18
18
|
from pygeodesy.errors import IntersectionError, LimitError, limiterrors, \
|
|
19
19
|
_TypeError, _ValueError, _xattr, _xError, \
|
|
20
|
-
_xcallable,_xkwds, _xkwds_pop2
|
|
20
|
+
_xcallable, _xkwds, _xkwds_pop2
|
|
21
21
|
from pygeodesy.fmath import euclid, fdot_, fprod, hypot, hypot2, sqrt0
|
|
22
22
|
from pygeodesy.fsums import fsumf_, Fmt, unstr
|
|
23
|
-
# from pygeodesy.internals import
|
|
23
|
+
# from pygeodesy.internals import typename # from .named
|
|
24
24
|
from pygeodesy.interns import _delta_, _distant_, _inside_, _SPACE_, _too_
|
|
25
25
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
26
|
-
from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed,
|
|
27
|
-
_DUNDER_nameof
|
|
26
|
+
from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed, typename
|
|
28
27
|
from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
|
|
29
28
|
Intersection3Tuple, PhiLam2Tuple
|
|
30
29
|
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
@@ -43,7 +42,7 @@ from contextlib import contextmanager
|
|
|
43
42
|
from math import atan, cos, degrees, fabs, radians, sin, sqrt # pow
|
|
44
43
|
|
|
45
44
|
__all__ = _ALL_LAZY.formy
|
|
46
|
-
__version__ = '25.
|
|
45
|
+
__version__ = '25.04.14'
|
|
47
46
|
|
|
48
47
|
_RADIANS2 = radians(_1_0)**2 # degree to radians-squared
|
|
49
48
|
_ratio_ = 'ratio'
|
|
@@ -371,9 +370,9 @@ def _dS(fun_, radius, wrap, *lls, **adjust):
|
|
|
371
370
|
def _ellipsoidal(earth, where):
|
|
372
371
|
'''(INTERNAL) Helper for distances.
|
|
373
372
|
'''
|
|
374
|
-
return _EWGS84 if earth
|
|
375
|
-
earth if
|
|
376
|
-
(earth if
|
|
373
|
+
return _EWGS84 if _isin(earth, _EWGS84, _WGS84) else (
|
|
374
|
+
earth if isinstance(earth, Ellipsoid) else
|
|
375
|
+
(earth if isinstance(earth, Datum) else # PYCHOK indent
|
|
377
376
|
_ellipsoidal_datum(earth, name__=where)).ellipsoid)
|
|
378
377
|
|
|
379
378
|
|
|
@@ -1077,8 +1076,8 @@ class _idllmn6(object): # see also .geodesicw._wargs, .latlonBase._toCartesian3
|
|
|
1077
1076
|
if wrap:
|
|
1078
1077
|
_, lat2, lon2 = _Wrap.latlon3(lon1, lat2, lon2, wrap)
|
|
1079
1078
|
kwds = _xkwds(kwds, wrap=wrap) # for _xError
|
|
1080
|
-
m =
|
|
1081
|
-
n =
|
|
1079
|
+
m = small if small is _100km else Meter_(small=small)
|
|
1080
|
+
n = typename(intersections2 if s else intersection2)
|
|
1082
1081
|
if datum is None or euclidean(lat1, lon1, lat2, lon2) < m:
|
|
1083
1082
|
d, m = None, _MODS.vector3d
|
|
1084
1083
|
_i = m._intersects2 if s else m._intersect3d3
|