pygeodesy 25.5.25__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 +1 -1
- pygeodesy/__main__.py +2 -1
- pygeodesy/booleans.py +10 -10
- pygeodesy/constants.py +6 -6
- pygeodesy/css.py +1 -1
- pygeodesy/ellipsoidalExact.py +22 -27
- pygeodesy/ellipsoidalGeodSolve.py +19 -19
- pygeodesy/ellipsoidalKarney.py +22 -27
- pygeodesy/ellipsoidalVincenty.py +12 -11
- pygeodesy/elliptic.py +15 -10
- pygeodesy/frechet.py +2 -2
- pygeodesy/geodesicw.py +27 -8
- pygeodesy/geodesicx/gx.py +51 -47
- pygeodesy/geodesicx/gxarea.py +53 -64
- pygeodesy/geodesicx/gxbases.py +12 -2
- pygeodesy/geodesicx/gxline.py +9 -6
- pygeodesy/geoids.py +1 -1
- pygeodesy/hausdorff.py +2 -2
- pygeodesy/heights.py +4 -4
- pygeodesy/internals.py +2 -2
- pygeodesy/interns.py +5 -5
- pygeodesy/karney.py +27 -11
- pygeodesy/lcc.py +2 -2
- pygeodesy/props.py +3 -3
- pygeodesy/sphericalBase.py +3 -3
- pygeodesy/sphericalNvector.py +18 -15
- pygeodesy/sphericalTrigonometry.py +19 -20
- pygeodesy/vector2d.py +2 -2
- {pygeodesy-25.5.25.dist-info → pygeodesy-25.5.28.dist-info}/METADATA +2 -2
- {pygeodesy-25.5.25.dist-info → pygeodesy-25.5.28.dist-info}/RECORD +32 -32
- {pygeodesy-25.5.25.dist-info → pygeodesy-25.5.28.dist-info}/WHEEL +0 -0
- {pygeodesy-25.5.25.dist-info → pygeodesy-25.5.28.dist-info}/top_level.txt +0 -0
pygeodesy/__init__.py
CHANGED
|
@@ -604,7 +604,7 @@ else:
|
|
|
604
604
|
|
|
605
605
|
from pygeodesy.internals import _version2, _DOT_ # noqa: E402
|
|
606
606
|
# from pygeodesy.interns import _DOT_ # from .internals
|
|
607
|
-
__version__ = '25.05.
|
|
607
|
+
__version__ = '25.05.28'
|
|
608
608
|
# see setup.py for similar logic
|
|
609
609
|
version = _DOT_(*_version2(__version__, n=3))
|
|
610
610
|
|
pygeodesy/__main__.py
CHANGED
|
@@ -5,7 +5,7 @@ u'''Print L{pygeodesy} version, etc. using C{python -m pygeodesy}.
|
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
7
|
__all__ = ()
|
|
8
|
-
__version__ = '25.
|
|
8
|
+
__version__ = '25.06.26'
|
|
9
9
|
|
|
10
10
|
from os.path import basename, dirname
|
|
11
11
|
|
|
@@ -28,6 +28,7 @@ def _main(): # PYCHOK no cover
|
|
|
28
28
|
('isLazy', isLazy),
|
|
29
29
|
('_isfrozen', _isfrozen),
|
|
30
30
|
('_floats', len(constants._floats)),
|
|
31
|
+
# ('_interns', len(interns.__dict__) - 22),
|
|
31
32
|
(_DALL_, len(_all_imports())),
|
|
32
33
|
(_DEPRECATED_, len(_all_deprecates()))))
|
|
33
34
|
|
pygeodesy/booleans.py
CHANGED
|
@@ -45,7 +45,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
|
|
|
45
45
|
# from math import fabs # from .utily
|
|
46
46
|
|
|
47
47
|
__all__ = _ALL_LAZY.booleans
|
|
48
|
-
__version__ = '25.05.
|
|
48
|
+
__version__ = '25.05.26'
|
|
49
49
|
|
|
50
50
|
_0EPS = EPS # near-zero, positive
|
|
51
51
|
_EPS0 = -EPS # near-zero, negative
|
|
@@ -199,8 +199,8 @@ class _LatLonBool(_Named):
|
|
|
199
199
|
|
|
200
200
|
def __sub__(self, other):
|
|
201
201
|
_other(self, other)
|
|
202
|
-
return self
|
|
203
|
-
|
|
202
|
+
return type(self)(self.y - other.y, # classof
|
|
203
|
+
self.x - other.x)
|
|
204
204
|
|
|
205
205
|
def _2A(self, p2, p3):
|
|
206
206
|
# I{Signed} area of a triangle, I{doubled}.
|
|
@@ -314,7 +314,7 @@ class LatLonFHP(_LatLonBool):
|
|
|
314
314
|
|
|
315
315
|
def __add__(self, other):
|
|
316
316
|
_other(self, other)
|
|
317
|
-
return self
|
|
317
|
+
return type(self)(self.y + other.y, self.x + other.x)
|
|
318
318
|
|
|
319
319
|
def __mod__(self, other): # cross product
|
|
320
320
|
_other(self, other)
|
|
@@ -326,7 +326,7 @@ class LatLonFHP(_LatLonBool):
|
|
|
326
326
|
|
|
327
327
|
def __rmul__(self, other): # scalar product
|
|
328
328
|
_xscalar(other=other)
|
|
329
|
-
return self
|
|
329
|
+
return type(self)(self.y * other, self.x * other)
|
|
330
330
|
|
|
331
331
|
# def _edge2(self):
|
|
332
332
|
# # Return the start and end point of the
|
|
@@ -959,7 +959,7 @@ class _CompositeBase(_Named):
|
|
|
959
959
|
# Return a new instance
|
|
960
960
|
_g = kwds.get
|
|
961
961
|
kwds = dict((n, _g(n, v)) for n, v in dflts.items())
|
|
962
|
-
return self
|
|
962
|
+
return type(self)(corners or (), **kwds)
|
|
963
963
|
|
|
964
964
|
@property_RO
|
|
965
965
|
def _clipids(self): # PYCHOK no cover
|
|
@@ -1549,7 +1549,7 @@ class _EdgeFHP(object):
|
|
|
1549
1549
|
dq = q2 - q1
|
|
1550
1550
|
dq2 = dq * dq # dot product, hypot2
|
|
1551
1551
|
if dq2 > EPS2: # like ._clip
|
|
1552
|
-
T, _E = None, _EdgeFHP # self
|
|
1552
|
+
T, _E = None, _EdgeFHP # type(self)
|
|
1553
1553
|
p1, p2 = self._p1_p2
|
|
1554
1554
|
ap1 = p1._2A(q1, q2)
|
|
1555
1555
|
ap2_1 = p2._2A(q1, q2) - ap1
|
|
@@ -1750,8 +1750,8 @@ class _BooleanBase(object):
|
|
|
1750
1750
|
|
|
1751
1751
|
def _boolean4(self, other, op):
|
|
1752
1752
|
# Set up a new C{Boolean[FHP|GH]}.
|
|
1753
|
-
C = self
|
|
1754
|
-
kwds = C._kwds(self, op)
|
|
1753
|
+
C = type(self)
|
|
1754
|
+
kwds = C._kwds(self, op) # PYCHOK in _Composite[FHP|GH]
|
|
1755
1755
|
a = C(self, **kwds)
|
|
1756
1756
|
b = _other(self, other)
|
|
1757
1757
|
return a, b, C, kwds
|
|
@@ -1964,7 +1964,7 @@ def _min_max_eps2(*xs):
|
|
|
1964
1964
|
def _other(this, other):
|
|
1965
1965
|
'''(INTERNAL) Check for compatible C{type}s.
|
|
1966
1966
|
'''
|
|
1967
|
-
C = this
|
|
1967
|
+
C = type(this)
|
|
1968
1968
|
if isinstance(other, C):
|
|
1969
1969
|
return other
|
|
1970
1970
|
raise _IsnotError(C, other=other)
|
pygeodesy/constants.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
u'''Single-instance C{float} and C{int} constants across C{pygeodesy} modules and
|
|
5
|
-
|
|
4
|
+
u'''Single-instance C{float} and C{int} constants across C{pygeodesy} modules and related
|
|
5
|
+
functions L{pygeodesy.float_}, L{pygeodesy.float0_}, L{pygeodesy.isclose}, L{pygeodesy.isfinite},
|
|
6
6
|
L{pygeodesy.isinf}, L{pygeodesy.isint0}, L{pygeodesy.isnan}, L{pygeodesy.isnear0},
|
|
7
7
|
L{pygeodesy.isnear1}, L{pygeodesy.isnear90}, L{pygeodesy.isneg0}, L{pygeodesy.isninf},
|
|
8
8
|
L{pygeodesy.isnon0} and L{pygeodesy.remainder}.
|
|
@@ -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__ = '25.05.
|
|
29
|
+
__version__ = '25.05.26'
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def _copysign_0_0(y):
|
|
@@ -495,12 +495,12 @@ def _umod_PI2(rad):
|
|
|
495
495
|
|
|
496
496
|
if __name__ == _DMAIN_:
|
|
497
497
|
|
|
498
|
-
def _main(
|
|
498
|
+
def _main(globalocals):
|
|
499
499
|
from pygeodesy import itemsorted, printf
|
|
500
500
|
from pygeodesy.interns import _DALL_, _UNDER_
|
|
501
501
|
|
|
502
502
|
t = n = v = []
|
|
503
|
-
for n, v in itemsorted(
|
|
503
|
+
for n, v in itemsorted(globalocals):
|
|
504
504
|
if isinstance(v, (Float, Int, Radius)):
|
|
505
505
|
printf('%9s: %r', n, v.toRepr(std=False))
|
|
506
506
|
if v.name != n:
|
|
@@ -512,7 +512,7 @@ if __name__ == _DMAIN_:
|
|
|
512
512
|
t.append(typename(float_))
|
|
513
513
|
printf('%s = %r', _DALL_, tuple(t))
|
|
514
514
|
|
|
515
|
-
_main(locals()
|
|
515
|
+
_main(globals()) # or locals()
|
|
516
516
|
|
|
517
517
|
# **) MIT License
|
|
518
518
|
#
|
pygeodesy/css.py
CHANGED
|
@@ -470,7 +470,7 @@ class Css(_NamedBase):
|
|
|
470
470
|
# h=self.height, cs0=self.cs0,
|
|
471
471
|
# name=_name__(name, _or_nameof(self)))
|
|
472
472
|
# args, kwds = _args_kwds(**kwds)
|
|
473
|
-
# return self
|
|
473
|
+
# return type(self)(*args, **kwds) # .classof
|
|
474
474
|
|
|
475
475
|
@Property_RO
|
|
476
476
|
def easting(self):
|
pygeodesy/ellipsoidalExact.py
CHANGED
|
@@ -24,7 +24,7 @@ from pygeodesy.points import _areaError, ispolar # PYCHOK exported
|
|
|
24
24
|
# from math import fabs # from .karney
|
|
25
25
|
|
|
26
26
|
__all__ = _ALL_LAZY.ellipsoidalExact
|
|
27
|
-
__version__ = '25.05.
|
|
27
|
+
__version__ = '25.05.28'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class Cartesian(CartesianEllipsoidalBase):
|
|
@@ -88,17 +88,19 @@ class LatLon(LatLonEllipsoidalBaseDI):
|
|
|
88
88
|
return LatLonEllipsoidalBaseDI.toCartesian(self, **kwds)
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
def areaOf(points, datum=_WGS84, wrap=True):
|
|
91
|
+
def areaOf(points, datum=_WGS84, wrap=True, polar=False):
|
|
92
92
|
'''Compute the area of an (ellipsoidal) polygon or composite.
|
|
93
93
|
|
|
94
|
-
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or
|
|
95
|
-
L{BooleanGH}).
|
|
94
|
+
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
96
95
|
@kwarg datum: Optional datum (L{Datum}).
|
|
97
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
98
|
-
|
|
96
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}}
|
|
97
|
+
(C{bool}).
|
|
98
|
+
@kwarg polar: Use C{B{polar}=True} if the polygon encloses a pole (C{bool}), see
|
|
99
|
+
function L{ispolar<pygeodesy.points.ispolar>} and U{area of a polygon
|
|
100
|
+
enclosing a pole<https://GeographicLib.SourceForge.io/C++/doc/
|
|
101
|
+
classGeographicLib_1_1GeodesicExact.html#a3d7a9155e838a09a48dc14d0c3fac525>}.
|
|
99
102
|
|
|
100
|
-
@return: Area (C{meter} I{squared}, same units as the B{C{datum}}'s
|
|
101
|
-
ellipsoid axes).
|
|
103
|
+
@return: Area (C{meter} I{squared}, same units as the B{C{datum}}'s ellipsoid axes).
|
|
102
104
|
|
|
103
105
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
104
106
|
|
|
@@ -110,12 +112,8 @@ def areaOf(points, datum=_WGS84, wrap=True):
|
|
|
110
112
|
@see: Functions L{pygeodesy.areaOf}, L{ellipsoidalGeodSolve.areaOf},
|
|
111
113
|
L{ellipsoidalKarney.areaOf}, L{sphericalNvector.areaOf} and
|
|
112
114
|
L{sphericalTrigonometry.areaOf}.
|
|
113
|
-
|
|
114
|
-
@note: The U{area of a polygon enclosing a pole<https://GeographicLib.SourceForge.io/
|
|
115
|
-
C++/doc/classGeographicLib_1_1GeodesicExact.html#a3d7a9155e838a09a48dc14d0c3fac525>}
|
|
116
|
-
can be found by adding half the datum's ellipsoid surface area to the polygon's area.
|
|
117
115
|
'''
|
|
118
|
-
return fabs(_polygon(datum.ellipsoid.geodesicx, points, True, False, wrap))
|
|
116
|
+
return fabs(_polygon(datum.ellipsoid.geodesicx, points, True, False, wrap, polar))
|
|
119
117
|
|
|
120
118
|
|
|
121
119
|
def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=True
|
|
@@ -216,13 +214,14 @@ def intersections2(center1, radius1, center2, radius2, height=None, wrap=False,
|
|
|
216
214
|
equidistant=equidistant, tol=tol, **kwds)
|
|
217
215
|
|
|
218
216
|
|
|
219
|
-
def isclockwise(points, datum=_WGS84, wrap=True):
|
|
217
|
+
def isclockwise(points, datum=_WGS84, wrap=True, polar=False):
|
|
220
218
|
'''Determine the direction of a path or polygon.
|
|
221
219
|
|
|
222
220
|
@arg points: The path or polygon points (C{LatLon}[]).
|
|
223
221
|
@kwarg datum: Optional datum (L{Datum}).
|
|
224
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
225
|
-
|
|
222
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
223
|
+
@kwarg polar: Use C{B{polar}=True} if the C{B{points}} enclose a pole (C{bool}),
|
|
224
|
+
see function U{ispolar<pygeodeys.points.ispolar>}.
|
|
226
225
|
|
|
227
226
|
@return: C{True} if B{C{points}} are clockwise, C{False} otherwise.
|
|
228
227
|
|
|
@@ -234,7 +233,7 @@ def isclockwise(points, datum=_WGS84, wrap=True):
|
|
|
234
233
|
|
|
235
234
|
@see: L{pygeodesy.isclockwise}.
|
|
236
235
|
'''
|
|
237
|
-
a = _polygon(datum.ellipsoid.geodesicx, points, True, False, wrap)
|
|
236
|
+
a = _polygon(datum.ellipsoid.geodesicx, points, True, False, wrap, polar)
|
|
238
237
|
if a < 0:
|
|
239
238
|
return True
|
|
240
239
|
elif a > 0:
|
|
@@ -288,29 +287,25 @@ def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
|
288
287
|
def perimeterOf(points, closed=False, datum=_WGS84, wrap=True):
|
|
289
288
|
'''Compute the perimeter of an (ellipsoidal) polygon or composite.
|
|
290
289
|
|
|
291
|
-
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or
|
|
292
|
-
L{BooleanGH}).
|
|
290
|
+
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
293
291
|
@kwarg closed: Optionally, close the polygon (C{bool}).
|
|
294
292
|
@kwarg datum: Optional datum (L{Datum}).
|
|
295
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
296
|
-
B{C{points}} (C{bool}).
|
|
293
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
297
294
|
|
|
298
|
-
@return: Perimeter (C{meter}, same units as the B{C{datum}}'s
|
|
299
|
-
ellipsoid axes).
|
|
295
|
+
@return: Perimeter (C{meter}, same units as the B{C{datum}}'s ellipsoid axes).
|
|
300
296
|
|
|
301
297
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
302
298
|
|
|
303
299
|
@raise TypeError: Some B{C{points}} are not L{LatLon}.
|
|
304
300
|
|
|
305
|
-
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled
|
|
306
|
-
|
|
307
|
-
with C{B{points}} a composite.
|
|
301
|
+
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled longitudes not
|
|
302
|
+
supported or C{B{closed}=False} with C{B{points}} a composite.
|
|
308
303
|
|
|
309
304
|
@see: Functions L{pygeodesy.perimeterOf}, L{ellipsoidalGeodSolve.perimeterOf},
|
|
310
305
|
L{ellipsoidalKarney.perimeterOf}, L{sphericalNvector.perimeterOf} and
|
|
311
306
|
L{sphericalTrigonometry.perimeterOf}.
|
|
312
307
|
'''
|
|
313
|
-
return _polygon(datum.ellipsoid.geodesicx, points, closed, True, wrap)
|
|
308
|
+
return _polygon(datum.ellipsoid.geodesicx, points, closed, True, wrap, False)
|
|
314
309
|
|
|
315
310
|
|
|
316
311
|
__all__ += _ALL_OTHER(Cartesian, LatLon, # classes
|
|
@@ -24,7 +24,7 @@ from pygeodesy.points import _areaError, ispolar # PYCHOK exported
|
|
|
24
24
|
# from math import fabs # from .karney
|
|
25
25
|
|
|
26
26
|
__all__ = _ALL_LAZY.ellipsoidalGeodSolve
|
|
27
|
-
__version__ = '
|
|
27
|
+
__version__ = '25.05.28'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class Cartesian(CartesianEllipsoidalBase):
|
|
@@ -87,12 +87,16 @@ class LatLon(LatLonEllipsoidalBaseDI):
|
|
|
87
87
|
return LatLonEllipsoidalBaseDI.toCartesian(self, **kwds)
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
def areaOf(points, datum=_WGS84, wrap=True):
|
|
90
|
+
def areaOf(points, datum=_WGS84, wrap=True, polar=False):
|
|
91
91
|
'''Compute the area of an (ellipsoidal) polygon or composite.
|
|
92
92
|
|
|
93
93
|
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
94
94
|
@kwarg datum: Optional datum (L{Datum}).
|
|
95
95
|
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
96
|
+
@kwarg polar: Use C{B{polar}=True} if the polygon encloses a pole (C{bool}), see
|
|
97
|
+
function L{ispolar<pygeodesy.points.ispolar>} and U{area of a polygon
|
|
98
|
+
enclosing a pole<https://GeographicLib.SourceForge.io/C++/doc/
|
|
99
|
+
classGeographicLib_1_1GeodesicExact.html#a3d7a9155e838a09a48dc14d0c3fac525>}.
|
|
96
100
|
|
|
97
101
|
@return: Area (C{meter}, same as units of the B{C{datum}}'s ellipsoid axes, I{squared}).
|
|
98
102
|
|
|
@@ -105,7 +109,7 @@ def areaOf(points, datum=_WGS84, wrap=True):
|
|
|
105
109
|
@see: Functions L{pygeodesy.areaOf}, L{ellipsoidalExact.areaOf}, L{ellipsoidalKarney.areaOf},
|
|
106
110
|
L{sphericalNvector.areaOf} and L{sphericalTrigonometry.areaOf}.
|
|
107
111
|
'''
|
|
108
|
-
return fabs(_polygon(datum.ellipsoid.geodsolve, points, True, False, wrap))
|
|
112
|
+
return fabs(_polygon(datum.ellipsoid.geodsolve, points, True, False, wrap, polar))
|
|
109
113
|
|
|
110
114
|
|
|
111
115
|
def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=True
|
|
@@ -209,13 +213,14 @@ def intersections2(center1, radius1, center2, radius2, height=None, wrap=False,
|
|
|
209
213
|
equidistant=equidistant, tol=tol, LatLon=LatLon, **LatLon_kwds)
|
|
210
214
|
|
|
211
215
|
|
|
212
|
-
def isclockwise(points, datum=_WGS84, wrap=True):
|
|
216
|
+
def isclockwise(points, datum=_WGS84, wrap=True, polar=False):
|
|
213
217
|
'''Determine the direction of a path or polygon.
|
|
214
218
|
|
|
215
219
|
@arg points: The path or polygon points (C{LatLon}[]).
|
|
216
220
|
@kwarg datum: Optional datum (L{Datum}).
|
|
217
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
218
|
-
|
|
221
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
222
|
+
@kwarg polar: Use C{B{polar}=True} if the C{B{points}} enclose a pole (C{bool}),
|
|
223
|
+
see function U{ispolar<pygeodeys.points.ispolar>}.
|
|
219
224
|
|
|
220
225
|
@return: C{True} if B{C{points}} are clockwise, C{False} otherwise.
|
|
221
226
|
|
|
@@ -223,12 +228,11 @@ def isclockwise(points, datum=_WGS84, wrap=True):
|
|
|
223
228
|
|
|
224
229
|
@raise TypeError: Some B{C{points}} are not C{LatLon}.
|
|
225
230
|
|
|
226
|
-
@raise ValueError: The B{C{points}} enclose a pole or zero
|
|
227
|
-
area.
|
|
231
|
+
@raise ValueError: The B{C{points}} enclose a pole or zero area.
|
|
228
232
|
|
|
229
233
|
@see: L{pygeodesy.isclockwise}.
|
|
230
234
|
'''
|
|
231
|
-
a = _polygon(datum.ellipsoid.geodsolve, points, True, False, wrap)
|
|
235
|
+
a = _polygon(datum.ellipsoid.geodsolve, points, True, False, wrap, polar)
|
|
232
236
|
if a < 0:
|
|
233
237
|
return True
|
|
234
238
|
elif a > 0:
|
|
@@ -282,29 +286,25 @@ def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
|
282
286
|
def perimeterOf(points, closed=False, datum=_WGS84, wrap=True):
|
|
283
287
|
'''Compute the perimeter of an (ellipsoidal) polygon or composite.
|
|
284
288
|
|
|
285
|
-
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or
|
|
286
|
-
L{BooleanGH}).
|
|
289
|
+
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
287
290
|
@kwarg closed: Optionally, close the polygon (C{bool}).
|
|
288
291
|
@kwarg datum: Optional datum (L{Datum}).
|
|
289
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
290
|
-
B{C{points}} (C{bool}).
|
|
292
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
291
293
|
|
|
292
|
-
@return: Perimeter (C{meter}, same as units of the B{C{datum}}'s
|
|
293
|
-
ellipsoid axes).
|
|
294
|
+
@return: Perimeter (C{meter}, same as units of the B{C{datum}}'s ellipsoid axes).
|
|
294
295
|
|
|
295
296
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
296
297
|
|
|
297
298
|
@raise TypeError: Some B{C{points}} are not L{LatLon}.
|
|
298
299
|
|
|
299
|
-
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled
|
|
300
|
-
|
|
301
|
-
with C{B{points}} a composite.
|
|
300
|
+
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled longitudes not
|
|
301
|
+
supported or C{B{closed}=False} with C{B{points}} a composite.
|
|
302
302
|
|
|
303
303
|
@see: Functions L{pygeodesy.perimeterOf}, L{ellipsoidalExact.perimeterOf},
|
|
304
304
|
L{ellipsoidalKarney.perimeterOf}, L{sphericalNvector.perimeterOf}
|
|
305
305
|
and L{sphericalTrigonometry.perimeterOf}.
|
|
306
306
|
'''
|
|
307
|
-
return _polygon(datum.ellipsoid.geodsolve, points, closed, True, wrap)
|
|
307
|
+
return _polygon(datum.ellipsoid.geodsolve, points, closed, True, wrap, False)
|
|
308
308
|
|
|
309
309
|
|
|
310
310
|
__all__ += _ALL_OTHER(Cartesian, LatLon, # classes
|
pygeodesy/ellipsoidalKarney.py
CHANGED
|
@@ -42,7 +42,7 @@ from pygeodesy.props import deprecated_method, Property_RO
|
|
|
42
42
|
# from math import fabs # from .karney
|
|
43
43
|
|
|
44
44
|
__all__ = _ALL_LAZY.ellipsoidalKarney
|
|
45
|
-
__version__ = '
|
|
45
|
+
__version__ = '25.05.27'
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class Cartesian(CartesianEllipsoidalBase):
|
|
@@ -110,13 +110,17 @@ class LatLon(LatLonEllipsoidalBaseDI):
|
|
|
110
110
|
return LatLonEllipsoidalBaseDI.toCartesian(self, **kwds)
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
def areaOf(points, datum=_WGS84, wrap=True):
|
|
113
|
+
def areaOf(points, datum=_WGS84, wrap=True, polar=False):
|
|
114
114
|
'''Compute the area of an (ellipsoidal) polygon or composite using I{Karney}'s
|
|
115
115
|
U{geographiclib<https://PyPI.org/project/geographiclib>} package.
|
|
116
116
|
|
|
117
117
|
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
118
118
|
@kwarg datum: Optional datum (L{Datum}).
|
|
119
119
|
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
120
|
+
@kwarg polar: Use C{B{polar}=True} if the polygon encloses a pole (C{bool}), see
|
|
121
|
+
function L{ispolar<pygeodesy.points.ispolar>} and U{area of a polygon
|
|
122
|
+
enclosing a pole<https://GeographicLib.SourceForge.io/C++/doc/
|
|
123
|
+
classGeographicLib_1_1GeodesicExact.html#a3d7a9155e838a09a48dc14d0c3fac525>}.
|
|
120
124
|
|
|
121
125
|
@return: Area (C{meter}, same as units of the B{C{datum}}'s ellipsoid axes, I{squared}).
|
|
122
126
|
|
|
@@ -131,12 +135,8 @@ def areaOf(points, datum=_WGS84, wrap=True):
|
|
|
131
135
|
|
|
132
136
|
@see: Functions L{pygeodesy.areaOf}, L{ellipsoidalExact.areaOf}, L{ellipsoidalGeodSolve.areaOf},
|
|
133
137
|
L{sphericalNvector.areaOf} and L{sphericalTrigonometry.areaOf}.
|
|
134
|
-
|
|
135
|
-
@note: The U{area of a polygon enclosing a pole<https://GeographicLib.SourceForge.io/
|
|
136
|
-
C++/doc/classGeographicLib_1_1GeodesicExact.html#a3d7a9155e838a09a48dc14d0c3fac525>}
|
|
137
|
-
can be found by adding half the datum's ellipsoid surface area to the polygon's area.
|
|
138
138
|
'''
|
|
139
|
-
return fabs(_polygon(datum.ellipsoid.geodesic, points, True, False, wrap))
|
|
139
|
+
return fabs(_polygon(datum.ellipsoid.geodesic, points, True, False, wrap, polar))
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=True
|
|
@@ -240,19 +240,19 @@ def intersections2(center1, radius1, center2, radius2, height=None, wrap=False,
|
|
|
240
240
|
equidistant=equidistant, tol=tol, LatLon=LatLon, **LatLon_kwds)
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
def isclockwise(points, datum=_WGS84, wrap=True):
|
|
243
|
+
def isclockwise(points, datum=_WGS84, wrap=True, polar=False):
|
|
244
244
|
'''Determine the direction of a path or polygon using I{Karney}'s
|
|
245
245
|
U{geographiclib<https://PyPI.org/project/geographiclib>} package.
|
|
246
246
|
|
|
247
247
|
@arg points: The path or polygon points (C{LatLon}[]).
|
|
248
248
|
@kwarg datum: Optional datum (L{Datum}).
|
|
249
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
250
|
-
|
|
249
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
250
|
+
@kwarg polar: Use C{B{polar}=True} if the C{B{points}} enclose a pole (C{bool}),
|
|
251
|
+
see function U{ispolar<pygeodeys.points.ispolar>}.
|
|
251
252
|
|
|
252
253
|
@return: C{True} if B{C{points}} are clockwise, C{False} otherwise.
|
|
253
254
|
|
|
254
|
-
@raise ImportError: Package U{geographiclib
|
|
255
|
-
<https://PyPI.org/project/geographiclib>}
|
|
255
|
+
@raise ImportError: Package U{geographiclib<https://PyPI.org/project/geographiclib>}
|
|
256
256
|
not installed or not found.
|
|
257
257
|
|
|
258
258
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
@@ -263,7 +263,7 @@ def isclockwise(points, datum=_WGS84, wrap=True):
|
|
|
263
263
|
|
|
264
264
|
@see: L{pygeodesy.isclockwise}.
|
|
265
265
|
'''
|
|
266
|
-
a = _polygon(datum.ellipsoid.geodesic, points, True, False, wrap)
|
|
266
|
+
a = _polygon(datum.ellipsoid.geodesic, points, True, False, wrap, polar)
|
|
267
267
|
if a < 0:
|
|
268
268
|
return True
|
|
269
269
|
elif a > 0:
|
|
@@ -322,34 +322,29 @@ def perimeterOf(points, closed=False, datum=_WGS84, wrap=True):
|
|
|
322
322
|
'''Compute the perimeter of an (ellipsoidal) polygon or composite using I{Karney}'s
|
|
323
323
|
U{geographiclib<https://PyPI.org/project/geographiclib>} package.
|
|
324
324
|
|
|
325
|
-
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or
|
|
326
|
-
L{BooleanGH}).
|
|
325
|
+
@arg points: The polygon points (L{LatLon}[], L{BooleanFHP} or L{BooleanGH}).
|
|
327
326
|
@kwarg closed: Optionally, close the polygon (C{bool}).
|
|
328
327
|
@kwarg datum: Optional datum (L{Datum}).
|
|
329
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
330
|
-
B{C{points}} (C{bool}).
|
|
328
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}} (C{bool}).
|
|
331
329
|
|
|
332
|
-
@return: Perimeter (C{meter}, same as units of the B{C{datum}}'s
|
|
333
|
-
ellipsoid axes).
|
|
330
|
+
@return: Perimeter (C{meter}, same as units of the B{C{datum}}'s ellipsoid axes).
|
|
334
331
|
|
|
335
|
-
@raise ImportError: Package U{geographiclib
|
|
336
|
-
<https://PyPI.org/project/geographiclib>}
|
|
332
|
+
@raise ImportError: Package U{geographiclib<https://PyPI.org/project/geographiclib>}
|
|
337
333
|
not installed or not found.
|
|
338
334
|
|
|
339
335
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
340
336
|
|
|
341
|
-
@raise TypeError: Some B{C{points}} are not L{LatLon} or C{B{closed}=False}
|
|
342
|
-
|
|
337
|
+
@raise TypeError: Some B{C{points}} are not L{LatLon} or C{B{closed}=False} with
|
|
338
|
+
B{C{points}} a composite.
|
|
343
339
|
|
|
344
|
-
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled
|
|
345
|
-
|
|
346
|
-
with C{B{points}} a composite.
|
|
340
|
+
@raise ValueError: Invalid C{B{wrap}=False}, unwrapped, unrolled longitudes not
|
|
341
|
+
supported or C{B{closed}=False} with C{B{points}} a composite.
|
|
347
342
|
|
|
348
343
|
@see: Functions L{pygeodesy.perimeterOf}, L{ellipsoidalExact.perimeterOf},
|
|
349
344
|
L{ellipsoidalGeodSolve.perimeterOf}, L{sphericalNvector.perimeterOf}
|
|
350
345
|
and L{sphericalTrigonometry.perimeterOf}.
|
|
351
346
|
'''
|
|
352
|
-
return _polygon(datum.ellipsoid.geodesic, points, closed, True, wrap)
|
|
347
|
+
return _polygon(datum.ellipsoid.geodesic, points, closed, True, wrap, False)
|
|
353
348
|
|
|
354
349
|
|
|
355
350
|
__all__ += _ALL_OTHER(Cartesian, LatLon, # classes
|
pygeodesy/ellipsoidalVincenty.py
CHANGED
|
@@ -76,7 +76,7 @@ from pygeodesy.utily import atan2, atan2b, atan2d, sincos2, sincos2d, \
|
|
|
76
76
|
from math import cos, degrees, fabs, radians, tan as _tan
|
|
77
77
|
|
|
78
78
|
__all__ = _ALL_LAZY.ellipsoidalVincenty
|
|
79
|
-
__version__ = '25.05.
|
|
79
|
+
__version__ = '25.05.26'
|
|
80
80
|
|
|
81
81
|
_antipodal_to_ = _SPACE_(_antipodal_, _to_)
|
|
82
82
|
|
|
@@ -349,13 +349,6 @@ def _c2sm2(c2sm):
|
|
|
349
349
|
return c2sm**2 * _2_0 - _1_0
|
|
350
350
|
|
|
351
351
|
|
|
352
|
-
def _ellipsoidal(): # helper for areaOf and perimeterOf
|
|
353
|
-
try:
|
|
354
|
-
return _MODS.ellipsoidalKarney
|
|
355
|
-
except ImportError:
|
|
356
|
-
return _MODS.ellipsoidalExact
|
|
357
|
-
|
|
358
|
-
|
|
359
352
|
def _Dl(f, ca2, sa, s, cs, ss, c2sm, dl=_0_0):
|
|
360
353
|
# C{Dl}
|
|
361
354
|
if f and sa:
|
|
@@ -385,6 +378,14 @@ def _Ecef():
|
|
|
385
378
|
return E
|
|
386
379
|
|
|
387
380
|
|
|
381
|
+
def _ellipsoidalOf(_Of, points, **kwds): # helper for DEPRECATED areaOf and perimeterOf
|
|
382
|
+
try:
|
|
383
|
+
r = getattr(_MODS.ellipsoidalKarney, _Of.__name__)(points, **kwds)
|
|
384
|
+
except ImportError: # no geographiclib
|
|
385
|
+
r = getattr(_MODS.ellipsoidalExact, _Of.__name__)(points, **kwds)
|
|
386
|
+
return r
|
|
387
|
+
|
|
388
|
+
|
|
388
389
|
def _sincos22(sa):
|
|
389
390
|
# 2-Tuple C{(sin(a), cos(a)**2)}
|
|
390
391
|
ca2 = _1_0 - sa**2
|
|
@@ -403,10 +404,10 @@ def _sincostan3r(a, f):
|
|
|
403
404
|
|
|
404
405
|
|
|
405
406
|
@deprecated_function
|
|
406
|
-
def areaOf(points, **
|
|
407
|
+
def areaOf(points, **datum_wrap_polar):
|
|
407
408
|
'''DEPRECATED, use function L{ellipsoidalExact.areaOf} or L{ellipsoidalKarney.areaOf}.
|
|
408
409
|
'''
|
|
409
|
-
return
|
|
410
|
+
return _ellipsoidalOf(areaOf, points, **datum_wrap_polar)
|
|
410
411
|
|
|
411
412
|
|
|
412
413
|
def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=True
|
|
@@ -562,7 +563,7 @@ def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
|
562
563
|
def perimeterOf(points, **closed_datum_wrap):
|
|
563
564
|
'''DEPRECATED, use function L{ellipsoidalExact.perimeterOf} or L{ellipsoidalKarney.perimeterOf}.
|
|
564
565
|
'''
|
|
565
|
-
return
|
|
566
|
+
return _ellipsoidalOf(perimeterOf, points, **closed_datum_wrap)
|
|
566
567
|
|
|
567
568
|
|
|
568
569
|
__all__ += _ALL_DOCS(Cartesian, LatLon, intersecant2, # from .ellipsoidalBaseDI
|
pygeodesy/elliptic.py
CHANGED
|
@@ -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__ = '25.05.
|
|
102
|
+
__version__ = '25.05.28'
|
|
103
103
|
|
|
104
104
|
_TolRD = zqrt(EPS * 0.002)
|
|
105
105
|
_TolRF = zqrt(EPS * 0.030)
|
|
@@ -165,9 +165,9 @@ class Elliptic(_Named):
|
|
|
165
165
|
that case, we have C{Π(φ, 0, k) = F(φ, k), G(φ, 0, k) =
|
|
166
166
|
E(φ, k)} and C{H(φ, 0, k) = F(φ, k) - D(φ, k)}.
|
|
167
167
|
'''
|
|
168
|
-
self.reset(k2=k2, alpha2=alpha2, kp2=kp2, alphap2=alphap2)
|
|
169
168
|
if name:
|
|
170
169
|
self.name = name
|
|
170
|
+
self.reset(k2=k2, alpha2=alpha2, kp2=kp2, alphap2=alphap2)
|
|
171
171
|
|
|
172
172
|
@Property_RO
|
|
173
173
|
def alpha2(self):
|
|
@@ -760,15 +760,20 @@ class Elliptic(_Named):
|
|
|
760
760
|
that these conditions are met to enable accuracy to be
|
|
761
761
|
maintained, e.g., when C{k} is very close to unity.
|
|
762
762
|
'''
|
|
763
|
+
def _1p2(kp2, k2):
|
|
764
|
+
return (_1_0 - k2) if kp2 is None else kp2
|
|
765
|
+
|
|
766
|
+
def _S(**kwds):
|
|
767
|
+
return Scalar_(Error=EllipticError, **kwds)
|
|
768
|
+
|
|
763
769
|
if self.__dict__:
|
|
764
770
|
_update_all(self, _Named.iteration._uname, Base=Property_RO)
|
|
765
771
|
|
|
766
|
-
self._k2
|
|
767
|
-
self._kp2
|
|
772
|
+
self._k2 = _S(k2 = k2, low=None, high=_1_0)
|
|
773
|
+
self._kp2 = _S(kp2=_1p2(kp2, k2)) # low=_0_0
|
|
768
774
|
|
|
769
|
-
self._alpha2 =
|
|
770
|
-
self._alphap2 =
|
|
771
|
-
Error=EllipticError)
|
|
775
|
+
self._alpha2 = _S(alpha2 = alpha2, low=None, high=_1_0)
|
|
776
|
+
self._alphap2 = _S(alphap2=_1p2(alphap2, alpha2)) # low=_0_0
|
|
772
777
|
|
|
773
778
|
# Values of complete elliptic integrals for k = 0,1 and alpha = 0,1
|
|
774
779
|
# K E D
|
|
@@ -1120,11 +1125,11 @@ def _rC(unused, x, y):
|
|
|
1120
1125
|
'''(INTERNAL) Defined only for C{y != 0} and C{x >= 0}.
|
|
1121
1126
|
'''
|
|
1122
1127
|
d = x - y
|
|
1123
|
-
if
|
|
1128
|
+
if x < y: # catch NaN
|
|
1124
1129
|
# <https://DLMF.NIST.gov/19.2.E18>
|
|
1125
|
-
d = -
|
|
1130
|
+
d = y - x
|
|
1126
1131
|
r = atan(sqrt(d / x)) if x > 0 else PI_2
|
|
1127
|
-
elif
|
|
1132
|
+
elif x == y: # XXX d < EPS0? or EPS02 or _EPSmin
|
|
1128
1133
|
d, r = y, _1_0
|
|
1129
1134
|
elif y > 0: # <https://DLMF.NIST.gov/19.2.E19>
|
|
1130
1135
|
r = asinh(sqrt(d / y)) # atanh(sqrt((x - y) / x))
|
pygeodesy/frechet.py
CHANGED
|
@@ -101,7 +101,7 @@ from collections import defaultdict as _defaultdict
|
|
|
101
101
|
# from math import radians # from .points
|
|
102
102
|
|
|
103
103
|
__all__ = _ALL_LAZY.frechet
|
|
104
|
-
__version__ = '25.05.
|
|
104
|
+
__version__ = '25.05.26'
|
|
105
105
|
|
|
106
106
|
_formy = _MODS.into(formy=__name__)
|
|
107
107
|
|
|
@@ -153,7 +153,7 @@ class Frechet(_Named):
|
|
|
153
153
|
@raise FrechetError: Insufficient number of B{C{point1s}} or an invalid
|
|
154
154
|
B{C{point1}}, B{C{fraction}} or B{C{units}}.
|
|
155
155
|
'''
|
|
156
|
-
name, kwds = _name2__(**name__kwds) # name__=self
|
|
156
|
+
name, kwds = _name2__(**name__kwds) # name__=type(self)
|
|
157
157
|
if name:
|
|
158
158
|
self.name = name
|
|
159
159
|
|