pygeodesy 24.9.29__py2.py3-none-any.whl → 24.10.24__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/METADATA +15 -15
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/RECORD +56 -56
- pygeodesy/__init__.py +20 -19
- pygeodesy/__main__.py +5 -5
- pygeodesy/albers.py +12 -17
- pygeodesy/basics.py +38 -41
- pygeodesy/booleans.py +54 -46
- pygeodesy/cartesianBase.py +2 -2
- pygeodesy/constants.py +20 -16
- pygeodesy/datums.py +3 -3
- pygeodesy/dms.py +250 -270
- pygeodesy/ellipsoidalBase.py +2 -2
- pygeodesy/ellipsoidalBaseDI.py +10 -10
- pygeodesy/ellipsoidalNvector.py +4 -4
- pygeodesy/ellipsoidalVincenty.py +2 -2
- pygeodesy/ellipsoids.py +7 -48
- pygeodesy/elliptic.py +14 -14
- pygeodesy/errors.py +15 -10
- pygeodesy/etm.py +18 -2
- pygeodesy/fmath.py +188 -176
- pygeodesy/formy.py +4 -4
- pygeodesy/fstats.py +54 -56
- pygeodesy/fsums.py +304 -266
- pygeodesy/geodesici.py +43 -40
- pygeodesy/geodesicw.py +3 -3
- pygeodesy/geodesicx/gxarea.py +3 -2
- pygeodesy/geodsolve.py +73 -24
- pygeodesy/geohash.py +2 -2
- pygeodesy/geoids.py +28 -27
- pygeodesy/internals.py +156 -85
- pygeodesy/interns.py +23 -20
- pygeodesy/karney.py +61 -12
- pygeodesy/latlonBase.py +13 -15
- pygeodesy/lazily.py +206 -214
- pygeodesy/mgrs.py +13 -13
- pygeodesy/named.py +11 -10
- pygeodesy/nvectorBase.py +1 -1
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +34 -13
- pygeodesy/rhumb/bases.py +5 -5
- pygeodesy/rhumb/solve.py +7 -8
- pygeodesy/solveBase.py +7 -25
- pygeodesy/sphericalBase.py +20 -23
- pygeodesy/sphericalNvector.py +24 -23
- pygeodesy/sphericalTrigonometry.py +9 -8
- pygeodesy/streprs.py +11 -8
- pygeodesy/trf.py +6 -4
- pygeodesy/triaxials.py +46 -9
- pygeodesy/units.py +4 -3
- pygeodesy/ups.py +6 -6
- pygeodesy/utily.py +2 -2
- pygeodesy/utm.py +2 -2
- pygeodesy/vector3d.py +5 -5
- pygeodesy/vector3dBase.py +4 -5
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/top_level.txt +0 -0
pygeodesy/booleans.py
CHANGED
|
@@ -23,7 +23,7 @@ from pygeodesy.errors import ClipError, _IsnotError, _TypeError, \
|
|
|
23
23
|
_ValueError, _xattr, _xkwds_get, _xkwds_pop2
|
|
24
24
|
from pygeodesy.fmath import favg, hypot, hypot2
|
|
25
25
|
# from pygeodesy.fsums import fsum1 # _MODS
|
|
26
|
-
from pygeodesy.interns import NN, _BANG_,
|
|
26
|
+
from pygeodesy.interns import NN, _BANG_, _clipid_, _COMMASPACE_, \
|
|
27
27
|
_composite_, _DOT_, _duplicate_, _e_, \
|
|
28
28
|
_ELLIPSIS_, _few_, _height_, _lat_, _LatLon_, \
|
|
29
29
|
_lon_, _not_, _points_, _SPACE_, _too_, _X_, \
|
|
@@ -43,7 +43,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
|
|
|
43
43
|
# from math import fabs # from .utily
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.booleans
|
|
46
|
-
__version__ = '24.
|
|
46
|
+
__version__ = '24.10.22'
|
|
47
47
|
|
|
48
48
|
_0_EPS = EPS # near-zero, positive
|
|
49
49
|
_EPS_0 = -EPS # near-zero, negative
|
|
@@ -326,6 +326,21 @@ class LatLonFHP(_LatLonBool):
|
|
|
326
326
|
_xscalar(other=other)
|
|
327
327
|
return self.__class__(self.y * other, self.x * other)
|
|
328
328
|
|
|
329
|
+
# def _edge2(self):
|
|
330
|
+
# # Return the start and end point of the
|
|
331
|
+
# # edge containing I{intersection} C{v}.
|
|
332
|
+
# n = p = self
|
|
333
|
+
# while p.isintersection:
|
|
334
|
+
# p = p._prev
|
|
335
|
+
# if p is self:
|
|
336
|
+
# break
|
|
337
|
+
# while n.isintersection:
|
|
338
|
+
# n = n._next
|
|
339
|
+
# if n is self:
|
|
340
|
+
# break
|
|
341
|
+
# # assert p == self or not p._2Abs(self, n)
|
|
342
|
+
# return p, n
|
|
343
|
+
|
|
329
344
|
def _e_x_str(self, t): # PYCHOK no cover
|
|
330
345
|
if self._label:
|
|
331
346
|
t = NN(self._label, t)
|
|
@@ -417,21 +432,6 @@ class LatLonFHP(_LatLonBool):
|
|
|
417
432
|
n = n._next
|
|
418
433
|
return p._prev, n
|
|
419
434
|
|
|
420
|
-
# def _edge2(self):
|
|
421
|
-
# # Return the start and end point of the
|
|
422
|
-
# # edge containing I{intersection} C{v}.
|
|
423
|
-
# n = p = self
|
|
424
|
-
# while p.isintersection:
|
|
425
|
-
# p = p._prev
|
|
426
|
-
# if p is self:
|
|
427
|
-
# break
|
|
428
|
-
# while n.isintersection:
|
|
429
|
-
# n = n._next
|
|
430
|
-
# if n is self:
|
|
431
|
-
# break
|
|
432
|
-
# # assert p == self or not p._2Abs(self, n)
|
|
433
|
-
# return p, n
|
|
434
|
-
|
|
435
435
|
def _RPoracle(self, p1, p2, p3):
|
|
436
436
|
# Relative Position oracle
|
|
437
437
|
if p1._linked is self: # or p1._linked2(self):
|
|
@@ -729,7 +729,7 @@ class _Clip(_Named):
|
|
|
729
729
|
try:
|
|
730
730
|
i = cp._clips.index(self)
|
|
731
731
|
if i != self._id:
|
|
732
|
-
kwds
|
|
732
|
+
kwds.update(clip=i)
|
|
733
733
|
except ValueError:
|
|
734
734
|
pass
|
|
735
735
|
kwds[_clipid_] = self._id
|
|
@@ -1201,7 +1201,7 @@ class _CompositeFHP(_CompositeBase):
|
|
|
1201
1201
|
def _clip(self, corners, Union=False, Clas=None,
|
|
1202
1202
|
**closed_inull_raiser_eps):
|
|
1203
1203
|
# Clip this composite with another one, C{corners},
|
|
1204
|
-
# using Foster-Hormann-Popa's algorithm.
|
|
1204
|
+
# using the Foster-Hormann-Popa's algorithm.
|
|
1205
1205
|
P = self
|
|
1206
1206
|
Q = self._class(corners, closed_inull_raiser_eps,
|
|
1207
1207
|
eps=P._eps, raiser=False)
|
|
@@ -1442,6 +1442,7 @@ class _CompositeGH(_CompositeBase):
|
|
|
1442
1442
|
raiser=False, xtend=False)
|
|
1443
1443
|
bt = C._bottom_top_eps2
|
|
1444
1444
|
lr = C._left_right_eps2
|
|
1445
|
+
|
|
1445
1446
|
# 1. find intersections
|
|
1446
1447
|
for s1, s2, Sc in S._edges3(**closed_inull_raiser_xtend_eps):
|
|
1447
1448
|
if not (_outside(s1.x, s2.x, *lr) or
|
|
@@ -1546,7 +1547,7 @@ class _EdgeFHP(object):
|
|
|
1546
1547
|
dq = q2 - q1
|
|
1547
1548
|
dq2 = dq * dq # dot product, hypot2
|
|
1548
1549
|
if dq2 > EPS2: # like ._clip
|
|
1549
|
-
T,
|
|
1550
|
+
T, _E = None, _EdgeFHP # self.__class__
|
|
1550
1551
|
p1, p2 = self._p1_p2
|
|
1551
1552
|
ap1 = p1._2A(q1, q2)
|
|
1552
1553
|
ap2_1 = p2._2A(q1, q2) - ap1
|
|
@@ -1558,10 +1559,10 @@ class _EdgeFHP(object):
|
|
|
1558
1559
|
a, a_0, a_0_1, _ = _alpha4(-ap1 / ap2_1)
|
|
1559
1560
|
b, b_0, b_0_1, _ = _alpha4(-aq1 / aq2_1)
|
|
1560
1561
|
# distinguish intersection types
|
|
1561
|
-
T =
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1562
|
+
T = _E.X_INTERSECT if a_0_1 and b_0_1 else (
|
|
1563
|
+
_E.P_INTERSECT if a_0_1 and b_0 else (
|
|
1564
|
+
_E.Q_INTERSECT if a_0 and b_0_1 else (
|
|
1565
|
+
_E.V_INTERSECT if a_0 and b_0 else None)))
|
|
1565
1566
|
|
|
1566
1567
|
elif fabs(ap1) < _0_EPS: # parallel or colinear edges
|
|
1567
1568
|
dp = self._dp
|
|
@@ -1570,21 +1571,21 @@ class _EdgeFHP(object):
|
|
|
1570
1571
|
a, a_0, a_0_1, _a_0_1 = _alpha4((d1 * dp) / self._dp2)
|
|
1571
1572
|
b, b_0, b_0_1, _b_0_1 = _alpha4((d1 * dq) / (-dq2))
|
|
1572
1573
|
# distinguish overlap type
|
|
1573
|
-
T =
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1574
|
+
T = _E.X_OVERLAP if a_0_1 and b_0_1 else (
|
|
1575
|
+
_E.P_OVERLAP if a_0_1 and _b_0_1 else (
|
|
1576
|
+
_E.Q_OVERLAP if _a_0_1 and b_0_1 else (
|
|
1577
|
+
_E.V_OVERLAP if a_0 and b_0 else None)))
|
|
1577
1578
|
|
|
1578
1579
|
if T:
|
|
1579
|
-
if T is
|
|
1580
|
+
if T is _E.X_INTERSECT:
|
|
1580
1581
|
v = p1 + a * self._dp
|
|
1581
1582
|
yield T, (v, p1, p2, a), (v, q1, q2, b)
|
|
1582
|
-
elif T in
|
|
1583
|
+
elif T in _E.Vs:
|
|
1583
1584
|
yield T, (p1,), (q1,)
|
|
1584
1585
|
else:
|
|
1585
|
-
if T in
|
|
1586
|
+
if T in _E.Qs:
|
|
1586
1587
|
yield T, (p1,), (p1, q1, q2, b)
|
|
1587
|
-
if T in
|
|
1588
|
+
if T in _E.Ps:
|
|
1588
1589
|
yield T, (q1, p1, p2, a), (q1,)
|
|
1589
1590
|
|
|
1590
1591
|
|
|
@@ -1898,9 +1899,9 @@ def _alpha4(a):
|
|
|
1898
1899
|
# Return 4-tuple (alpha, -EPS < alpha < EPS,
|
|
1899
1900
|
# 0 < alpha < 1,
|
|
1900
1901
|
# not 0 < alpha < 1)
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1902
|
+
a_EPS = bool(_EPS_0 < a < _0_EPS)
|
|
1903
|
+
a_0_1 = bool(_0_EPS < a < _EPS_1)
|
|
1904
|
+
return a, a_EPS, a_0_1, (not a_0_1)
|
|
1904
1905
|
|
|
1905
1906
|
|
|
1906
1907
|
def _Cps(Cp, composites_points, where):
|
|
@@ -1914,7 +1915,7 @@ def _Cps(Cp, composites_points, where):
|
|
|
1914
1915
|
|
|
1915
1916
|
|
|
1916
1917
|
def _eps0(eps):
|
|
1917
|
-
# Adjust C{eps} or C{
|
|
1918
|
+
# Adjust C{eps} or C{0}.
|
|
1918
1919
|
return eps if eps and eps > EPS else 0
|
|
1919
1920
|
|
|
1920
1921
|
|
|
@@ -1930,7 +1931,7 @@ def isBoolean(obj):
|
|
|
1930
1931
|
|
|
1931
1932
|
|
|
1932
1933
|
def _left_right_bottom_top_eps2(p1, p2):
|
|
1933
|
-
'''(INTERNAL) Return 2-tuple C{(left, right), (bottom, top)}, oversized.
|
|
1934
|
+
'''(INTERNAL) Return 2-tuple C{((left, right), (bottom, top))}, both oversized.
|
|
1934
1935
|
'''
|
|
1935
1936
|
return (_min_max_eps2(p1.x, p2.x),
|
|
1936
1937
|
_min_max_eps2(p1.y, p2.y))
|
|
@@ -1939,18 +1940,23 @@ def _left_right_bottom_top_eps2(p1, p2):
|
|
|
1939
1940
|
def _low_high_eps2(lo, hi, eps):
|
|
1940
1941
|
'''(INTERNAL) Return 2-tuple C{(lo, hi)}, oversized.
|
|
1941
1942
|
'''
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1943
|
+
# assert eps > 0
|
|
1944
|
+
lo -= fabs(eps * lo)
|
|
1945
|
+
hi += fabs(eps * hi)
|
|
1946
|
+
if lo < hi:
|
|
1947
|
+
pass
|
|
1948
|
+
elif lo > hi:
|
|
1949
|
+
lo, hi = hi, lo
|
|
1950
|
+
else:
|
|
1951
|
+
lo -= eps
|
|
1952
|
+
hi += eps
|
|
1953
|
+
return lo, hi
|
|
1945
1954
|
|
|
1946
1955
|
|
|
1947
1956
|
def _min_max_eps2(*xs):
|
|
1948
1957
|
'''(INTERNAL) Return 2-tuple C{(min, max)}, oversized.
|
|
1949
1958
|
'''
|
|
1950
|
-
|
|
1951
|
-
lo *= _1_EPS if lo < 0 else _EPS_1
|
|
1952
|
-
hi *= _EPS_1 if hi < 0 else _1_EPS
|
|
1953
|
-
return (lo or _EPS_0), (hi or _0_EPS)
|
|
1959
|
+
return _low_high_eps2(min(xs), max(xs), EPS)
|
|
1954
1960
|
|
|
1955
1961
|
|
|
1956
1962
|
def _other(this, other):
|
|
@@ -1963,9 +1969,11 @@ def _other(this, other):
|
|
|
1963
1969
|
|
|
1964
1970
|
|
|
1965
1971
|
def _outside(x1, x2, lo, hi):
|
|
1966
|
-
'''(INTERNAL)
|
|
1972
|
+
'''(INTERNAL) Are C{x1} and C{x2} outside C{(lo, hi)}?
|
|
1967
1973
|
'''
|
|
1968
|
-
|
|
1974
|
+
# assert lo <= hi
|
|
1975
|
+
return (x1 < lo or x2 > hi) if x1 > x2 else \
|
|
1976
|
+
(x2 < lo or x1 > hi)
|
|
1969
1977
|
|
|
1970
1978
|
|
|
1971
1979
|
__all__ += _ALL_DOCS(_BooleanBase, _Clip,
|
pygeodesy/cartesianBase.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
u'''(INTERNAL) Private C{CartesianBase} class for elliposiodal, spherical and N-/vectorial
|
|
5
5
|
C{Cartesian}s and public functions L{rtp2xyz}, L{rtp2xyz_}, L{xyz2rtp} and L{xyz2rtp_}.
|
|
6
6
|
|
|
7
|
-
After I{(C) Chris Veness 2011-
|
|
7
|
+
After I{(C) Chris Veness 2011-2024} published under the same MIT Licence**, see
|
|
8
8
|
U{https://www.Movable-Type.co.UK/scripts/latlong.html},
|
|
9
9
|
U{https://www.Movable-Type.co.UK/scripts/latlong-vectors.html} and
|
|
10
10
|
U{https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html}.
|
|
@@ -43,7 +43,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
|
43
43
|
# from math import atan2, degrees, fabs, radians, sqrt # from .fmath, .utily
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.cartesianBase
|
|
46
|
-
__version__ = '24.
|
|
46
|
+
__version__ = '24.10.12'
|
|
47
47
|
|
|
48
48
|
_r_ = 'r'
|
|
49
49
|
_theta_ = 'theta'
|
pygeodesy/constants.py
CHANGED
|
@@ -26,7 +26,7 @@ except ImportError: # Python 2-
|
|
|
26
26
|
_inf, _nan = float(_INF_), float(_NAN_)
|
|
27
27
|
|
|
28
28
|
__all__ = _ALL_LAZY.constants
|
|
29
|
-
__version__ = '24.
|
|
29
|
+
__version__ = '24.10.15'
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def _copysign_0_0(y):
|
|
@@ -256,7 +256,8 @@ _K0_UTM = _Float(_K0_UTM = 0.9996) # PYCHOK in .etm, .ktm, .utm, UTM scale at
|
|
|
256
256
|
# sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
257
257
|
# 1.414213562373095_048_801_688_724_209_698_078_569_671_875_376_948_073_176_679_737_99
|
|
258
258
|
# _1SQRT2= _Float(_1SQRT2 =sqrt(_2_0) + 1)
|
|
259
|
-
|
|
259
|
+
# 0.707106781186547_524_400_844_362_104_849_039_284_835_937_688_474_036_588_339_868_99
|
|
260
|
+
_SQRT2_2 = _Float(_SQRT2_2=sqrt(_0_5)) # PYCHOK = 0.707106781186547_5 == sqrt(2) / 2
|
|
260
261
|
|
|
261
262
|
INF = Float(INF =_inf) # PYCHOK INFinity, see function L{isinf}, L{isfinite}, NOT _Float!
|
|
262
263
|
INT0 = Int( INT0= 0) # PYCHOK unique int(0) instance, see .fsums, useZ=False
|
|
@@ -494,20 +495,23 @@ def _umod_PI2(rad):
|
|
|
494
495
|
|
|
495
496
|
if __name__ == '__main__':
|
|
496
497
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
498
|
+
def _main():
|
|
499
|
+
from pygeodesy import itemsorted, printf
|
|
500
|
+
|
|
501
|
+
t = n = v = []
|
|
502
|
+
for n, v in itemsorted(locals()):
|
|
503
|
+
if isinstance(v, (Float, Int, Radius)):
|
|
504
|
+
printf('%9s: %r', n, v.toRepr(std=False))
|
|
505
|
+
if v.name != n:
|
|
506
|
+
raise AssertionError('%r != %r' % (n, v))
|
|
507
|
+
if v.name is not n:
|
|
508
|
+
raise AssertionError('%r is not %r' % (n, v))
|
|
509
|
+
if not n.startswith(_UNDER_):
|
|
510
|
+
t.append(n)
|
|
511
|
+
t.append(float_.__name__)
|
|
512
|
+
printf('__all__ = %r', tuple(t))
|
|
513
|
+
|
|
514
|
+
_main()
|
|
511
515
|
|
|
512
516
|
# **) MIT License
|
|
513
517
|
#
|
pygeodesy/datums.py
CHANGED
|
@@ -8,7 +8,7 @@ Classes L{Datum} and L{Transform} and registries L{Datums} and L{Transforms}, re
|
|
|
8
8
|
Pure Python implementation of geodesy tools for ellipsoidal earth models, including datums
|
|
9
9
|
and ellipsoid parameters for different geographic coordinate systems and methods for
|
|
10
10
|
converting between them and to cartesian coordinates. Transcoded from JavaScript originals by
|
|
11
|
-
I{(C) Chris Veness 2005-
|
|
11
|
+
I{(C) Chris Veness 2005-2024} and published under the same MIT Licence**, see U{latlon-ellipsoidal.js
|
|
12
12
|
<https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html>}.
|
|
13
13
|
|
|
14
14
|
Historical geodetic datums: a latitude/longitude point defines a geographic location on, above
|
|
@@ -94,7 +94,7 @@ from pygeodesy.units import _isRadius, Radius_, radians
|
|
|
94
94
|
# import operator as _operator # from .fmath
|
|
95
95
|
|
|
96
96
|
__all__ = _ALL_LAZY.datums
|
|
97
|
-
__version__ = '24.
|
|
97
|
+
__version__ = '24.10.12'
|
|
98
98
|
|
|
99
99
|
_a_ellipsoid_ = _UNDER_(_a_, _ellipsoid_)
|
|
100
100
|
_BD72_ = 'BD72'
|
|
@@ -610,7 +610,7 @@ def _mean_radius(radius, *lats):
|
|
|
610
610
|
return r
|
|
611
611
|
|
|
612
612
|
|
|
613
|
-
def _negastr(name): # in .trf
|
|
613
|
+
def _negastr(name): # in .trf, test/testTrf
|
|
614
614
|
'''(INTERNAL) Negate a C{Transform/-Xform} name.
|
|
615
615
|
'''
|
|
616
616
|
b, m, p = _BAR_, _MINUS_, _PLUS_
|