pygeodesy 25.5.5__py2.py3-none-any.whl → 25.5.28__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 +186 -186
- pygeodesy/__main__.py +4 -3
- pygeodesy/albers.py +4 -4
- pygeodesy/auxilats/_CX_Rs.py +3 -3
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxDLat.py +2 -2
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +2 -2
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +2 -2
- pygeodesy/booleans.py +11 -11
- pygeodesy/cartesianBase.py +2 -2
- pygeodesy/clipy.py +2 -2
- pygeodesy/constants.py +7 -7
- pygeodesy/css.py +1 -1
- pygeodesy/datums.py +2 -2
- pygeodesy/deprecated/__init__.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/rhumbBase.py +2 -2
- pygeodesy/deprecated/rhumbaux.py +2 -2
- pygeodesy/deprecated/rhumbsolve.py +2 -2
- pygeodesy/deprecated/rhumbx.py +2 -2
- pygeodesy/ecef.py +3 -4
- pygeodesy/ellipsoidalBase.py +2 -2
- pygeodesy/ellipsoidalBaseDI.py +7 -6
- pygeodesy/ellipsoidalExact.py +24 -29
- pygeodesy/ellipsoidalGeodSolve.py +19 -19
- pygeodesy/ellipsoidalKarney.py +22 -27
- pygeodesy/ellipsoidalNvector.py +4 -4
- pygeodesy/ellipsoidalVincenty.py +17 -15
- pygeodesy/ellipsoids.py +4 -4
- pygeodesy/elliptic.py +16 -11
- pygeodesy/errors.py +1 -1
- pygeodesy/etm.py +2 -2
- pygeodesy/fmath.py +9 -9
- pygeodesy/formy.py +2 -2
- pygeodesy/frechet.py +6 -6
- pygeodesy/fstats.py +2 -2
- pygeodesy/fsums.py +37 -28
- pygeodesy/gars.py +2 -3
- pygeodesy/geodesici.py +4 -4
- pygeodesy/geodesicw.py +27 -8
- pygeodesy/geodesicx/__init__.py +3 -3
- pygeodesy/geodesicx/gx.py +52 -48
- pygeodesy/geodesicx/gxarea.py +54 -65
- pygeodesy/geodesicx/gxbases.py +12 -2
- pygeodesy/geodesicx/gxline.py +10 -7
- pygeodesy/geoids.py +6 -6
- pygeodesy/hausdorff.py +5 -5
- pygeodesy/heights.py +5 -5
- pygeodesy/internals.py +2 -2
- pygeodesy/interns.py +5 -5
- pygeodesy/iters.py +1 -1
- pygeodesy/karney.py +28 -12
- pygeodesy/ktm.py +2 -2
- pygeodesy/latlonBase.py +3 -4
- pygeodesy/lazily.py +1 -1
- pygeodesy/lcc.py +3 -3
- pygeodesy/ltp.py +5 -5
- pygeodesy/mgrs.py +3 -3
- pygeodesy/namedTuples.py +3 -3
- pygeodesy/nvectorBase.py +2 -2
- pygeodesy/osgr.py +2 -2
- pygeodesy/points.py +2 -3
- pygeodesy/props.py +18 -18
- pygeodesy/resections.py +30 -24
- pygeodesy/rhumb/aux_.py +2 -2
- pygeodesy/rhumb/bases.py +3 -3
- pygeodesy/rhumb/ekx.py +3 -4
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/simplify.py +2 -2
- pygeodesy/solveBase.py +2 -2
- pygeodesy/sphericalBase.py +8 -8
- pygeodesy/sphericalNvector.py +19 -16
- pygeodesy/sphericalTrigonometry.py +24 -24
- pygeodesy/trf.py +4 -4
- pygeodesy/triaxials.py +2 -2
- pygeodesy/units.py +7 -8
- pygeodesy/utily.py +2 -2
- pygeodesy/utmupsBase.py +2 -2
- pygeodesy/vector2d.py +14 -8
- pygeodesy/vector3d.py +3 -3
- pygeodesy/webmercator.py +2 -2
- {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/METADATA +16 -16
- pygeodesy-25.5.28.dist-info/RECORD +119 -0
- pygeodesy-25.5.5.dist-info/RECORD +0 -119
- {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/WHEEL +0 -0
- {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -37,7 +37,7 @@ respectively C{ValueError} exceptions. However, in that case I{non-finite}
|
|
|
37
37
|
results may differ from Python's C{math.fsum} results.
|
|
38
38
|
'''
|
|
39
39
|
# make sure int/int division yields float quotient, see .basics
|
|
40
|
-
from __future__ import division as _; del _ #
|
|
40
|
+
from __future__ import division as _; del _ # noqa: E702 ;
|
|
41
41
|
|
|
42
42
|
from pygeodesy.basics import _gcd, isbool, iscomplex, isint, isscalar, \
|
|
43
43
|
_signOf, itemsorted, signOf, _xiterable
|
|
@@ -48,7 +48,7 @@ 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, _envPYGEODESY, _passarg, typename
|
|
51
|
+
from pygeodesy.internals import _enquote, _envPYGEODESY, _passarg, typename # _sizeof
|
|
52
52
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DMAIN_, _DOT_, _from_, \
|
|
53
53
|
_not_finite_, _SPACE_, _std_, _UNDER_
|
|
54
54
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
|
|
@@ -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__ = '25.
|
|
67
|
+
__version__ = '25.05.12'
|
|
68
68
|
|
|
69
69
|
from pygeodesy.interns import (
|
|
70
70
|
_PLUS_ as _add_op_, # in .auxilats.auxAngle
|
|
@@ -230,13 +230,13 @@ def f2product(two=None):
|
|
|
230
230
|
def _Fsumf_(*xs): # in .auxLat, ...
|
|
231
231
|
'''(INTERNAL) An C{Fsum(xs)}, all C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
232
232
|
'''
|
|
233
|
-
return Fsum().
|
|
233
|
+
return Fsum()._facc_xsum(xs, up=False)
|
|
234
234
|
|
|
235
235
|
|
|
236
236
|
def _Fsum1f_(*xs): # in .albers
|
|
237
237
|
'''(INTERNAL) An C{Fsum(xs)}, all C{scalar}, an L{Fsum} or L{Fsum2Tuple}, 1-primed.
|
|
238
238
|
'''
|
|
239
|
-
return Fsum().
|
|
239
|
+
return Fsum()._facc_xsum(_1primed(xs), origin=-1, up=False)
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
def _halfeven(s, r, p):
|
|
@@ -585,7 +585,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
585
585
|
with quotient C{div} an C{int} in Python 3+ or C{float}
|
|
586
586
|
in Python 2- and remainder C{mod} an L{Fsum} instance.
|
|
587
587
|
|
|
588
|
-
@arg other:
|
|
588
|
+
@arg other: Modulus (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
589
589
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
590
590
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
591
591
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
@@ -623,7 +623,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
623
623
|
def __floordiv__(self, other):
|
|
624
624
|
'''Return C{B{self} // B{other}} as an L{Fsum}.
|
|
625
625
|
|
|
626
|
-
@arg other:
|
|
626
|
+
@arg other: Divisor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
627
627
|
|
|
628
628
|
@return: The C{floor} quotient (L{Fsum}).
|
|
629
629
|
|
|
@@ -632,6 +632,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
632
632
|
f = self._copyd(self.__floordiv__)
|
|
633
633
|
return f._floordiv(other, _floordiv_op_)
|
|
634
634
|
|
|
635
|
+
# def __format__(self, *other): # PYCHOK no cover
|
|
636
|
+
# '''Not implemented.'''
|
|
637
|
+
# return _NotImplemented(self, *other)
|
|
638
|
+
|
|
635
639
|
def __ge__(self, other):
|
|
636
640
|
'''Return C{(B{self} >= B{other})}, see C{__eq__}.
|
|
637
641
|
'''
|
|
@@ -672,7 +676,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
672
676
|
def __ifloordiv__(self, other):
|
|
673
677
|
'''Apply C{B{self} //= B{other}} to this instance.
|
|
674
678
|
|
|
675
|
-
@arg other:
|
|
679
|
+
@arg other: Divisor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
676
680
|
|
|
677
681
|
@return: This instance, updated (L{Fsum}).
|
|
678
682
|
|
|
@@ -696,7 +700,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
696
700
|
def __imod__(self, other):
|
|
697
701
|
'''Apply C{B{self} %= B{other}} to this instance.
|
|
698
702
|
|
|
699
|
-
@arg other:
|
|
703
|
+
@arg other: Modulus (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
700
704
|
|
|
701
705
|
@return: This instance, updated (L{Fsum}).
|
|
702
706
|
|
|
@@ -707,7 +711,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
707
711
|
def __imul__(self, other):
|
|
708
712
|
'''Apply C{B{self} *= B{other}} to this instance.
|
|
709
713
|
|
|
710
|
-
@arg other:
|
|
714
|
+
@arg other: Factor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
711
715
|
|
|
712
716
|
@return: This instance, updated (L{Fsum}).
|
|
713
717
|
|
|
@@ -736,7 +740,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
736
740
|
def __ipow__(self, other, *mod, **raiser_RESIDUAL): # PYCHOK 2 vs 3 args
|
|
737
741
|
'''Apply C{B{self} **= B{other}} to this instance.
|
|
738
742
|
|
|
739
|
-
@arg other:
|
|
743
|
+
@arg other: Exponent (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
740
744
|
@arg mod: Optional modulus (C{int} or C{None}) for the 3-argument
|
|
741
745
|
C{pow(B{self}, B{other}, B{mod})} version.
|
|
742
746
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
@@ -798,7 +802,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
798
802
|
def __itruediv__(self, other, **raiser_RESIDUAL):
|
|
799
803
|
'''Apply C{B{self} /= B{other}} to this instance.
|
|
800
804
|
|
|
801
|
-
@arg other:
|
|
805
|
+
@arg other: Divisor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
802
806
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
803
807
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
804
808
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
@@ -917,7 +921,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
917
921
|
f = self._rcopyd(other, self.__rfloordiv__)
|
|
918
922
|
return f._floordiv(self, _floordiv_op_)
|
|
919
923
|
|
|
920
|
-
def __rmatmul__(self, other): # PYCHOK no
|
|
924
|
+
def __rmatmul__(self, other): # PYCHOK no cover
|
|
921
925
|
'''Not implemented.'''
|
|
922
926
|
return _NotImplemented(self, other)
|
|
923
927
|
|
|
@@ -970,6 +974,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
970
974
|
f = self._rcopyd(other, self.__rtruediv__)
|
|
971
975
|
return f._ftruediv(self, _truediv_op_, **raiser_RESIDUAL)
|
|
972
976
|
|
|
977
|
+
# def __sizeof__(self):
|
|
978
|
+
# '''Return the size of this instance (C{int} bytes}).
|
|
979
|
+
# '''
|
|
980
|
+
# return _sizeof(self._ps) + _sizeof(self._n)
|
|
981
|
+
|
|
973
982
|
def __str__(self):
|
|
974
983
|
'''Return the default C{str(self)}.
|
|
975
984
|
'''
|
|
@@ -990,7 +999,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
990
999
|
def __truediv__(self, other, **raiser_RESIDUAL):
|
|
991
1000
|
'''Return C{B{self} / B{other}} as an L{Fsum}.
|
|
992
1001
|
|
|
993
|
-
@arg other:
|
|
1002
|
+
@arg other: Divisor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
994
1003
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
995
1004
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
996
1005
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
@@ -1221,14 +1230,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1221
1230
|
'''
|
|
1222
1231
|
return self._facc_scalar(xs, **up)
|
|
1223
1232
|
|
|
1224
|
-
def _facc_scalarf(self, xs, up=True, **origin_which):
|
|
1225
|
-
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}, an L{Fsum} or
|
|
1226
|
-
L{Fsum2Tuple}, like function C{_xsum}.
|
|
1227
|
-
'''
|
|
1228
|
-
fs = _xs(xs, **_x_isfine(self.nonfinitesOK, _Cdot=type(self),
|
|
1229
|
-
**origin_which)) # PYCHOK yield
|
|
1230
|
-
return self._facc_scalar(fs, up=up)
|
|
1231
|
-
|
|
1232
1233
|
# def _facc_up(self, up=True):
|
|
1233
1234
|
# '''(INTERNAL) Update the C{partials}, by removing
|
|
1234
1235
|
# and re-accumulating the final C{partial}.
|
|
@@ -1243,6 +1244,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1243
1244
|
# break
|
|
1244
1245
|
# return self._update() if up else self
|
|
1245
1246
|
|
|
1247
|
+
def _facc_xsum(self, xs, up=True, **origin_which):
|
|
1248
|
+
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}, an L{Fsum}
|
|
1249
|
+
or L{Fsum2Tuple}, like function C{_xsum}.
|
|
1250
|
+
'''
|
|
1251
|
+
fs = _xs(xs, **_x_isfine(self.nonfinitesOK, _Cdot=type(self),
|
|
1252
|
+
**origin_which)) # PYCHOK yield
|
|
1253
|
+
return self._facc_scalar(fs, up=up)
|
|
1254
|
+
|
|
1246
1255
|
def fadd(self, xs=()):
|
|
1247
1256
|
'''Add an iterable's items to this instance.
|
|
1248
1257
|
|
|
@@ -1533,17 +1542,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1533
1542
|
def fover(self, over, **raiser_RESIDUAL):
|
|
1534
1543
|
'''Apply C{B{self} /= B{over}} and summate.
|
|
1535
1544
|
|
|
1536
|
-
@arg over:
|
|
1545
|
+
@arg over: Divisor (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
1537
1546
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
1538
1547
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
1539
1548
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
1540
1549
|
|
|
1541
|
-
@return: Precision running sum (C{float}).
|
|
1550
|
+
@return: Precision running quotient sum (C{float}).
|
|
1542
1551
|
|
|
1543
1552
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1544
1553
|
B{C{RESIDUAL}}.
|
|
1545
1554
|
|
|
1546
|
-
@see: Methods L{Fsum.
|
|
1555
|
+
@see: Methods L{Fsum.fdiv}, L{Fsum.__itruediv__} and L{Fsum.fsum}.
|
|
1547
1556
|
'''
|
|
1548
1557
|
return float(self.fdiv(over, **raiser_RESIDUAL)._fprs)
|
|
1549
1558
|
|
|
@@ -1837,19 +1846,19 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1837
1846
|
'''Like method L{Fsum.fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1838
1847
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1839
1848
|
'''
|
|
1840
|
-
return self.
|
|
1849
|
+
return self._facc_xsum(xs, which=self.fsumf_)._fprs # origin=1?
|
|
1841
1850
|
|
|
1842
1851
|
def Fsumf_(self, *xs):
|
|
1843
1852
|
'''Like method L{Fsum.Fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1844
1853
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1845
1854
|
'''
|
|
1846
|
-
return self.
|
|
1855
|
+
return self._facc_xsum(xs, which=self.Fsumf_)._copyd(self.Fsumf_) # origin=1?
|
|
1847
1856
|
|
|
1848
1857
|
def fsum2f_(self, *xs):
|
|
1849
1858
|
'''Like method L{Fsum.fsum2_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1850
1859
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1851
1860
|
'''
|
|
1852
|
-
return self._fsum2(xs, self.
|
|
1861
|
+
return self._fsum2(xs, self._facc_xsum, which=self.fsum2f_) # origin=1?
|
|
1853
1862
|
|
|
1854
1863
|
# ftruediv = __itruediv__ # for naming consistency?
|
|
1855
1864
|
|
pygeodesy/gars.py
CHANGED
|
@@ -15,8 +15,7 @@ Transcoded from I{Charles Karney}'s C++ class U{GARS
|
|
|
15
15
|
'''
|
|
16
16
|
|
|
17
17
|
from pygeodesy.basics import isstr, _splituple, typename
|
|
18
|
-
from pygeodesy.constants import _off90, _1_over, _0_5
|
|
19
|
-
_1_0 # PYCHOK used!
|
|
18
|
+
from pygeodesy.constants import _off90, _1_over, _0_5
|
|
20
19
|
from pygeodesy.errors import _ValueError, _xkwds, _xStrError
|
|
21
20
|
# from pygeodesy.internals import typename # from .basics
|
|
22
21
|
from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _INV_
|
|
@@ -30,7 +29,7 @@ from pygeodesy.units import Int_, Lat, Lon, Precision_, Scalar_, Str
|
|
|
30
29
|
from math import floor
|
|
31
30
|
|
|
32
31
|
__all__ = _ALL_LAZY.gars
|
|
33
|
-
__version__ = '25.
|
|
32
|
+
__version__ = '25.05.07'
|
|
34
33
|
|
|
35
34
|
_Digits = _0to9_
|
|
36
35
|
_LatLen = 2
|
pygeodesy/geodesici.py
CHANGED
|
@@ -23,7 +23,7 @@ and I{S. Baselga Moreno & J.C. Martinez-Llario}'s U{Intersection and point-to-li
|
|
|
23
23
|
on the ellipsoid<https://riunet.UPV.ES/bitstream/handle/10251/122902/Revised_Manuscript.pdf>}.
|
|
24
24
|
'''
|
|
25
25
|
# make sure int/int division yields float quotient
|
|
26
|
-
from __future__ import division as _; del _ #
|
|
26
|
+
from __future__ import division as _; del _ # noqa: E702 ;
|
|
27
27
|
|
|
28
28
|
from pygeodesy.basics import _copy, _enumereverse, map1, \
|
|
29
29
|
_xinstanceof, _xor, typename
|
|
@@ -57,7 +57,7 @@ from pygeodesy.utily import atan2, sincos2, fabs, radians
|
|
|
57
57
|
# from math import ceil as _ceil, fabs, radians # .fsums, .utily
|
|
58
58
|
|
|
59
59
|
__all__ = _ALL_LAZY.geodesici
|
|
60
|
-
__version__ = '25.
|
|
60
|
+
__version__ = '25.05.12'
|
|
61
61
|
|
|
62
62
|
_0t = 0, # int
|
|
63
63
|
_1_1t = -1, +1
|
|
@@ -1560,7 +1560,7 @@ if __name__ == _DMAIN_: # MCCABE 14
|
|
|
1560
1560
|
|
|
1561
1561
|
_isopt = re.compile('^[-]+[a-z]*$', flags=re.IGNORECASE).match
|
|
1562
1562
|
|
|
1563
|
-
I = Intersector(GeodesicExact()) #
|
|
1563
|
+
I = Intersector(GeodesicExact()) # noqa: E741 I is eye
|
|
1564
1564
|
M = m = _R = None
|
|
1565
1565
|
_T = _V = _h = _C = False
|
|
1566
1566
|
|
|
@@ -1584,7 +1584,7 @@ if __name__ == _DMAIN_: # MCCABE 14
|
|
|
1584
1584
|
elif arg == _R__ and args:
|
|
1585
1585
|
_R = args.pop(0)
|
|
1586
1586
|
elif _starts('--Tool', arg):
|
|
1587
|
-
I = Intersectool() #
|
|
1587
|
+
I = Intersectool() # noqa: E741 I is eye
|
|
1588
1588
|
if _V:
|
|
1589
1589
|
I.verbose = True
|
|
1590
1590
|
if not _Xables.X_OK(I.IntersectTool):
|
pygeodesy/geodesicw.py
CHANGED
|
@@ -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__ = '25.
|
|
42
|
+
__version__ = '25.05.28'
|
|
43
43
|
|
|
44
44
|
_plumb_ = 'plumb'
|
|
45
45
|
_TRIPS = 65
|
|
@@ -96,6 +96,28 @@ class _gWrapped(_kWrapped):
|
|
|
96
96
|
if name:
|
|
97
97
|
self._name, _ = _name2__(name, _or_nameof=E)
|
|
98
98
|
|
|
99
|
+
def Area(self, polyline=False, **name): # like GeodesicExact.Area
|
|
100
|
+
'''Return a C{PolygonArea} instance with method C{Compute} extended.
|
|
101
|
+
'''
|
|
102
|
+
_AreaBase = _wrapped._PolygonArea # in .karney._kwrapped
|
|
103
|
+
|
|
104
|
+
class _PolygonArea(_AreaBase):
|
|
105
|
+
# def __init__(self, *earth_polyline):
|
|
106
|
+
# _PolygonArea.__init__(self, *earth_polyline)
|
|
107
|
+
|
|
108
|
+
def Compute(self, reverse=False, sign=True, polar=False):
|
|
109
|
+
'''Use C{B{polar}=True} to adjust the area, see function
|
|
110
|
+
L{areaOf<pygeodesy.geodesicx.gxarea.areaOf>}.
|
|
111
|
+
'''
|
|
112
|
+
n, p, a = _AreaBase.Compute(self, reverse=reverse, sign=sign)
|
|
113
|
+
if polar: # see .geodesicx.gxarea.GeodesicAreaExact._reduced
|
|
114
|
+
a += _copysign(self.area0 * _0_5 * n, a)
|
|
115
|
+
return n, p, a
|
|
116
|
+
|
|
117
|
+
A = _PolygonArea(self, polyline)
|
|
118
|
+
A.name = _name2__(name, _or_nameof=self)
|
|
119
|
+
return A
|
|
120
|
+
|
|
99
121
|
def ArcDirect(self, lat1, lon1, azi1, a12, outmask=Caps.STANDARD): # PYCHOK no cover
|
|
100
122
|
'''Return the C{_Geodesic.ArcDirect} result as L{GDict}.
|
|
101
123
|
'''
|
|
@@ -108,8 +130,6 @@ class _gWrapped(_kWrapped):
|
|
|
108
130
|
'''
|
|
109
131
|
return self._GenDirectLine(lat1, lon1, azi1, True, a12, caps, **name)
|
|
110
132
|
|
|
111
|
-
Area = _Geodesic.Polygon # like GeodesicExact.Area
|
|
112
|
-
|
|
113
133
|
@property_RO
|
|
114
134
|
def datum(self):
|
|
115
135
|
'''Get this geodesic's datum (C{Datum}).
|
|
@@ -257,9 +277,8 @@ class _gWrapped(_kWrapped):
|
|
|
257
277
|
'''
|
|
258
278
|
return self._name
|
|
259
279
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
WGS84 = None # _EWGS84.geodesicw recusion
|
|
280
|
+
Polygon = Area
|
|
281
|
+
WGS84 = None # _EWGS84.geodesicw recusion
|
|
263
282
|
|
|
264
283
|
# Geodesic.ArcDirect.__doc__ = _Geodesic.ArcDirect.__doc__
|
|
265
284
|
# Geodesic.Direct.__doc__ = _Geodesic.Direct.__doc__
|
|
@@ -461,7 +480,7 @@ class Geodesic(_gWrapped): # overwritten by 1st instance
|
|
|
461
480
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
462
481
|
'''
|
|
463
482
|
g = _wrapped.Geodesic(a_ellipsoid, f=f, **name)
|
|
464
|
-
_MODS.geodesicw.Geodesic = g
|
|
483
|
+
_MODS.geodesicw.Geodesic = type(g) # overwrite class
|
|
465
484
|
return g
|
|
466
485
|
|
|
467
486
|
|
|
@@ -485,7 +504,7 @@ class GeodesicLine(_gWrapped): # overwritten by 1st instance
|
|
|
485
504
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
486
505
|
'''
|
|
487
506
|
gl = _wrapped.GeodesicLine(geodesic, lat1, lon1, azi1, caps=caps, **name)
|
|
488
|
-
_MODS.geodesicw.GeodesicLine = gl
|
|
507
|
+
_MODS.geodesicw.GeodesicLine = type(gl) # overwrite class
|
|
489
508
|
return gl
|
|
490
509
|
|
|
491
510
|
|
pygeodesy/geodesicx/__init__.py
CHANGED
|
@@ -17,13 +17,13 @@ respectively C{GeodesicLine} from I{Karney}'s Python implementation U{geographic
|
|
|
17
17
|
L{pygeodesy.geodesicw} and L{pygeodesy.karney}.
|
|
18
18
|
'''
|
|
19
19
|
|
|
20
|
-
from pygeodesy.geodesicx.gx import GeodesicExact, GeodesicLineExact #
|
|
21
|
-
from pygeodesy.geodesicx.gxarea import GeodesicAreaExact, PolygonArea #
|
|
20
|
+
from pygeodesy.geodesicx.gx import GeodesicExact, GeodesicLineExact # noqa: F401
|
|
21
|
+
from pygeodesy.geodesicx.gxarea import GeodesicAreaExact, PolygonArea # noqa: F401
|
|
22
22
|
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__ = '25.
|
|
26
|
+
__version__ = '25.05.12'
|
|
27
27
|
|
|
28
28
|
# **) MIT License
|
|
29
29
|
#
|
pygeodesy/geodesicx/gx.py
CHANGED
|
@@ -13,7 +13,7 @@ and licensed under the MIT/X11 License. For more information, see the
|
|
|
13
13
|
U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
14
14
|
'''
|
|
15
15
|
# make sure int/int division yields float quotient
|
|
16
|
-
from __future__ import division as _; del _ #
|
|
16
|
+
from __future__ import division as _; del _ # noqa: E702 ;
|
|
17
17
|
|
|
18
18
|
# A copy of comments from Karney's C{GeodesicExact.cpp}:
|
|
19
19
|
#
|
|
@@ -44,11 +44,11 @@ from pygeodesy.constants import EPS, EPS0, EPS02, MANT_DIG, NAN, PI, _EPSqrt, \
|
|
|
44
44
|
from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
45
45
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
46
46
|
from pygeodesy.errors import GeodesicError, _xkwds_pop2
|
|
47
|
-
from pygeodesy.fmath import hypot
|
|
47
|
+
from pygeodesy.fmath import fdot_, hypot, hypot2, Fmt
|
|
48
48
|
from pygeodesy.fsums import fsumf_, fsum1f_
|
|
49
49
|
from pygeodesy.geodesicx.gxbases import _cosSeries, _GeodesicBase, \
|
|
50
50
|
_sincos12, _sin1cos2, _sinf1cos2d, \
|
|
51
|
-
_TINY, _xnC4
|
|
51
|
+
_TINY, _toNAN, _xnC4
|
|
52
52
|
from pygeodesy.geodesicx.gxline import _GeodesicLineExact, _update_glXs
|
|
53
53
|
# from pygeodesy.internals import typename # from .basics
|
|
54
54
|
from pygeodesy.interns import NN, _DOT_, _UNDER_
|
|
@@ -65,7 +65,7 @@ from pygeodesy.utily import atan2, atan2d as _atan2d_reverse, _unrollon, \
|
|
|
65
65
|
from math import copysign, cos, degrees, fabs, radians, sqrt
|
|
66
66
|
|
|
67
67
|
__all__ = ()
|
|
68
|
-
__version__ = '25.
|
|
68
|
+
__version__ = '25.05.28'
|
|
69
69
|
|
|
70
70
|
_MAXIT1 = 20
|
|
71
71
|
_MAXIT2 = 10 + _MAXIT1 + MANT_DIG # MANT_DIG == C++ digits
|
|
@@ -96,15 +96,12 @@ def _eTOL2(f):
|
|
|
96
96
|
# (bet1 + bet2) / 2, the relative error in the azimuth
|
|
97
97
|
# consistency check is sig12^2 * abs(f) * min(1, 1-f/2) / 2.
|
|
98
98
|
# (Error measured for 1/100 < b/a < 100 and abs(f) >= 1/1000.
|
|
99
|
-
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
# Here 0.1 is a safety factor (error decreased by 100) and
|
|
106
|
-
# max(0.001, abs(f)) stops etol2 getting too large in the
|
|
107
|
-
# nearly spherical case.
|
|
99
|
+
# For a given f and sig12, the max error occurs for lines
|
|
100
|
+
# near the pole. If the old rule for computing dnm = (dn1 +
|
|
101
|
+
# dn2)/2 is used, then the error increases by a factor of 2.)
|
|
102
|
+
# Setting this equal to epsilon gives sig12 = eTOL2. Here,
|
|
103
|
+
# safety factor 0.1 (error decreased by 100) and max(0.001, abs(f))
|
|
104
|
+
# stops eTOL2 getting too large in the nearly spherical case.
|
|
108
105
|
t = min(_1_0, _1_0 - f * _0_5) * max(_0_001, fabs(f)) * _0_5
|
|
109
106
|
return _TOL3 / (sqrt(t) if t > EPS02 else EPS0)
|
|
110
107
|
|
|
@@ -216,11 +213,10 @@ class GeodesicExact(_GeodesicBase):
|
|
|
216
213
|
return GeodesicLineExact(self, lat1, lon1, azi1, caps=caps, **name)._GenSet(self._debug, a12=a12)
|
|
217
214
|
|
|
218
215
|
def Area(self, polyline=False, **name):
|
|
219
|
-
'''Set up a L{GeodesicAreaExact} to compute area and
|
|
220
|
-
perimeter of a polygon.
|
|
216
|
+
'''Set up a L{GeodesicAreaExact} to compute area and perimeter of a polygon.
|
|
221
217
|
|
|
222
|
-
@kwarg polyline: If C{True}, compute the perimeter only, otherwise
|
|
223
|
-
|
|
218
|
+
@kwarg polyline: If C{True}, compute the perimeter only, otherwise the
|
|
219
|
+
perimeter and area (C{bool}).
|
|
224
220
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
225
221
|
|
|
226
222
|
@return: A L{GeodesicAreaExact} instance.
|
|
@@ -429,17 +425,21 @@ class GeodesicExact(_GeodesicBase):
|
|
|
429
425
|
def _eF_reset_cHe2_f1(self, x, y):
|
|
430
426
|
'''(INTERNAL) Reset elliptic function and return M{cH * e2 / f1 * ...}.
|
|
431
427
|
'''
|
|
432
|
-
|
|
433
|
-
|
|
428
|
+
if isnan(x):
|
|
429
|
+
y = NAN
|
|
430
|
+
else:
|
|
431
|
+
self._eF_reset_k2(x)
|
|
432
|
+
y *= self._eF.cH * self._e2_f1
|
|
433
|
+
return y
|
|
434
434
|
|
|
435
435
|
def _eF_reset_k2(self, x):
|
|
436
436
|
'''(INTERNAL) Reset elliptic function and return C{k2}.
|
|
437
437
|
'''
|
|
438
438
|
ep2 = self.ep2
|
|
439
|
-
|
|
440
|
-
self._eF.reset(k2=-
|
|
439
|
+
x *= x * ep2 # see .gxline._GeodesicLineExact._eF
|
|
440
|
+
self._eF.reset(k2=-x, alpha2=-ep2) # kp2, alphap2 defaults
|
|
441
441
|
_update_glXs(self) # zap cached/memoized _GeodesicLineExact attrs
|
|
442
|
-
return
|
|
442
|
+
return x
|
|
443
443
|
|
|
444
444
|
@Property_RO
|
|
445
445
|
def ellipsoid(self):
|
|
@@ -499,6 +499,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
499
499
|
if self._debug: # PYCHOK no cover
|
|
500
500
|
outmask |= Cs._DEBUG_INVERSE & self._debug
|
|
501
501
|
outmask &= Cs._OUT_MASK # incl. _SALP_CALPs_ and _DEBUG_
|
|
502
|
+
toNAN = _toNAN(outmask, lat1, lon1, lat2, lon2)
|
|
502
503
|
# compute longitude difference carefully (with _diff182):
|
|
503
504
|
# result is in [-180, +180] but -180 is only for west-going
|
|
504
505
|
# geodesics, +180 is for east-going and meridional geodesics
|
|
@@ -700,7 +701,9 @@ class GeodesicExact(_GeodesicBase):
|
|
|
700
701
|
eFk2=eF.k2, eFa2=eF.alpha2)
|
|
701
702
|
p.update(r) # r overrides p
|
|
702
703
|
r = p.toGDict()
|
|
703
|
-
|
|
704
|
+
|
|
705
|
+
r = self._iter2tion(r, **p)
|
|
706
|
+
return r._toNAN(outmask) if toNAN else r
|
|
704
707
|
|
|
705
708
|
def _GenDirect(self, lat1, lon1, azi1, arcmode, s12_a12, outmask=Caps.STANDARD):
|
|
706
709
|
'''(INTERNAL) The general I{Inverse} geodesic calculation.
|
|
@@ -805,8 +808,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
805
808
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>} and
|
|
806
809
|
Python U{Geodesic.InverseLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
807
810
|
'''
|
|
808
|
-
|
|
809
|
-
r = self._GDictInverse(lat1, lon1, lat2, lon2, caps | Cs._SALP_CALPs_)
|
|
811
|
+
r = self._GDictInverse(lat1, lon1, lat2, lon2, caps | Caps._SALP_CALPs_)
|
|
810
812
|
return GeodesicLineExact(self, lat1, lon1, None, caps=caps, _s_calp1=(r.salp1, r.calp1),
|
|
811
813
|
**name)._GenSet(self._debug, **r)
|
|
812
814
|
|
|
@@ -839,12 +841,12 @@ class GeodesicExact(_GeodesicBase):
|
|
|
839
841
|
# (tan(bet1/2) + tan(bet2/2)) /
|
|
840
842
|
# (tan(bet1/2) * tan(bet2/2) + 1))
|
|
841
843
|
# with tan(x/2) = sin(x) / (1 + cos(x))
|
|
842
|
-
dbet1 =
|
|
843
|
-
dbet2 =
|
|
844
|
-
domg12 =
|
|
845
|
-
salp12 = (p.sbet1
|
|
846
|
-
calp12 = (p.sbet1
|
|
847
|
-
alp12 =
|
|
844
|
+
dbet1 = p.cbet1 + _1_0
|
|
845
|
+
dbet2 = p.cbet2 + _1_0
|
|
846
|
+
domg12 = comg12 + _1_0
|
|
847
|
+
salp12 = fdot_(p.sbet1, dbet2, dbet1, p.sbet2) * somg12
|
|
848
|
+
calp12 = fdot_(p.sbet1, p.sbet2, dbet1, dbet2) * domg12
|
|
849
|
+
alp12 = atan2(salp12, calp12) * _2_0
|
|
848
850
|
else:
|
|
849
851
|
# alp12 = alp2 - alp1, used in atan2, no need to normalize
|
|
850
852
|
salp12, calp12 = _sincos12(salp1, calp1, salp2, calp2)
|
|
@@ -870,7 +872,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
870
872
|
and C{p.set_sigs} updated for Newton, C{sig12=None}.
|
|
871
873
|
'''
|
|
872
874
|
sig12 = None # use Newton
|
|
873
|
-
salp1 = calp1 = salp2 = calp2 =
|
|
875
|
+
salp1 = calp1 = salp2 = calp2 = NAN
|
|
874
876
|
|
|
875
877
|
# bet12 = bet2 - bet1 in [0, PI)
|
|
876
878
|
sbet12, cbet12 = _sincos12(p.sbet1, p.cbet1, p.sbet2, p.cbet2)
|
|
@@ -878,12 +880,15 @@ class GeodesicExact(_GeodesicBase):
|
|
|
878
880
|
if shortline:
|
|
879
881
|
# sin((bet1 + bet2)/2)^2 = (sbet1 + sbet2)^2 / (
|
|
880
882
|
# (cbet1 + cbet2)^2 + (sbet1 + sbet2)^2)
|
|
881
|
-
t =
|
|
882
|
-
|
|
883
|
-
|
|
883
|
+
t = p.sbet1 + p.sbet2
|
|
884
|
+
if t:
|
|
885
|
+
t *= t / hypot2(t, p.cbet1 + p.cbet2)
|
|
886
|
+
dnm = sqrt(self.ep2 * t + _1_0)
|
|
887
|
+
else:
|
|
888
|
+
dnm = _1_0
|
|
884
889
|
somg12, comg12 = _sincos2(lam12 / (self.f1 * dnm))
|
|
885
890
|
else:
|
|
886
|
-
somg12, comg12 = p.slam12, p.clam12
|
|
891
|
+
somg12, comg12, dnm = p.slam12, p.clam12, NAN
|
|
887
892
|
|
|
888
893
|
# bet12a = bet2 + bet1 in (-PI, 0], note -sbet1
|
|
889
894
|
sbet12a, cbet12a = _sincos12(-p.sbet1, p.cbet1, p.sbet2, p.cbet2)
|
|
@@ -894,8 +899,8 @@ class GeodesicExact(_GeodesicBase):
|
|
|
894
899
|
salp1 = p.cbet2 * somg12
|
|
895
900
|
calp1 = (sbet12a - t) if comg12 < 0 else (sbet12 + t)
|
|
896
901
|
|
|
897
|
-
ssig12 =
|
|
898
|
-
csig12 =
|
|
902
|
+
ssig12 = hypot(salp1, calp1)
|
|
903
|
+
csig12 = fdot_(p.sbet1, p.sbet2, p.cbet1, p.cbet2 * comg12)
|
|
899
904
|
|
|
900
905
|
if shortline and ssig12 < self._eTOL2: # really short lines
|
|
901
906
|
t = c if comg12 < 0 else s
|
|
@@ -970,8 +975,8 @@ class GeodesicExact(_GeodesicBase):
|
|
|
970
975
|
#
|
|
971
976
|
# omg12 is near PI, estimate work with omg12a = PI - omg12
|
|
972
977
|
k = _Astroid(x, y)
|
|
973
|
-
|
|
974
|
-
|
|
978
|
+
k1 = _1_0 + k
|
|
979
|
+
sca *= (y * k1 / k) if f < 0 else (x * k / k1)
|
|
975
980
|
s, c = _sincos2(-sca) # omg12a
|
|
976
981
|
# update spherical estimate of alp1 using omg12 instead of lam12
|
|
977
982
|
salp1 = p.cbet2 * s
|
|
@@ -1082,16 +1087,15 @@ class GeodesicExact(_GeodesicBase):
|
|
|
1082
1087
|
# Missing a factor of self.b. Add parens around
|
|
1083
1088
|
# (csig1 * ssig2) and (ssig1 * csig2) to ensure
|
|
1084
1089
|
# accurate cancellation for coincident points.
|
|
1085
|
-
m12b =
|
|
1086
|
-
|
|
1087
|
-
|
|
1090
|
+
m12b = fdot_(p.dn2, (p.csig1 * p.ssig2),
|
|
1091
|
+
-p.dn1, (p.ssig1 * p.csig2),
|
|
1092
|
+
J12, (p.csig1 * p.csig2))
|
|
1088
1093
|
if (outmask & Cs.GEODESICSCALE):
|
|
1089
|
-
M12 = M21 = p.ssig1
|
|
1090
|
-
p.csig1 * p.csig2
|
|
1094
|
+
M12 = M21 = fdot_(p.ssig1, p.ssig2, p.csig1, p.csig2)
|
|
1091
1095
|
t = (p.cbet1 - p.cbet2) * self.ep2 * \
|
|
1092
1096
|
(p.cbet1 + p.cbet2) / (p.dn1 + p.dn2)
|
|
1093
|
-
M12 += (p.ssig2
|
|
1094
|
-
M21 -= (p.ssig1
|
|
1097
|
+
M12 += fdot_(p.ssig2, t, p.csig2, J12) * p.ssig1 / p.dn1
|
|
1098
|
+
M21 -= fdot_(p.ssig1, t, p.csig1, J12) * p.ssig2 / p.dn2
|
|
1095
1099
|
|
|
1096
1100
|
return s12b, m12b, m0, M12, M21
|
|
1097
1101
|
|
|
@@ -1310,7 +1314,7 @@ def _Astroid(x, y):
|
|
|
1310
1314
|
u = _cbrt(S * _2_0) # == T3 + _copysign(abs(S), T3)
|
|
1311
1315
|
else:
|
|
1312
1316
|
u = _0_0
|
|
1313
|
-
v =
|
|
1317
|
+
v = hypot(u, y) # sqrt(u**2 + q)
|
|
1314
1318
|
# avoid loss of accuracy when u < 0
|
|
1315
1319
|
u = (q / (v - u)) if u < 0 else (v + u)
|
|
1316
1320
|
w = (u - q) / (v + v) # positive?
|