pygeodesy 24.10.10__py2.py3-none-any.whl → 24.11.11__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.10.dist-info → PyGeodesy-24.11.11.dist-info}/METADATA +12 -12
- PyGeodesy-24.11.11.dist-info/RECORD +118 -0
- {PyGeodesy-24.10.10.dist-info → PyGeodesy-24.11.11.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +14 -14
- pygeodesy/__main__.py +5 -5
- pygeodesy/albers.py +12 -17
- pygeodesy/azimuthal.py +51 -61
- pygeodesy/basics.py +60 -62
- pygeodesy/booleans.py +87 -79
- pygeodesy/cartesianBase.py +6 -6
- pygeodesy/constants.py +23 -19
- pygeodesy/css.py +7 -8
- pygeodesy/datums.py +3 -3
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +9 -9
- pygeodesy/deprecated/functions.py +6 -6
- pygeodesy/dms.py +250 -270
- pygeodesy/ecef.py +11 -14
- pygeodesy/ellipsoidalBase.py +106 -121
- pygeodesy/ellipsoidalBaseDI.py +114 -118
- pygeodesy/ellipsoidalExact.py +35 -37
- pygeodesy/ellipsoidalNvector.py +4 -4
- pygeodesy/ellipsoidalVincenty.py +2 -2
- pygeodesy/ellipsoids.py +10 -51
- pygeodesy/elliptic.py +14 -14
- pygeodesy/errors.py +28 -28
- pygeodesy/etm.py +92 -68
- pygeodesy/fmath.py +42 -40
- pygeodesy/formy.py +7 -6
- pygeodesy/fsums.py +72 -51
- pygeodesy/geodesici.py +43 -40
- pygeodesy/geodesicw.py +17 -16
- pygeodesy/geodesicx/__init__.py +2 -2
- pygeodesy/geodesicx/gxarea.py +3 -2
- pygeodesy/geodsolve.py +79 -39
- pygeodesy/geohash.py +2 -2
- pygeodesy/geoids.py +32 -31
- pygeodesy/heights.py +2 -2
- pygeodesy/internals.py +201 -147
- pygeodesy/interns.py +23 -20
- pygeodesy/karney.py +62 -13
- pygeodesy/ktm.py +11 -13
- pygeodesy/latlonBase.py +18 -20
- pygeodesy/lazily.py +210 -218
- pygeodesy/lcc.py +4 -4
- pygeodesy/ltp.py +10 -10
- pygeodesy/ltpTuples.py +74 -75
- pygeodesy/mgrs.py +20 -21
- pygeodesy/named.py +15 -10
- pygeodesy/nvectorBase.py +1 -1
- pygeodesy/osgr.py +9 -12
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +35 -14
- pygeodesy/resections.py +9 -10
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/bases.py +5 -5
- pygeodesy/rhumb/solve.py +9 -10
- pygeodesy/simplify.py +5 -5
- pygeodesy/solveBase.py +7 -25
- pygeodesy/sphericalBase.py +20 -23
- pygeodesy/sphericalNvector.py +103 -145
- pygeodesy/sphericalTrigonometry.py +68 -73
- pygeodesy/streprs.py +5 -5
- pygeodesy/trf.py +6 -4
- pygeodesy/triaxials.py +46 -9
- pygeodesy/units.py +5 -4
- pygeodesy/ups.py +6 -6
- pygeodesy/utily.py +2 -2
- pygeodesy/utm.py +7 -7
- pygeodesy/vector2d.py +13 -13
- pygeodesy/vector3d.py +19 -21
- pygeodesy/vector3dBase.py +21 -19
- pygeodesy/webmercator.py +4 -4
- pygeodesy/wgrs.py +4 -4
- PyGeodesy-24.10.10.dist-info/RECORD +0 -118
- {PyGeodesy-24.10.10.dist-info → PyGeodesy-24.11.11.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -48,12 +48,12 @@ from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
|
|
|
48
48
|
_ValueError, _xError, _xError2, _xkwds, \
|
|
49
49
|
_xkwds_get, _xkwds_get1, _xkwds_not, \
|
|
50
50
|
_xkwds_pop, _xsError
|
|
51
|
-
from pygeodesy.internals import _enquote, _passarg
|
|
51
|
+
from pygeodesy.internals import _enquote, _getPYGEODESY, _MODS, _passarg
|
|
52
52
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DOT_, _from_, \
|
|
53
53
|
_not_finite_, _SPACE_, _std_, _UNDER_
|
|
54
|
-
from pygeodesy.lazily import _ALL_LAZY
|
|
54
|
+
# from pygeodesy.lazily import _ALL_LAZY # from .named
|
|
55
55
|
from pygeodesy.named import _name__, _name2__, _Named, _NamedTuple, \
|
|
56
|
-
_NotImplemented
|
|
56
|
+
_NotImplemented, _ALL_LAZY
|
|
57
57
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_method, \
|
|
58
58
|
deprecated_property_RO, Property, \
|
|
59
59
|
Property_RO, property_RO
|
|
@@ -64,7 +64,7 @@ from math import fabs, isinf, isnan, \
|
|
|
64
64
|
ceil as _ceil, floor as _floor # PYCHOK used! .ltp
|
|
65
65
|
|
|
66
66
|
__all__ = _ALL_LAZY.fsums
|
|
67
|
-
__version__ = '24.
|
|
67
|
+
__version__ = '24.11.11'
|
|
68
68
|
|
|
69
69
|
from pygeodesy.interns import (
|
|
70
70
|
_PLUS_ as _add_op_, # in .auxilats.auxAngle
|
|
@@ -79,15 +79,15 @@ from pygeodesy.interns import (
|
|
|
79
79
|
)
|
|
80
80
|
_floordiv_op_ = _truediv_op_ * 2 # _DSLASH_
|
|
81
81
|
_divmod_op_ = _floordiv_op_ + _mod_op_
|
|
82
|
-
_F2PRODUCT =
|
|
82
|
+
_F2PRODUCT = _getPYGEODESY('FSUM_F2PRODUCT')
|
|
83
83
|
_iadd_op_ = _add_op_ + _fset_op_ # in .auxilats.auxAngle, .fstats
|
|
84
84
|
_integer_ = 'integer'
|
|
85
85
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
86
86
|
_NONFINITEr = _0_0 # NOT INT0!
|
|
87
|
-
_NONFINITES =
|
|
87
|
+
_NONFINITES = _getPYGEODESY('FSUM_NONFINITES')
|
|
88
88
|
_non_zero_ = 'non-zero'
|
|
89
89
|
_pow_op_ = _mul_op_ * 2 # _DSTAR_
|
|
90
|
-
_RESIDUAL_0_0 =
|
|
90
|
+
_RESIDUAL_0_0 = _getPYGEODESY('FSUM_RESIDUAL', _0_0)
|
|
91
91
|
_significant_ = 'significant'
|
|
92
92
|
_threshold_ = 'threshold'
|
|
93
93
|
|
|
@@ -163,9 +163,11 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
163
163
|
|
|
164
164
|
_2n_d = None # redef
|
|
165
165
|
|
|
166
|
-
def _fmaX(r, *a_b_c): #
|
|
167
|
-
#
|
|
168
|
-
#
|
|
166
|
+
def _fmaX(r, *a_b_c): # PYCHOK no cover
|
|
167
|
+
# handle non-finite as Python 3.13+ C-function U{math_fma_impl<https://
|
|
168
|
+
# GitHub.com/python/cpython/blob/main/Modules/mathmodule.c#L2305>}:
|
|
169
|
+
# raise a ValueError for a NAN result from non-NAN C{a_b_c}s or an
|
|
170
|
+
# OverflowError for a non-NAN non-finite from all finite C{a_b_c}s.
|
|
169
171
|
if isnan(r):
|
|
170
172
|
def _x(x):
|
|
171
173
|
return not isnan(x)
|
|
@@ -212,11 +214,11 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
212
214
|
return map(_2split3, xs)
|
|
213
215
|
|
|
214
216
|
|
|
215
|
-
def f2product(
|
|
217
|
+
def f2product(two=None):
|
|
216
218
|
'''Turn accurate I{TwoProduct} multiplication on or off.
|
|
217
219
|
|
|
218
|
-
@
|
|
219
|
-
|
|
220
|
+
@kwarg two: If C{True}, turn I{TwoProduct} on, if C{False} off or
|
|
221
|
+
if C{None} or omitted, keep the current setting.
|
|
220
222
|
|
|
221
223
|
@return: The previous setting (C{bool}).
|
|
222
224
|
|
|
@@ -226,8 +228,8 @@ def f2product(*two):
|
|
|
226
228
|
equivalent, slower implementation when not available.
|
|
227
229
|
'''
|
|
228
230
|
t = Fsum._f2product
|
|
229
|
-
if two
|
|
230
|
-
Fsum._f2product = bool(two
|
|
231
|
+
if two is not None:
|
|
232
|
+
Fsum._f2product = bool(two)
|
|
231
233
|
return t
|
|
232
234
|
|
|
233
235
|
|
|
@@ -318,14 +320,14 @@ def _NonfiniteError(x):
|
|
|
318
320
|
_ValueError if isnan(x) else _AssertionError)
|
|
319
321
|
|
|
320
322
|
|
|
321
|
-
def nonfiniterrors(
|
|
323
|
+
def nonfiniterrors(raiser=None):
|
|
322
324
|
'''Throw C{OverflowError} and C{ValueError} exceptions for or
|
|
323
325
|
handle I{non-finite} C{float}s as C{inf}, C{INF}, C{NINF},
|
|
324
326
|
C{nan} and C{NAN} in summations and multiplications.
|
|
325
327
|
|
|
326
|
-
@
|
|
327
|
-
|
|
328
|
-
|
|
328
|
+
@kwarg raiser: If C{True}, throw exceptions, if C{False} handle
|
|
329
|
+
I{non-finites} or if C{None} or omitted, leave
|
|
330
|
+
the setting unchanged.
|
|
329
331
|
|
|
330
332
|
@return: Previous setting (C{bool}).
|
|
331
333
|
|
|
@@ -333,8 +335,8 @@ def nonfiniterrors(*raiser):
|
|
|
333
335
|
C{nan} and C{NAN} a C{ValueError}.
|
|
334
336
|
'''
|
|
335
337
|
d = Fsum._isfine
|
|
336
|
-
if raiser
|
|
337
|
-
Fsum._isfine = {} if bool(raiser
|
|
338
|
+
if raiser is not None:
|
|
339
|
+
Fsum._isfine = {} if bool(raiser) else Fsum._nonfinites_isfine_kwds[True]
|
|
338
340
|
return (False if d is Fsum._nonfinites_isfine_kwds[True] else
|
|
339
341
|
_xkwds_get1(d, _isfine=_isfinite) is _isfinite) if d else True
|
|
340
342
|
|
|
@@ -516,7 +518,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
516
518
|
@see: Module L{fsums<pygeodesy.fsums>} for env variables C{PYGEODESY_FSUM_F2PRODUCT},
|
|
517
519
|
C{PYGEODESY_FSUM_NONFINITES} and C{PYGEODESY_FSUM_RESIDUAL}.
|
|
518
520
|
'''
|
|
519
|
-
_f2product =
|
|
521
|
+
_f2product = _MODS.sys_version_info2 > (3, 12) or bool(_F2PRODUCT)
|
|
520
522
|
_isfine = {} # == _isfinite, see nonfiniterrors()
|
|
521
523
|
_n = 0
|
|
522
524
|
# _ps = [] # partial sums
|
|
@@ -645,10 +647,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
645
647
|
f = self._copy_2(self.__floordiv__)
|
|
646
648
|
return f._floordiv(other, _floordiv_op_)
|
|
647
649
|
|
|
648
|
-
def __format__(self, *other): # PYCHOK no cover
|
|
649
|
-
'''Not implemented.'''
|
|
650
|
-
return _NotImplemented(self, *other)
|
|
651
|
-
|
|
652
650
|
def __ge__(self, other):
|
|
653
651
|
'''Return C{(B{self} >= B{other})}, see C{__eq__}.
|
|
654
652
|
'''
|
|
@@ -913,6 +911,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
913
911
|
f = self._copy_2r(other, self.__rdivmod__)
|
|
914
912
|
return f._fdivmod2(self, _divmod_op_)
|
|
915
913
|
|
|
914
|
+
# turned off, called by _deepcopy and _copy
|
|
915
|
+
# def __reduce__(self): # Python 3.8+
|
|
916
|
+
# ''' Pickle, like std C{fractions.Fraction}, see U{__reduce__
|
|
917
|
+
# <https://docs.Python.org/3/library/pickle.html#object.__reduce__>}
|
|
918
|
+
# '''
|
|
919
|
+
# dict_ = self._Fsum_as().__dict__ # no __setstate__
|
|
920
|
+
# return (self.__class__, self.partials, dict_)
|
|
921
|
+
|
|
916
922
|
# def __repr__(self):
|
|
917
923
|
# '''Return the default C{repr(this)}.
|
|
918
924
|
# '''
|
|
@@ -926,7 +932,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
926
932
|
f = self._copy_2r(other, self.__rfloordiv__)
|
|
927
933
|
return f._floordiv(self, _floordiv_op_)
|
|
928
934
|
|
|
929
|
-
def __rmatmul__(self, other): # PYCHOK no
|
|
935
|
+
def __rmatmul__(self, other): # PYCHOK no coveS
|
|
930
936
|
'''Not implemented.'''
|
|
931
937
|
return _NotImplemented(self, other)
|
|
932
938
|
|
|
@@ -1015,7 +1021,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1015
1021
|
|
|
1016
1022
|
__trunc__ = __int__
|
|
1017
1023
|
|
|
1018
|
-
if
|
|
1024
|
+
if _MODS.sys_version_info2 < (3, 0): # PYCHOK no cover
|
|
1019
1025
|
# <https://docs.Python.org/2/library/operator.html#mapping-operators-to-functions>
|
|
1020
1026
|
__div__ = __truediv__
|
|
1021
1027
|
__idiv__ = __itruediv__
|
|
@@ -1101,7 +1107,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1101
1107
|
def _copy_2(self, which, name=NN):
|
|
1102
1108
|
'''(INTERNAL) Copy for I{dyadic} operators.
|
|
1103
1109
|
'''
|
|
1104
|
-
n = name or which.__name__ #
|
|
1110
|
+
n = name or which.__name__ # _DUNDER_nameof
|
|
1105
1111
|
# NOT .classof due to .Fdot(a, *b) args, etc.
|
|
1106
1112
|
f = _Named.copy(self, deep=False, name=n)
|
|
1107
1113
|
f._ps = list(self._ps) # separate list
|
|
@@ -1152,6 +1158,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1152
1158
|
fs = _xs(xs, **kwds) # PYCHOK yield
|
|
1153
1159
|
ps = self._ps
|
|
1154
1160
|
ps[:] = self._ps_acc(list(ps), fs, up=up)
|
|
1161
|
+
# if len(ps) > 16:
|
|
1162
|
+
# _ = _psum(ps, **self._isfine)
|
|
1155
1163
|
return self
|
|
1156
1164
|
|
|
1157
1165
|
def _facc_args(self, xs, **up):
|
|
@@ -1161,6 +1169,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1161
1169
|
return self._fadd(xs[0], **up) if len(xs) == 1 else \
|
|
1162
1170
|
self._facc(xs, **up) # origin=1?
|
|
1163
1171
|
|
|
1172
|
+
def _facc_dot(self, n, xs, ys, **kwds): # in .fmath
|
|
1173
|
+
'''(INTERNAL) Accumulate C{fdot(B{xs}, *B{ys})}.
|
|
1174
|
+
'''
|
|
1175
|
+
if n > 0:
|
|
1176
|
+
_f = Fsum(**kwds)
|
|
1177
|
+
self._facc(_f(x).fmul(y) for x, y in zip(xs, ys)) # PYCHOK attr?
|
|
1178
|
+
return self
|
|
1179
|
+
|
|
1164
1180
|
def _facc_neg(self, xs, **up_origin):
|
|
1165
1181
|
'''(INTERNAL) Accumulate more C{xs}, negated.
|
|
1166
1182
|
'''
|
|
@@ -1452,7 +1468,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1452
1468
|
try:
|
|
1453
1469
|
s, r = self._fprs2
|
|
1454
1470
|
if r:
|
|
1455
|
-
f = self._f2mul(self.fma, other1, **nonfinites)
|
|
1471
|
+
f = self._f2mul(self.fma, (other1,), **nonfinites)
|
|
1456
1472
|
f += other2
|
|
1457
1473
|
elif _residue(other1) or _residue(other2):
|
|
1458
1474
|
fs = _2split3s(_fs(op, other1))
|
|
@@ -1491,36 +1507,41 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1491
1507
|
@deprecated_method
|
|
1492
1508
|
def f2mul(self, *others, **raiser):
|
|
1493
1509
|
'''DEPRECATED on 2024.09.13, use method L{f2mul_<Fsum.f2mul_>}.'''
|
|
1494
|
-
return self._fset(self.f2mul_(
|
|
1510
|
+
return self._fset(self.f2mul_(others, **raiser))
|
|
1495
1511
|
|
|
1496
|
-
def f2mul_(self, *others, **
|
|
1512
|
+
def f2mul_(self, *others, **f2product_nonfinites): # in .fmath.f2mul
|
|
1497
1513
|
'''Return C{B{self} * B{other} * B{other} ...} for all B{C{others}} using cascaded,
|
|
1498
|
-
accurate multiplication like with L{f2product<Fsum.f2product>}
|
|
1514
|
+
accurate multiplication like with L{f2product<Fsum.f2product>}C{(B{True})}.
|
|
1499
1515
|
|
|
1500
1516
|
@arg others: Multipliers (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
1501
1517
|
positional.
|
|
1502
|
-
@kwarg
|
|
1503
|
-
|
|
1504
|
-
|
|
1518
|
+
@kwarg f2product_nonfinites: Use C{B{f2product=False}} to override the default
|
|
1519
|
+
C{True} and C{B{nonfinites}=True} or C{False}, to override
|
|
1520
|
+
settings L{nonfinites<Fsum.nonfinites>} and L{nonfiniterrors}.
|
|
1505
1521
|
|
|
1506
1522
|
@return: The cascaded I{TwoProduct} (L{Fsum} or C{float}).
|
|
1507
1523
|
|
|
1508
1524
|
@see: U{Equations 2.3<https://www.TUHH.De/ti3/paper/rump/OzOgRuOi06.pdf>}
|
|
1509
1525
|
'''
|
|
1510
|
-
return self._f2mul(self.f2mul_,
|
|
1526
|
+
return self._f2mul(self.f2mul_, others, **f2product_nonfinites)
|
|
1511
1527
|
|
|
1512
|
-
def _f2mul(self, where,
|
|
1528
|
+
def _f2mul(self, where, others, f2product=True, **nonfinites_raiser):
|
|
1513
1529
|
'''(INTERNAL) See methods C{fma} and C{f2mul_}.
|
|
1514
1530
|
'''
|
|
1515
|
-
f
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1531
|
+
f = _Psum(self._ps, f2product=f2product, name=where.__name__)
|
|
1532
|
+
if others and f:
|
|
1533
|
+
if f.f2product():
|
|
1534
|
+
def _pfs(f, ps):
|
|
1535
|
+
return _2products(f, _2split3s(ps))
|
|
1536
|
+
else:
|
|
1537
|
+
def _pfs(f, ps): # PYCHOK redef
|
|
1538
|
+
return (f * p for p in ps)
|
|
1539
|
+
|
|
1540
|
+
op, ps = where.__name__, f._ps
|
|
1541
|
+
try: # as if self.f2product(True)
|
|
1520
1542
|
for other in others: # to pinpoint errors
|
|
1521
1543
|
for p in self._ps_other(op, other):
|
|
1522
|
-
|
|
1523
|
-
ps[:] = f._ps_acc([], pfs, up=False)
|
|
1544
|
+
ps[:] = f._ps_acc([], _pfs(p, ps), update=False)
|
|
1524
1545
|
f._update()
|
|
1525
1546
|
except TypeError as X:
|
|
1526
1547
|
raise self._ErrorX(X, op, other)
|
|
@@ -2299,11 +2320,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2299
2320
|
return (p * f for f in fs)
|
|
2300
2321
|
|
|
2301
2322
|
for p in ps:
|
|
2302
|
-
for
|
|
2303
|
-
yield
|
|
2323
|
+
for x in _pfs(p, fs):
|
|
2324
|
+
yield x if _isfine(x) else _nfError(x)
|
|
2304
2325
|
|
|
2305
|
-
|
|
2306
|
-
f = _Psum(self._ps_acc([],
|
|
2326
|
+
xs = _psfs(self._ps, factors, **self._isfine)
|
|
2327
|
+
f = _Psum(self._ps_acc([], xs, up=False), name=op)
|
|
2307
2328
|
return f
|
|
2308
2329
|
|
|
2309
2330
|
@property_RO
|
|
@@ -2774,7 +2795,7 @@ def _xs(xs, _X=_X_ps, _x=float, _isfine=_isfinite, # defaults for Fsum._facc
|
|
|
2774
2795
|
i, x = 0, xs
|
|
2775
2796
|
try:
|
|
2776
2797
|
for i, x in enumerate(_xiterable(xs)):
|
|
2777
|
-
if
|
|
2798
|
+
if _isFsum_2Tuple(x):
|
|
2778
2799
|
for p in _X(x):
|
|
2779
2800
|
yield p if _isfine(p) else _nfError(p)
|
|
2780
2801
|
else:
|
|
@@ -2803,7 +2824,7 @@ def _xsum(which, xs, nonfinites=None, primed=0, **floats): # origin=0
|
|
|
2803
2824
|
# delete all decorators, etc.
|
|
2804
2825
|
del _allPropertiesOf_n, deprecated_method, deprecated_property_RO, \
|
|
2805
2826
|
Property, Property_RO, property_RO, _ALL_LAZY, _F2PRODUCT, \
|
|
2806
|
-
MANT_DIG, _NONFINITES, _RESIDUAL_0_0,
|
|
2827
|
+
MANT_DIG, _NONFINITES, _RESIDUAL_0_0, _getPYGEODESY, _std_
|
|
2807
2828
|
|
|
2808
2829
|
if __name__ == '__main__':
|
|
2809
2830
|
|
pygeodesy/geodesici.py
CHANGED
|
@@ -38,11 +38,10 @@ from pygeodesy.errors import GeodesicError, IntersectionError, _an, \
|
|
|
38
38
|
# from pygeodesy.errors import exception_chaining # _MODS
|
|
39
39
|
from pygeodesy.fmath import euclid, fdot
|
|
40
40
|
from pygeodesy.fsums import Fsum, fsum1_, _ceil
|
|
41
|
-
from pygeodesy.interns import NN, _A_, _B_, _c_, _COMMASPACE_, \
|
|
42
|
-
|
|
43
|
-
from pygeodesy.karney import Caps, _diff182, GDict, _sincos2de
|
|
44
|
-
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
45
|
-
_getenv, _PYGEODESY_INTERSECTTOOL_
|
|
41
|
+
from pygeodesy.interns import NN, _A_, _B_, _c_, _COMMASPACE_, _HASH_, \
|
|
42
|
+
_M_, _not_, _SPACE_, _too_
|
|
43
|
+
from pygeodesy.karney import Caps, _diff182, GDict, _sincos2de, _Xables
|
|
44
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
46
45
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, _Pass
|
|
47
46
|
# from pygeodesy.namedTuples import _LL4Tuple # _MODS
|
|
48
47
|
from pygeodesy.props import deprecated_method, Property, \
|
|
@@ -57,7 +56,7 @@ from pygeodesy.utily import sincos2, atan2, fabs, radians
|
|
|
57
56
|
# from math import atan2, ceil as _ceil, fabs, radians # .fsums, .utily
|
|
58
57
|
|
|
59
58
|
__all__ = _ALL_LAZY.geodesici
|
|
60
|
-
__version__ = '24.
|
|
59
|
+
__version__ = '24.10.22'
|
|
61
60
|
|
|
62
61
|
_0t = 0, # int
|
|
63
62
|
_1_1t = -1, +1
|
|
@@ -470,8 +469,8 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
470
469
|
_Names_ABs = _latA_, _lonA_, 'latB', 'lonB', _sAB_ # -C to stderr
|
|
471
470
|
_Names_XDict = 'sA', 'sB', _c_ # plus 'k' from -i or 'sX0' from -R
|
|
472
471
|
_o_alt = _o__, # Offset latA lonA aziA latB lonB aziB x0 y0
|
|
473
|
-
_Xable_name =
|
|
474
|
-
_Xable_path =
|
|
472
|
+
_Xable_name = _Xables.IntersectTool.__name__
|
|
473
|
+
_Xable_path = _Xables.IntersectTool()
|
|
475
474
|
|
|
476
475
|
def __init__(self, a_geodesic=None, f=None, **name):
|
|
477
476
|
'''New L{IntersectTool}.
|
|
@@ -1547,7 +1546,7 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1547
1546
|
ll4 += ll4.replace(_A_, _B_)
|
|
1548
1547
|
llz = _SPACE_(NN, _latA_, _lonA_, 'aziA')
|
|
1549
1548
|
llz2 = llz + llz.replace(_A_, _B_)
|
|
1550
|
-
return dict(opts='-Verbose|V--version|v--help|h--Tool|T--Check|C-R meter
|
|
1549
|
+
return dict(opts='-Verbose|V--version|v--help|h--Tool|T--Check|C-R <meter>-',
|
|
1551
1550
|
alts=((_c_ + llz2),
|
|
1552
1551
|
(_i_ + ll4),
|
|
1553
1552
|
(_m_ + ll4),
|
|
@@ -1587,8 +1586,8 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1587
1586
|
I = Intersectool() # PYCHOK I
|
|
1588
1587
|
if _V:
|
|
1589
1588
|
I.verbose = True
|
|
1590
|
-
if I.IntersectTool
|
|
1591
|
-
I.IntersectTool =
|
|
1589
|
+
if not _Xables.X_OK(I.IntersectTool):
|
|
1590
|
+
I.IntersectTool = _Xables.IntersectTool(_Xables.bin_)
|
|
1592
1591
|
elif _V:
|
|
1593
1592
|
_ = I.version
|
|
1594
1593
|
M, _T = None, True
|
|
@@ -1640,38 +1639,42 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1640
1639
|
for i, X in enumerate(X):
|
|
1641
1640
|
printf(_COLONSPACE_(Fmt.INDEX(m, i), repr(X)))
|
|
1642
1641
|
|
|
1642
|
+
def _examples():
|
|
1643
|
+
|
|
1644
|
+
from pygeodesy.internals import _usage_argv
|
|
1645
|
+
|
|
1646
|
+
s = _SPACE_(*_usage_argv(__file__))
|
|
1647
|
+
for t in ('-h', '-h -n',
|
|
1648
|
+
'-c 0 0 45 40 10 135',
|
|
1649
|
+
'-C -c 0 0 45 40 10 135',
|
|
1650
|
+
'-T -R 2.6e7 -c 0 0 45 40 10 135',
|
|
1651
|
+
'-c 50 -4 -147.7 0 0 90',
|
|
1652
|
+
'-C -c 50 -4 -147.7 0 0 90',
|
|
1653
|
+
'# % echo 0 0 10 10 50 -4 50S 4W | IntersectTool -i -p 0 -C',
|
|
1654
|
+
'# -631414 5988887 0 -3',
|
|
1655
|
+
'# -4.05187 -4.00000 -4.05187 -4.00000 0',
|
|
1656
|
+
'-m 0 0 10 10 50 -4 50S 4W',
|
|
1657
|
+
'-C -m 0 0 10 10 50 -4 50S 4W',
|
|
1658
|
+
'-i 0 0 10 10 50 -4 50S 4W',
|
|
1659
|
+
'-T -i 0 0 10 10 50 -4 50S 4W',
|
|
1660
|
+
'-C -i 0 0 10 10 50 -4 50S 4W',
|
|
1661
|
+
'-T -C -i 0 0 10 10 50 -4 50S 4W',
|
|
1662
|
+
'-V -T -i 0 0 10 10 50 -4 -50 -4',
|
|
1663
|
+
'-C -R 4e7 -c 50 -4 -147.7 0 0 90',
|
|
1664
|
+
'-T -C -R 4e7 -c 50 -4 -147.7 0 0 90',
|
|
1665
|
+
'-R 4e7 -i 0 0 10 10 50 -4 -50 -4',
|
|
1666
|
+
'-T -R 4e7 -i 0 0 10 10 50 -4 -50 -4'):
|
|
1667
|
+
if t.startswith(_HASH_):
|
|
1668
|
+
printf(t, nl=int(t[2] == '%'))
|
|
1669
|
+
else:
|
|
1670
|
+
printf(_SPACE_(_HASH_, s, t), nl=1)
|
|
1671
|
+
argv[1:] = t = t.split()
|
|
1672
|
+
_main(t)
|
|
1673
|
+
|
|
1643
1674
|
from sys import argv, stderr
|
|
1644
1675
|
try:
|
|
1645
1676
|
if len(argv) == 2 and argv[1] == __help_:
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
s = _SPACE_(*_usage_argv(__file__))
|
|
1649
|
-
for t in ('-h', '-h -n',
|
|
1650
|
-
'-c 0 0 45 40 10 135',
|
|
1651
|
-
'-C -c 0 0 45 40 10 135',
|
|
1652
|
-
'-T -R 2.6e7 -c 0 0 45 40 10 135',
|
|
1653
|
-
'-c 50 -4 -147.7 0 0 90',
|
|
1654
|
-
'-C -c 50 -4 -147.7 0 0 90',
|
|
1655
|
-
'# % echo 0 0 10 10 50 -4 50S 4W | IntersectTool -i -p 0 -C',
|
|
1656
|
-
'# -631414 5988887 0 -3',
|
|
1657
|
-
'# -4.05187 -4.00000 -4.05187 -4.00000 0',
|
|
1658
|
-
'-m 0 0 10 10 50 -4 50S 4W',
|
|
1659
|
-
'-C -m 0 0 10 10 50 -4 50S 4W',
|
|
1660
|
-
'-i 0 0 10 10 50 -4 50S 4W',
|
|
1661
|
-
'-T -i 0 0 10 10 50 -4 50S 4W',
|
|
1662
|
-
'-C -i 0 0 10 10 50 -4 50S 4W',
|
|
1663
|
-
'-T -C -i 0 0 10 10 50 -4 50S 4W',
|
|
1664
|
-
'-V -T -i 0 0 10 10 50 -4 -50 -4',
|
|
1665
|
-
'-C -R 4e7 -c 50 -4 -147.7 0 0 90',
|
|
1666
|
-
'-T -C -R 4e7 -c 50 -4 -147.7 0 0 90',
|
|
1667
|
-
'-R 4e7 -i 0 0 10 10 50 -4 -50 -4',
|
|
1668
|
-
'-T -R 4e7 -i 0 0 10 10 50 -4 -50 -4'):
|
|
1669
|
-
if t.startswith(_HASH_):
|
|
1670
|
-
printf(t, nl=int(t[2] == '%'))
|
|
1671
|
-
else:
|
|
1672
|
-
printf(_SPACE_(_HASH_, s, t), nl=1)
|
|
1673
|
-
argv[1:] = t = t.split()
|
|
1674
|
-
_main(t)
|
|
1677
|
+
_examples()
|
|
1675
1678
|
else:
|
|
1676
1679
|
_main(argv[1:])
|
|
1677
1680
|
|
pygeodesy/geodesicw.py
CHANGED
|
@@ -21,7 +21,7 @@ from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
|
21
21
|
from pygeodesy.errors import _AssertionError, GeodesicError, \
|
|
22
22
|
IntersectionError
|
|
23
23
|
from pygeodesy.fsums import Fsum, Fmt, unstr
|
|
24
|
-
from pygeodesy.internals import
|
|
24
|
+
from pygeodesy.internals import _DUNDER_nameof, _under
|
|
25
25
|
from pygeodesy.interns import NN, _DOT_, _SPACE_, _to_, _too_
|
|
26
26
|
from pygeodesy.karney import _atan2d, Caps, Direct9Tuple, GDict, \
|
|
27
27
|
Inverse10Tuple, _kWrapped
|
|
@@ -39,7 +39,7 @@ from contextlib import contextmanager
|
|
|
39
39
|
# from math import fabs # from .utily
|
|
40
40
|
|
|
41
41
|
__all__ = _ALL_LAZY.geodesicw
|
|
42
|
-
__version__ = '24.
|
|
42
|
+
__version__ = '24.11.02'
|
|
43
43
|
|
|
44
44
|
_plumb_ = 'plumb'
|
|
45
45
|
_TRIPS = 65
|
|
@@ -94,14 +94,14 @@ class _gWrapped(_kWrapped):
|
|
|
94
94
|
if name:
|
|
95
95
|
self._name, _ = _name2__(name, _or_nameof=E)
|
|
96
96
|
|
|
97
|
-
def ArcDirect(self, lat1, lon1, azi1, a12, outmask=Caps._STD):
|
|
97
|
+
def ArcDirect(self, lat1, lon1, azi1, a12, outmask=Caps._STD): # PYCHOK no cover
|
|
98
98
|
'''Return the C{_Geodesic.ArcDirect} result as L{GDict}.
|
|
99
99
|
'''
|
|
100
100
|
with _wargs(self, lat1, lon1, azi1, a12, outmask) as args:
|
|
101
101
|
d = _Geodesic.ArcDirect(self, *args)
|
|
102
102
|
return GDict(d)
|
|
103
103
|
|
|
104
|
-
def ArcDirectLine(self, lat1, lon1, azi1, a12, caps=Caps._STD_LINE, **name):
|
|
104
|
+
def ArcDirectLine(self, lat1, lon1, azi1, a12, caps=Caps._STD_LINE, **name): # PYCHOK no cover
|
|
105
105
|
'''Return the C{_Geodesic.ArcDirectLine} as I{wrapped} C{GeodesicLine}.
|
|
106
106
|
'''
|
|
107
107
|
return self._GenDirectLine(lat1, lon1, azi1, True, a12, caps, **name)
|
|
@@ -445,7 +445,7 @@ _wrapped = _gWrapped() # PYCHOK singleton, .ellipsoids, .test/base.py
|
|
|
445
445
|
|
|
446
446
|
class Geodesic(_gWrapped): # overwritten by 1st instance
|
|
447
447
|
'''I{Wrapper} around I{Karney}'s class U{geographiclib.geodesic.Geodesic
|
|
448
|
-
<https://
|
|
448
|
+
<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
449
449
|
'''
|
|
450
450
|
def __new__(unused, a_ellipsoid=_EWGS84, f=None, **name):
|
|
451
451
|
'''Return a I{wrapped} C{geodesic.Geodesic} instance from I{Karney}'s
|
|
@@ -465,7 +465,7 @@ class Geodesic(_gWrapped): # overwritten by 1st instance
|
|
|
465
465
|
|
|
466
466
|
class GeodesicLine(_gWrapped): # overwritten by 1st instance
|
|
467
467
|
'''I{Wrapper} around I{Karney}'s class U{geographiclib.geodesicline.GeodesicLine
|
|
468
|
-
<https://
|
|
468
|
+
<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
469
469
|
'''
|
|
470
470
|
def __new__(unused, geodesic, lat1, lon1, azi1, caps=Caps._STD_LINE, **name):
|
|
471
471
|
'''Return a I{wrapped} C{geodesicline.GeodesicLine} instance from I{Karney}'s
|
|
@@ -516,16 +516,15 @@ def _Intersecant2(gl, lat0, lon0, radius, tol=_TOL, form=F_D): # MCCABE in LatL
|
|
|
516
516
|
# (INTERNAL) Return the intersections of a circle at C{lat0, lon0}
|
|
517
517
|
# and a geodesic line as a 2-Tuple C{(P, Q)}, each a C{GDict}.
|
|
518
518
|
r = Radius_(radius)
|
|
519
|
-
n =
|
|
519
|
+
n = _DUNDER_nameof(_Intersecant2)[1:]
|
|
520
520
|
_P = gl.Position
|
|
521
521
|
_I = gl.geodesic.Inverse
|
|
522
|
-
_a = fabs
|
|
523
522
|
|
|
524
523
|
def _R3(s):
|
|
525
524
|
# radius, intersection, etc. at distance C{s}
|
|
526
525
|
P = _P(s)
|
|
527
526
|
d = _I(lat0, lon0, P.lat2, P.lon2)
|
|
528
|
-
return
|
|
527
|
+
return fabs(d.s12), P, d
|
|
529
528
|
|
|
530
529
|
def _bisect2(s, c, Rc, r, tol, _R3):
|
|
531
530
|
_s = Fsum(c).fsumf_
|
|
@@ -536,18 +535,20 @@ def _Intersecant2(gl, lat0, lon0, radius, tol=_TOL, form=F_D): # MCCABE in LatL
|
|
|
536
535
|
break
|
|
537
536
|
else: # b >>> s and c >>> s
|
|
538
537
|
raise ValueError(Fmt.no_convergence(b, s))
|
|
539
|
-
|
|
538
|
+
# Rb > r > Rc
|
|
540
539
|
for i in range(_TRIPS): # 47-48
|
|
541
|
-
s = (b + c) *
|
|
540
|
+
s = (b + c) * _0_5
|
|
542
541
|
R, P, d = _R3(s)
|
|
543
542
|
if Rb > R > r:
|
|
544
543
|
b, Rb = s, R
|
|
545
544
|
elif Rc < R < r:
|
|
546
545
|
c, Rc = s, R
|
|
547
|
-
|
|
548
|
-
|
|
546
|
+
# else:
|
|
547
|
+
# break
|
|
548
|
+
t = fabs(b - c)
|
|
549
|
+
if t < tol: # or fabs(R - r) < tol:
|
|
549
550
|
break
|
|
550
|
-
else: # t = min(t,
|
|
551
|
+
else: # t = min(t, fabs(R - r))
|
|
551
552
|
raise ValueError(Fmt.no_convergence(t, tol))
|
|
552
553
|
i += C.iteration # combine iterations
|
|
553
554
|
P.set_(lat0=lat0, lon0=lon0, azi0=d.azi1, iteration=i,
|
|
@@ -558,13 +559,13 @@ def _Intersecant2(gl, lat0, lon0, radius, tol=_TOL, form=F_D): # MCCABE in LatL
|
|
|
558
559
|
# one the plumb, pseudo-rhumb line to the other
|
|
559
560
|
C = _PlumbTo(gl, lat0, lon0, tol=tol)
|
|
560
561
|
try:
|
|
561
|
-
a =
|
|
562
|
+
a = fabs(C.s02) # distance between centers
|
|
562
563
|
if a < r:
|
|
563
564
|
c = C.s12 # distance along pseudo-rhumb line
|
|
564
565
|
h = _copysign(r, c) # past half chord length
|
|
565
566
|
P, p = _bisect2( h, c, a, r, tol, _R3)
|
|
566
567
|
Q, q = _bisect2(-h, c, a, r, tol, _R3)
|
|
567
|
-
if
|
|
568
|
+
if fabs(p - q) < max(EPS, tol):
|
|
568
569
|
Q = P
|
|
569
570
|
elif a > r:
|
|
570
571
|
raise ValueError(_too_(Fmt.distant(a)))
|
pygeodesy/geodesicx/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
u'''A pure Python version of I{Karney}'s C++ classes U{GeodesicExact
|
|
5
5
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>}
|
|
6
6
|
and U{GeodesicLineExact
|
|
7
|
-
<https://
|
|
7
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicLine.html>}.
|
|
8
8
|
|
|
9
9
|
For more details, see the C++ U{GeographicLib<https://GeographicLib.SourceForge.io/C++/doc/index.html>}
|
|
10
10
|
documentation, especially the U{Class List<https://GeographicLib.SourceForge.io/C++/doc/annotated.html>}
|
|
@@ -23,7 +23,7 @@ from pygeodesy.karney import Caps, GeodesicError
|
|
|
23
23
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
|
|
24
24
|
|
|
25
25
|
__all__ = _ALL_LAZY.geodesicx + _ALL_DOCS(Caps, GeodesicError)
|
|
26
|
-
__version__ = '24.
|
|
26
|
+
__version__ = '24.11.02'
|
|
27
27
|
|
|
28
28
|
# **) MIT License
|
|
29
29
|
#
|
pygeodesy/geodesicx/gxarea.py
CHANGED
|
@@ -19,10 +19,11 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
19
19
|
|
|
20
20
|
from pygeodesy.basics import isodd, unsigned0
|
|
21
21
|
from pygeodesy.constants import NAN, _0_0, _0_5, _720_0
|
|
22
|
+
from pygeodesy.internals import printf
|
|
22
23
|
# from pygeodesy.interns import _COMMASPACE_ # from .lazily
|
|
23
24
|
from pygeodesy.karney import Area3Tuple, _diff182, GeodesicError, \
|
|
24
25
|
_norm180, _remainder, _sum3
|
|
25
|
-
from pygeodesy.lazily import _ALL_DOCS,
|
|
26
|
+
from pygeodesy.lazily import _ALL_DOCS, _COMMASPACE_
|
|
26
27
|
from pygeodesy.named import ADict, callername, _NamedBase, pairs
|
|
27
28
|
from pygeodesy.props import Property, Property_RO, property_RO
|
|
28
29
|
# from pygeodesy.streprs import pairs # from .named
|
|
@@ -30,7 +31,7 @@ from pygeodesy.props import Property, Property_RO, property_RO
|
|
|
30
31
|
from math import fmod as _fmod
|
|
31
32
|
|
|
32
33
|
__all__ = ()
|
|
33
|
-
__version__ = '24.
|
|
34
|
+
__version__ = '24.10.14'
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
class GeodesicAreaExact(_NamedBase):
|