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/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__ = '24.
|
|
27
|
+
__version__ = '24.11.06'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class Cartesian(CartesianEllipsoidalBase):
|
|
@@ -119,30 +119,28 @@ def areaOf(points, datum=_WGS84, wrap=True):
|
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=True
|
|
122
|
-
|
|
123
|
-
'''I{Iteratively} compute the intersection point of two lines, each
|
|
124
|
-
|
|
125
|
-
initial bearing from North.
|
|
122
|
+
equidistant=None, tol=_TOL_M, **LatLon_and_kwds):
|
|
123
|
+
'''I{Iteratively} compute the intersection point of two geodesic lines, each
|
|
124
|
+
given as two points or as an start point and a bearing from North.
|
|
126
125
|
|
|
127
126
|
@arg start1: Start point of the first line (L{LatLon}).
|
|
128
127
|
@arg end1: End point of the first line (L{LatLon}) or the initial bearing
|
|
129
|
-
at
|
|
128
|
+
at B{C{start1}} (compass C{degrees360}).
|
|
130
129
|
@arg start2: Start point of the second line (L{LatLon}).
|
|
131
130
|
@arg end2: End point of the second line (L{LatLon}) or the initial bearing
|
|
132
|
-
at
|
|
131
|
+
at B{C{start2}} (compass C{degrees360}).
|
|
133
132
|
@kwarg height: Optional height at the intersection (C{meter}, conventionally)
|
|
134
133
|
or C{None} for the mean height.
|
|
135
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll
|
|
136
|
-
|
|
134
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{start2}} and
|
|
135
|
+
both B{C{end*}} points (C{bool}).
|
|
137
136
|
@kwarg equidistant: An azimuthal equidistant projection (I{class} or function
|
|
138
137
|
L{pygeodesy.equidistant}) or C{None} for the preferred
|
|
139
138
|
C{B{start1}.Equidistant}.
|
|
140
139
|
@kwarg tol: Tolerance for convergence and for skew line distance and length
|
|
141
140
|
(C{meter}, conventionally).
|
|
142
|
-
@kwarg
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
ignored if C{B{LatLon} is None}.
|
|
141
|
+
@kwarg LatLon_and_kwds: Optional class C{B{LatLon}=}L{LatLon} to return the
|
|
142
|
+
intersection points and optionally, additional B{C{LatLon}}
|
|
143
|
+
keyword arguments, ignored if C{B{LatLon}=None}.
|
|
146
144
|
|
|
147
145
|
@return: An L{Intersection3Tuple}C{(point, outside1, outside2)} with C{point}
|
|
148
146
|
a B{C{LatLon}} or if C{B{LatLon} is None}, a L{LatLon4Tuple}C{(lat,
|
|
@@ -154,23 +152,23 @@ def intersection3(start1, end1, start2, end2, height=None, wrap=False, # was=Tr
|
|
|
154
152
|
@raise TypeError: Invalid or non-ellipsoidal B{C{start1}}, B{C{end1}},
|
|
155
153
|
B{C{start2}} or B{C{end2}} or invalid B{C{equidistant}}.
|
|
156
154
|
|
|
157
|
-
@note: For each line specified with an initial bearing, a pseudo-end point
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
earth perimeter).
|
|
155
|
+
@note: For each line specified with an initial bearing, a pseudo-end point is
|
|
156
|
+
computed as the C{destination} along that bearing at about 1.5 times the
|
|
157
|
+
distance from the start point to an initial gu-/estimate of the intersection
|
|
158
|
+
point (and between 1/8 and 3/8 of the authalic earth perimeter).
|
|
162
159
|
|
|
163
160
|
@see: U{The B{ellipsoidal} case<https://GIS.StackExchange.com/questions/48937/
|
|
164
161
|
calculating-intersection-of-two-circles>} and U{Karney's paper
|
|
165
162
|
<https://ArXiv.org/pdf/1102.1215.pdf>}, pp 20-21, section B{14. MARITIME
|
|
166
163
|
BOUNDARIES} for more details about the iteration algorithm.
|
|
167
164
|
'''
|
|
165
|
+
kwds = _xkwds(LatLon_and_kwds, LatLon=LatLon)
|
|
168
166
|
return _intersection3(start1, end1, start2, end2, height=height, wrap=wrap,
|
|
169
|
-
|
|
167
|
+
equidistant=equidistant, tol=tol, **kwds)
|
|
170
168
|
|
|
171
169
|
|
|
172
170
|
def intersections2(center1, radius1, center2, radius2, height=None, wrap=False, # was=True
|
|
173
|
-
|
|
171
|
+
equidistant=None, tol=_TOL_M, **LatLon_and_kwds):
|
|
174
172
|
'''I{Iteratively} compute the intersection points of two circles, each defined
|
|
175
173
|
by an (ellipsoidal) center point and a radius.
|
|
176
174
|
|
|
@@ -189,10 +187,9 @@ def intersections2(center1, radius1, center2, radius2, height=None, wrap=False,
|
|
|
189
187
|
the preferred C{B{center1}.Equidistant}.
|
|
190
188
|
@kwarg tol: Convergence tolerance (C{meter}, same units as B{C{radius1}}
|
|
191
189
|
and B{C{radius2}}).
|
|
192
|
-
@kwarg
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
ignored if C{B{LatLon} is None}.
|
|
190
|
+
@kwarg LatLon_and_kwds: Optional class C{B{LatLon}=}L{LatLon} to return the
|
|
191
|
+
intersection points and optionally, additional B{C{LatLon}}
|
|
192
|
+
keyword arguments, ignored if C{B{LatLon}=None}.
|
|
196
193
|
|
|
197
194
|
@return: 2-Tuple of the intersection points, each a B{C{LatLon}} instance
|
|
198
195
|
or L{LatLon4Tuple}C{(lat, lon, height, datum)} if C{B{LatLon} is
|
|
@@ -214,8 +211,9 @@ def intersections2(center1, radius1, center2, radius2, height=None, wrap=False,
|
|
|
214
211
|
U{sphere-sphere<https://MathWorld.Wolfram.com/Sphere-SphereIntersection.html>}
|
|
215
212
|
intersections.
|
|
216
213
|
'''
|
|
214
|
+
kwds = _xkwds(LatLon_and_kwds, LatLon=LatLon)
|
|
217
215
|
return _intersections2(center1, radius1, center2, radius2, height=height, wrap=wrap,
|
|
218
|
-
|
|
216
|
+
equidistant=equidistant, tol=tol, **kwds)
|
|
219
217
|
|
|
220
218
|
|
|
221
219
|
def isclockwise(points, datum=_WGS84, wrap=True):
|
|
@@ -245,9 +243,9 @@ def isclockwise(points, datum=_WGS84, wrap=True):
|
|
|
245
243
|
|
|
246
244
|
|
|
247
245
|
def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
248
|
-
|
|
249
|
-
'''I{Iteratively} locate the closest point on the geodesic
|
|
250
|
-
two other (
|
|
246
|
+
equidistant=None, tol=_TOL_M, **LatLon_and_kwds):
|
|
247
|
+
'''I{Iteratively} locate the closest point on the geodesic (line)
|
|
248
|
+
between two other (ellipsoidal) points.
|
|
251
249
|
|
|
252
250
|
@arg point: Reference point (C{LatLon}).
|
|
253
251
|
@arg point1: Start point of the geodesic (C{LatLon}).
|
|
@@ -265,16 +263,15 @@ def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
|
265
263
|
or function L{pygeodesy.equidistant}) or C{None}
|
|
266
264
|
for the preferred C{B{point}.Equidistant}.
|
|
267
265
|
@kwarg tol: Convergence tolerance (C{meter}).
|
|
268
|
-
@kwarg
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
arguments, ignored if C{B{LatLon} is None}.
|
|
266
|
+
@kwarg LatLon_and_kwds: Optional class C{B{LatLon}=}L{LatLon} to return the
|
|
267
|
+
closest point and optionally, additional B{C{LatLon}} keyword
|
|
268
|
+
arguments, ignored if C{B{LatLon}=None}.
|
|
272
269
|
|
|
273
|
-
@return: Closest point, a B{C{LatLon}} instance or if C{B{LatLon}
|
|
274
|
-
|
|
270
|
+
@return: Closest point, a B{C{LatLon}} instance or if C{B{LatLon} is None},
|
|
271
|
+
a L{LatLon4Tuple}C{(lat, lon, height, datum)}.
|
|
275
272
|
|
|
276
|
-
@raise TypeError: Invalid or non-ellipsoidal B{C{point}}, B{C{point1}}
|
|
277
|
-
|
|
273
|
+
@raise TypeError: Invalid or non-ellipsoidal B{C{point}}, B{C{point1}} or
|
|
274
|
+
B{C{point2}} or invalid B{C{equidistant}}.
|
|
278
275
|
|
|
279
276
|
@raise ValueError: No convergence for the B{C{tol}}.
|
|
280
277
|
|
|
@@ -283,8 +280,9 @@ def nearestOn(point, point1, point2, within=True, height=None, wrap=False,
|
|
|
283
280
|
<https://ArXiv.org/pdf/1102.1215.pdf>}, pp 20-21, section B{14. MARITIME
|
|
284
281
|
BOUNDARIES} for more details about the iteration algorithm.
|
|
285
282
|
'''
|
|
283
|
+
kwds = _xkwds(LatLon_and_kwds, LatLon=LatLon)
|
|
286
284
|
return _nearestOn(point, point1, point2, within=within, height=height, wrap=wrap,
|
|
287
|
-
|
|
285
|
+
equidistant=equidistant, tol=tol, **kwds)
|
|
288
286
|
|
|
289
287
|
|
|
290
288
|
def perimeterOf(points, closed=False, datum=_WGS84, wrap=True):
|
pygeodesy/ellipsoidalNvector.py
CHANGED
|
@@ -8,7 +8,7 @@ and C{Nvector} and DEPRECATED L{Ned} and functions L{meanOf}, L{sumOf}
|
|
|
8
8
|
and DEPRECATED L{toNed}.
|
|
9
9
|
|
|
10
10
|
Pure Python implementation of n-vector-based geodetic (lat-/longitude)
|
|
11
|
-
methods by I{(C) Chris Veness 2011-
|
|
11
|
+
methods by I{(C) Chris Veness 2011-2024} published under the same MIT
|
|
12
12
|
Licence**, see U{Vector-based geodesy
|
|
13
13
|
<https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>}.
|
|
14
14
|
|
|
@@ -48,7 +48,7 @@ from pygeodesy.units import Bearing, Distance, Height, Scalar
|
|
|
48
48
|
# from math import fabs # from .nvectorBase
|
|
49
49
|
|
|
50
50
|
__all__ = _ALL_LAZY.ellipsoidalNvector
|
|
51
|
-
__version__ = '24.
|
|
51
|
+
__version__ = '24.10.19'
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
class Ned(_Ned):
|
|
@@ -417,7 +417,7 @@ class LatLon(LatLonNvectorBase, LatLonEllipsoidalBase):
|
|
|
417
417
|
return LatLonNvectorBase.toNvector(self, **kwds)
|
|
418
418
|
|
|
419
419
|
|
|
420
|
-
|
|
420
|
+
_Nv00 = LatLon(0, 0, name=_Nv00_) # reference instance (L{LatLon})
|
|
421
421
|
|
|
422
422
|
|
|
423
423
|
class Nvector(NvectorBase):
|
|
@@ -541,7 +541,7 @@ def meanOf(points, datum=_WGS84, height=None, wrap=False,
|
|
|
541
541
|
|
|
542
542
|
@raise ValueError: Insufficient number of B{C{points}}.
|
|
543
543
|
'''
|
|
544
|
-
Ps =
|
|
544
|
+
Ps = _Nv00.PointsIter(points, wrap=wrap)
|
|
545
545
|
n = sumOf(p._N_vector for p in Ps.iterate(closed=False))
|
|
546
546
|
return n.toLatLon(**_xkwds(LatLon_and_kwds, height=height, datum=datum,
|
|
547
547
|
LatLon=LatLon, name__=meanOf))
|
pygeodesy/ellipsoidalVincenty.py
CHANGED
|
@@ -8,7 +8,7 @@ I{Thaddeus Vincenty}'s geodetic (lat-/longitude) L{LatLon}, geocentric
|
|
|
8
8
|
L{intersections2}, L{nearestOn} and L{perimeterOf}.
|
|
9
9
|
|
|
10
10
|
Pure Python implementation of geodesy tools for ellipsoidal earth models,
|
|
11
|
-
transcoded from JavaScript originals by I{(C) Chris Veness 2005-
|
|
11
|
+
transcoded from JavaScript originals by I{(C) Chris Veness 2005-2024}
|
|
12
12
|
and published under the same MIT Licence**, see U{Vincenty geodesics
|
|
13
13
|
<https://www.Movable-Type.co.UK/scripts/LatLongVincenty.html>}. More
|
|
14
14
|
at U{geographiclib<https://PyPI.org/project/geographiclib>} and
|
|
@@ -72,7 +72,7 @@ from pygeodesy.utily import atan2b, atan2d, sincos2, sincos2d, unroll180, wrap18
|
|
|
72
72
|
from math import atan2, cos, degrees, fabs, radians, tan
|
|
73
73
|
|
|
74
74
|
__all__ = _ALL_LAZY.ellipsoidalVincenty
|
|
75
|
-
__version__ = '24.
|
|
75
|
+
__version__ = '24.10.12'
|
|
76
76
|
|
|
77
77
|
_antipodal_to_ = _SPACE_(_antipodal_, _to_)
|
|
78
78
|
|
pygeodesy/ellipsoids.py
CHANGED
|
@@ -66,7 +66,7 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
66
66
|
|
|
67
67
|
from pygeodesy.basics import copysign0, isbool, isint
|
|
68
68
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS1, INF, NINF, PI4, PI_2, PI_3, R_M, R_MA, R_FM, \
|
|
69
|
-
_EPSqrt, _EPStol as _TOL, _floatuple as _T, _isfinite,
|
|
69
|
+
_EPSqrt, _EPStol as _TOL, _floatuple as _T, _isfinite, \
|
|
70
70
|
_0_0s, _0_0, _0_5, _1_0, _1_EPS, _2_0, _4_0, _90_0, \
|
|
71
71
|
_0_25, _3_0 # PYCHOK used!
|
|
72
72
|
from pygeodesy.errors import _AssertionError, IntersectionError, _ValueError, _xattr, _xkwds_not
|
|
@@ -93,7 +93,7 @@ from pygeodesy.utily import atan1, atan1d, atan2b, degrees90, m2radians, radians
|
|
|
93
93
|
from math import asinh, atan, atanh, cos, degrees, exp, fabs, radians, sin, sinh, sqrt, tan
|
|
94
94
|
|
|
95
95
|
__all__ = _ALL_LAZY.ellipsoids
|
|
96
|
-
__version__ = '24.
|
|
96
|
+
__version__ = '24.10.15'
|
|
97
97
|
|
|
98
98
|
_f_0_0 = Float(f =_0_0) # zero flattening
|
|
99
99
|
_f__0_0 = Float(f_=_0_0) # zero inverse flattening
|
|
@@ -281,7 +281,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
281
281
|
|
|
282
282
|
self._register(Ellipsoids, n)
|
|
283
283
|
|
|
284
|
-
if f and f_: # see
|
|
284
|
+
if f and f_: # see test/testEllipsoidal
|
|
285
285
|
d = dict(eps=_TOL)
|
|
286
286
|
if None in ff_: # both f_ and f given
|
|
287
287
|
d.update(Error=_ValueError, txt=_incompatible_)
|
|
@@ -811,9 +811,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
811
811
|
|
|
812
812
|
eccentricity = e # eccentricity
|
|
813
813
|
# eccentricity2 = e2 # eccentricity squared
|
|
814
|
-
eccentricity1st2 = e2 # first eccentricity squared
|
|
815
|
-
eccentricity2nd2 = e22 # second eccentricity squared
|
|
816
|
-
eccentricity3rd2 = e32 # third eccentricity squared
|
|
814
|
+
eccentricity1st2 = e2 # first eccentricity squared, signed
|
|
815
|
+
eccentricity2nd2 = e22 # second eccentricity squared, signed
|
|
816
|
+
eccentricity3rd2 = e32 # third eccentricity squared, signed
|
|
817
817
|
|
|
818
818
|
def ecef(self, Ecef=None):
|
|
819
819
|
'''Return U{ECEF<https://WikiPedia.org/wiki/ECEF>} converter.
|
|
@@ -1160,7 +1160,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1160
1160
|
v = v.times_(t, t, 0) # force z=0.0
|
|
1161
1161
|
h = x - a # equatorial
|
|
1162
1162
|
else: # normal in 1st quadrant
|
|
1163
|
-
x, y, i = _plumbTo3(x, y, self)
|
|
1163
|
+
x, y, i = _MODS.triaxials._plumbTo3(x, y, self)
|
|
1164
1164
|
t, v = v, v.times_(x, x, y)
|
|
1165
1165
|
h = t.minus(v).length
|
|
1166
1166
|
|
|
@@ -1522,9 +1522,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1522
1522
|
def _Rhumbs(self):
|
|
1523
1523
|
'''(INTERNAL) Get all C{Rhumb...} classes, I{once}.
|
|
1524
1524
|
'''
|
|
1525
|
-
|
|
1526
|
-
return (
|
|
1527
|
-
|
|
1525
|
+
r = _MODS.rhumb
|
|
1526
|
+
return (r.aux_.RhumbAux, # overwrite property_ROver
|
|
1527
|
+
r.ekx.Rhumb, r.solve.RhumbSolve)
|
|
1528
1528
|
|
|
1529
1529
|
@property
|
|
1530
1530
|
def rhumbsolve(self):
|
|
@@ -2276,47 +2276,6 @@ def n2f_(n):
|
|
|
2276
2276
|
return f2f_(n2f(n))
|
|
2277
2277
|
|
|
2278
2278
|
|
|
2279
|
-
def _plumbTo3(px, py, E, eps=EPS): # in .height4 above
|
|
2280
|
-
'''(INTERNAL) Nearest point on a 2-D ellipse in 1st quadrant.
|
|
2281
|
-
|
|
2282
|
-
@see: Functions C{pygeodesy.triaxial._plumbTo4} and C{-._plumbTo5}.
|
|
2283
|
-
'''
|
|
2284
|
-
a, b, e0 = E.a, E.b, EPS0
|
|
2285
|
-
if min(px, py, a, b) < e0:
|
|
2286
|
-
raise _AssertionError(px=px, py=py, a=a, b=b, E=E)
|
|
2287
|
-
|
|
2288
|
-
a2 = a - b * E.b_a
|
|
2289
|
-
b2 = b - a * E.a_b
|
|
2290
|
-
tx = ty = _SQRT2_2
|
|
2291
|
-
_a, _h = fabs, hypot
|
|
2292
|
-
for i in range(16): # max 5
|
|
2293
|
-
ex = a2 * tx**3
|
|
2294
|
-
ey = b2 * ty**3
|
|
2295
|
-
|
|
2296
|
-
qx = px - ex
|
|
2297
|
-
qy = py - ey
|
|
2298
|
-
q = _h(qx, qy)
|
|
2299
|
-
if q < e0: # PYCHOK no cover
|
|
2300
|
-
break
|
|
2301
|
-
r = _h(ex - tx * a,
|
|
2302
|
-
ey - ty * b) / q
|
|
2303
|
-
|
|
2304
|
-
sx, tx = tx, min(_1_0, max(0, (ex + qx * r) / a))
|
|
2305
|
-
sy, ty = ty, min(_1_0, max(0, (ey + qy * r) / b))
|
|
2306
|
-
t = _h(ty, tx)
|
|
2307
|
-
if t < e0: # PYCHOK no cover
|
|
2308
|
-
break
|
|
2309
|
-
tx = tx / t # /= chokes PyChecker
|
|
2310
|
-
ty = ty / t
|
|
2311
|
-
if _a(sx - tx) < eps and \
|
|
2312
|
-
_a(sy - ty) < eps:
|
|
2313
|
-
break
|
|
2314
|
-
|
|
2315
|
-
tx *= a / px
|
|
2316
|
-
ty *= b / py
|
|
2317
|
-
return tx, ty, i # x and y as fractions
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
2279
|
class Ellipsoids(_NamedEnum):
|
|
2321
2280
|
'''(INTERNAL) L{Ellipsoid} registry, I{must} be a sub-class
|
|
2322
2281
|
to accommodate the L{_LazyNamedEnumItem} properties.
|
pygeodesy/elliptic.py
CHANGED
|
@@ -84,12 +84,12 @@ from pygeodesy.constants import EPS, INF, NAN, PI, PI_2, PI_4, _0_0, \
|
|
|
84
84
|
# from pygeodesy.errors import _ValueError # from .fmath
|
|
85
85
|
from pygeodesy.fmath import favg, hypot1, zqrt, _ValueError
|
|
86
86
|
from pygeodesy.fsums import Fsum, _sum
|
|
87
|
-
|
|
87
|
+
from pygeodesy.internals import _DUNDER_nameof
|
|
88
88
|
from pygeodesy.interns import NN, _delta_, _DOT_, _f_, _invalid_, \
|
|
89
89
|
_invokation_, _negative_, _SPACE_
|
|
90
90
|
from pygeodesy.karney import _K_2_0, _norm180, _signBit, _sincos2
|
|
91
|
-
from pygeodesy.lazily import _ALL_LAZY
|
|
92
|
-
from pygeodesy.named import _Named, _NamedTuple, Fmt, unstr
|
|
91
|
+
# from pygeodesy.lazily import _ALL_LAZY # from .named
|
|
92
|
+
from pygeodesy.named import _Named, _NamedTuple, _ALL_LAZY, Fmt, unstr
|
|
93
93
|
from pygeodesy.props import _allPropertiesOf_n, Property_RO, _update_all
|
|
94
94
|
# from pygeodesy.streprs import Fmt, unstr # from .named
|
|
95
95
|
from pygeodesy.units import Scalar, Scalar_
|
|
@@ -99,7 +99,7 @@ from math import asin, asinh, atan, atan2, ceil, cosh, fabs, floor, \
|
|
|
99
99
|
radians, sin, sinh, sqrt, tan, tanh
|
|
100
100
|
|
|
101
101
|
__all__ = _ALL_LAZY.elliptic
|
|
102
|
-
__version__ = '24.
|
|
102
|
+
__version__ = '24.10.14'
|
|
103
103
|
|
|
104
104
|
_TolRD = zqrt(EPS * 0.002)
|
|
105
105
|
_TolRF = zqrt(EPS * 0.030)
|
|
@@ -408,9 +408,9 @@ class Elliptic(_Named):
|
|
|
408
408
|
def _Einv(self, x):
|
|
409
409
|
'''(INTERNAL) Helper for C{.deltaEinv} and C{.fEinv}.
|
|
410
410
|
'''
|
|
411
|
-
E2
|
|
412
|
-
n
|
|
413
|
-
r
|
|
411
|
+
E2 = self.cE * _2_0
|
|
412
|
+
n = floor(x / E2 + _0_5)
|
|
413
|
+
r = x - E2 * n # r in [-cE, cE)
|
|
414
414
|
# linear approximation
|
|
415
415
|
phi = PI * r / E2 # phi in [-PI_2, PI_2)
|
|
416
416
|
Phi = Fsum(phi)
|
|
@@ -427,7 +427,7 @@ class Elliptic(_Named):
|
|
|
427
427
|
sn = self.fE(sn, cn, dn)
|
|
428
428
|
phi, d = _Phi2((r - sn) / dn)
|
|
429
429
|
else: # PYCHOK no cover
|
|
430
|
-
d = _0_0 # XXX continue?
|
|
430
|
+
d = _0_0 # XXX or continue?
|
|
431
431
|
if fabs(d) < _TolJAC: # 3-4 trips
|
|
432
432
|
_iterations(self, i)
|
|
433
433
|
break
|
|
@@ -497,20 +497,20 @@ class Elliptic(_Named):
|
|
|
497
497
|
'''(INTERNAL) Core of C{.fE}.
|
|
498
498
|
'''
|
|
499
499
|
if sn:
|
|
500
|
-
|
|
501
|
-
kp2, k2
|
|
500
|
+
cn2, dn2 = cn**2, dn**2
|
|
501
|
+
kp2, k2 = self.kp2, self.k2
|
|
502
502
|
if k2 <= 0: # Carlson, eq. 4.6, <https://DLMF.NIST.gov/19.25.E9>
|
|
503
503
|
Ei = _RF3(self, cn2, dn2, _1_0)
|
|
504
504
|
if k2:
|
|
505
|
-
Ei -= _RD(self, cn2, dn2, _1_0, _3over(k2,
|
|
505
|
+
Ei -= _RD(self, cn2, dn2, _1_0, _3over(k2, sn**2))
|
|
506
506
|
elif kp2 >= 0: # k2 > 0, <https://DLMF.NIST.gov/19.25.E10>
|
|
507
507
|
Ei = _over(k2 * fabs(cn), dn) # float
|
|
508
508
|
if kp2:
|
|
509
|
-
Ei += (_RD( self, cn2, _1_0, dn2, _3over(k2,
|
|
509
|
+
Ei += (_RD( self, cn2, _1_0, dn2, _3over(k2, sn**2)) +
|
|
510
510
|
_RF3(self, cn2, dn2, _1_0)) * kp2
|
|
511
511
|
else: # kp2 < 0, <https://DLMF.NIST.gov/19.25.E11>
|
|
512
512
|
Ei = _over(dn, fabs(cn))
|
|
513
|
-
Ei -= _RD(self, dn2, _1_0, cn2, _3over(kp2,
|
|
513
|
+
Ei -= _RD(self, dn2, _1_0, cn2, _3over(kp2, sn**2))
|
|
514
514
|
Ei *= fabs(sn)
|
|
515
515
|
ei = float(Ei)
|
|
516
516
|
else: # PYCHOK no cover
|
|
@@ -1075,7 +1075,7 @@ def _ellipticError(where, *args, **kwds_cause_txt):
|
|
|
1075
1075
|
|
|
1076
1076
|
x, t, kwds = _x_t_kwds(**kwds_cause_txt)
|
|
1077
1077
|
|
|
1078
|
-
n =
|
|
1078
|
+
n = _DUNDER_nameof(where, where)
|
|
1079
1079
|
n = _DOT_(Elliptic.__name__, n)
|
|
1080
1080
|
n = _SPACE_(_invokation_, n)
|
|
1081
1081
|
u = unstr(n, *args, **kwds)
|
pygeodesy/errors.py
CHANGED
|
@@ -14,12 +14,12 @@ C{PYGEODESY_EXCEPTION_CHAINING=std} or to any non-empty string.
|
|
|
14
14
|
# from pygeodesy.basics import isint, isodd, issubclassof, itemsorted, _xinstanceof, _zip # _MODS
|
|
15
15
|
# from pygeodesy.ellipsoidalBase import CartesianEllipsoidalBase, LatLonEllipsoidalBase # _MODS
|
|
16
16
|
# from pygeodesy import errors # _MODS, _MODS.getattr
|
|
17
|
-
from pygeodesy.internals import
|
|
17
|
+
from pygeodesy.internals import _DUNDER_nameof_, _getPYGEODESY, _plural, _tailof
|
|
18
18
|
from pygeodesy.interns import MISSING, NN, _a_, _an_, _and_, _clip_, _COLON_, _COLONSPACE_, \
|
|
19
19
|
_COMMASPACE_, _datum_, _ELLIPSIS_, _ellipsoidal_, _incompatible_, \
|
|
20
20
|
_invalid_, _keyword_, _LatLon_, _len_, _not_, _or_, _SPACE_, \
|
|
21
21
|
_specified_, _UNDER_, _vs_, _with_
|
|
22
|
-
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS,
|
|
22
|
+
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYTHON_X_DEV
|
|
23
23
|
# from pygeodesy import streprs as _streprs # _MODS
|
|
24
24
|
# from pygeodesy.unitsBase import Str # _MODS
|
|
25
25
|
# from pygeodesy.vector3dBase import Vector3dBase # _MODS
|
|
@@ -27,7 +27,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _getenv, _PYTHON_X_D
|
|
|
27
27
|
from copy import copy as _copy
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.errors # _ALL_DOCS('_InvalidError', '_IsnotError') _under
|
|
30
|
-
__version__ = '24.
|
|
30
|
+
__version__ = '24.11.02'
|
|
31
31
|
|
|
32
32
|
_argument_ = 'argument'
|
|
33
33
|
_box_ = 'box'
|
|
@@ -43,7 +43,7 @@ try:
|
|
|
43
43
|
_exception_chaining = None # not available
|
|
44
44
|
_ = Exception().__cause__ # Python 3.9+ exception chaining
|
|
45
45
|
|
|
46
|
-
if _PYTHON_X_DEV or
|
|
46
|
+
if _PYTHON_X_DEV or _getPYGEODESY('EXCEPTION_CHAINING'): # == _std_
|
|
47
47
|
_exception_chaining = True # turned on, std
|
|
48
48
|
raise AttributeError() # allow exception chaining
|
|
49
49
|
|
|
@@ -527,7 +527,7 @@ def _IsnotError(*types__, **name_value_Error_cause): # name=value [, Error=Type
|
|
|
527
527
|
n, v = _xkwds_item2(kwds)
|
|
528
528
|
|
|
529
529
|
n = _streprs.Fmt.PARENSPACED(n, repr(v))
|
|
530
|
-
t = _not_(_an(_or(*
|
|
530
|
+
t = _not_(_an(_or(*_DUNDER_nameof_(*types__))) if types__ else _specified_)
|
|
531
531
|
return _XError(E, n, txt=t, cause=x)
|
|
532
532
|
|
|
533
533
|
|
|
@@ -777,7 +777,7 @@ except AttributeError:
|
|
|
777
777
|
return d
|
|
778
778
|
|
|
779
779
|
|
|
780
|
-
# def _xkwds_bool(inst, **kwds): #
|
|
780
|
+
# def _xkwds_bool(inst, **kwds): # unused
|
|
781
781
|
# '''(INTERNAL) Set applicable C{bool} properties/attributes.
|
|
782
782
|
# '''
|
|
783
783
|
# for n, v in kwds.items():
|
|
@@ -789,18 +789,18 @@ except AttributeError:
|
|
|
789
789
|
# setattr(inst, NN(_UNDER_, n), v)
|
|
790
790
|
|
|
791
791
|
|
|
792
|
-
def _xkwds_from(orig, *args, **kwds):
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
792
|
+
# def _xkwds_from(orig, *args, **kwds): # unused
|
|
793
|
+
# '''(INTERNAL) Return the items from C{orig} with the keys
|
|
794
|
+
# from C{kwds} and a value not in C{args} and C{kwds}.
|
|
795
|
+
# '''
|
|
796
|
+
# def _items(orig, args, items):
|
|
797
|
+
# for n, m in items:
|
|
798
|
+
# if n in orig: # n in (orig.keys() & kwds.keys())
|
|
799
|
+
# t = orig[n]
|
|
800
|
+
# if t is not m and t not in args:
|
|
801
|
+
# yield n, t
|
|
802
|
+
#
|
|
803
|
+
# return _items(orig, args, kwds.items())
|
|
804
804
|
|
|
805
805
|
|
|
806
806
|
def _xkwds_get(kwds, **name_default):
|
|
@@ -813,14 +813,14 @@ def _xkwds_get(kwds, **name_default):
|
|
|
813
813
|
raise _xAssertionError(_xkwds_get, kwds, **name_default)
|
|
814
814
|
|
|
815
815
|
|
|
816
|
-
def _xkwds_get_(kwds, **names_defaults):
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
816
|
+
# def _xkwds_get_(kwds, **names_defaults): # unused
|
|
817
|
+
# '''(INTERNAL) Yield each C{kwds} value or its C{default}
|
|
818
|
+
# in I{case-insensitive, alphabetical} C{name} order.
|
|
819
|
+
# '''
|
|
820
|
+
# if not isinstance(kwds, dict):
|
|
821
|
+
# raise _xAssertionError(_xkwds_get_, kwds)
|
|
822
|
+
# for n, v in _MODS.basics.itemsorted(names_defaults):
|
|
823
|
+
# yield kwds.get(n, v)
|
|
824
824
|
|
|
825
825
|
|
|
826
826
|
def _xkwds_get1(kwds, **name_default):
|
|
@@ -844,11 +844,11 @@ def _xkwds_item2(kwds):
|
|
|
844
844
|
raise _xAssertionError(_xkwds_item2, kwds)
|
|
845
845
|
|
|
846
846
|
|
|
847
|
-
def _xkwds_kwds(kwds, **names_defaults):
|
|
847
|
+
def _xkwds_kwds(kwds, **names_defaults): # in .geodesici # PYCHOK no cover
|
|
848
848
|
'''(INTERNAL) Return a C{dict} of C{named_defaults} items replaced with C{kwds}.
|
|
849
849
|
'''
|
|
850
850
|
if not isinstance(kwds, dict):
|
|
851
|
-
raise _xAssertionError(
|
|
851
|
+
raise _xAssertionError(_xkwds_kwds, kwds)
|
|
852
852
|
_g = kwds.get
|
|
853
853
|
return dict((n, _g(n, v)) for n, v in names_defaults.items())
|
|
854
854
|
|