pygeodesy 24.11.11__py2.py3-none-any.whl → 25.1.5__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.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/METADATA +34 -35
- PyGeodesy-25.1.5.dist-info/RECORD +118 -0
- {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +19 -19
- pygeodesy/__main__.py +1 -1
- pygeodesy/albers.py +5 -5
- pygeodesy/auxilats/_CX_4.py +1 -1
- pygeodesy/auxilats/_CX_6.py +1 -1
- pygeodesy/auxilats/_CX_8.py +1 -1
- pygeodesy/auxilats/_CX_Rs.py +1 -1
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +1 -1
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDLat.py +6 -6
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +5 -5
- pygeodesy/basics.py +60 -8
- pygeodesy/booleans.py +1 -1
- pygeodesy/cartesianBase.py +22 -61
- pygeodesy/clipy.py +1 -1
- pygeodesy/constants.py +5 -5
- pygeodesy/css.py +1 -1
- pygeodesy/datums.py +1 -1
- pygeodesy/deprecated/__init__.py +2 -2
- pygeodesy/deprecated/bases.py +1 -1
- pygeodesy/deprecated/classes.py +86 -2
- pygeodesy/deprecated/consterns.py +1 -1
- pygeodesy/deprecated/datum.py +5 -5
- pygeodesy/deprecated/functions.py +42 -8
- pygeodesy/deprecated/nvector.py +1 -1
- pygeodesy/deprecated/rhumbBase.py +1 -1
- pygeodesy/deprecated/rhumbaux.py +1 -1
- pygeodesy/deprecated/rhumbsolve.py +1 -1
- pygeodesy/deprecated/rhumbx.py +1 -1
- pygeodesy/dms.py +1 -1
- pygeodesy/ecef.py +53 -56
- pygeodesy/elevations.py +1 -1
- pygeodesy/ellipsoidalBase.py +3 -3
- pygeodesy/ellipsoidalBaseDI.py +1 -1
- pygeodesy/ellipsoidalExact.py +1 -1
- pygeodesy/ellipsoidalGeodSolve.py +1 -1
- pygeodesy/ellipsoidalKarney.py +1 -1
- pygeodesy/ellipsoidalNvector.py +1 -1
- pygeodesy/ellipsoidalVincenty.py +6 -5
- pygeodesy/ellipsoids.py +4 -5
- pygeodesy/elliptic.py +6 -6
- pygeodesy/epsg.py +1 -1
- pygeodesy/errors.py +1 -1
- pygeodesy/etm.py +5 -5
- pygeodesy/fmath.py +18 -17
- pygeodesy/formy.py +409 -555
- pygeodesy/frechet.py +29 -86
- pygeodesy/fstats.py +1 -1
- pygeodesy/fsums.py +32 -33
- pygeodesy/gars.py +1 -1
- pygeodesy/geodesici.py +7 -7
- pygeodesy/geodesicw.py +1 -1
- pygeodesy/geodesicx/_C4_24.py +2 -2
- pygeodesy/geodesicx/_C4_27.py +2 -2
- pygeodesy/geodesicx/_C4_30.py +2 -2
- pygeodesy/geodesicx/__init__.py +2 -2
- pygeodesy/geodesicx/__main__.py +4 -5
- pygeodesy/geodesicx/gx.py +6 -5
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxbases.py +2 -2
- pygeodesy/geodesicx/gxline.py +16 -12
- pygeodesy/geodsolve.py +1 -1
- pygeodesy/geohash.py +1 -1
- pygeodesy/geoids.py +277 -203
- pygeodesy/hausdorff.py +23 -81
- pygeodesy/heights.py +115 -150
- pygeodesy/internals.py +1 -1
- pygeodesy/interns.py +2 -3
- pygeodesy/iters.py +1 -1
- pygeodesy/karney.py +3 -3
- pygeodesy/ktm.py +16 -15
- pygeodesy/latlonBase.py +323 -409
- pygeodesy/lazily.py +53 -44
- pygeodesy/lcc.py +1 -1
- pygeodesy/ltp.py +46 -50
- pygeodesy/ltpTuples.py +147 -130
- pygeodesy/mgrs.py +1 -1
- pygeodesy/named.py +149 -3
- pygeodesy/namedTuples.py +58 -7
- pygeodesy/nvectorBase.py +122 -105
- pygeodesy/osgr.py +1 -1
- pygeodesy/points.py +1 -1
- pygeodesy/props.py +1 -1
- pygeodesy/resections.py +18 -17
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +2 -2
- pygeodesy/rhumb/bases.py +2 -2
- pygeodesy/rhumb/ekx.py +4 -4
- pygeodesy/rhumb/solve.py +1 -1
- pygeodesy/simplify.py +289 -401
- pygeodesy/solveBase.py +1 -1
- pygeodesy/sphericalBase.py +1 -1
- pygeodesy/sphericalNvector.py +5 -5
- pygeodesy/sphericalTrigonometry.py +7 -6
- pygeodesy/streprs.py +10 -5
- pygeodesy/trf.py +1 -1
- pygeodesy/triaxials.py +23 -16
- pygeodesy/units.py +16 -16
- pygeodesy/unitsBase.py +1 -1
- pygeodesy/ups.py +4 -4
- pygeodesy/utily.py +341 -211
- pygeodesy/utm.py +5 -5
- pygeodesy/utmups.py +1 -1
- pygeodesy/utmupsBase.py +1 -1
- pygeodesy/vector2d.py +5 -5
- pygeodesy/vector3d.py +14 -3
- pygeodesy/vector3dBase.py +5 -5
- pygeodesy/webmercator.py +1 -1
- pygeodesy/wgrs.py +1 -1
- PyGeodesy-24.11.11.dist-info/RECORD +0 -118
- {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/top_level.txt +0 -0
pygeodesy/nvectorBase.py
CHANGED
|
@@ -11,14 +11,14 @@ and published under the same MIT Licence**, see U{Vector-based geodesy
|
|
|
11
11
|
'''
|
|
12
12
|
|
|
13
13
|
# from pygeodesy.basics import map1 # from .namedTuples
|
|
14
|
-
from pygeodesy.constants import EPS, EPS1, EPS_2, R_M,
|
|
14
|
+
from pygeodesy.constants import EPS, EPS0, EPS1, EPS_2, R_M, \
|
|
15
|
+
_0_0, _1_0, _2_0, _N_2_0
|
|
15
16
|
# from pygeodesy.datums import _spherical_datum # from .formy
|
|
16
17
|
from pygeodesy.errors import IntersectionError, _ValueError, VectorError, \
|
|
17
18
|
_xattrs, _xkwds, _xkwds_pop2
|
|
18
|
-
from pygeodesy.fmath import fdot, fidw,
|
|
19
|
+
from pygeodesy.fmath import fdot, fidw, hypot # PYCHOK fdot shared
|
|
19
20
|
from pygeodesy.fsums import Fsum, fsumf_
|
|
20
|
-
from pygeodesy.formy import _isequalTo,
|
|
21
|
-
_spherical_datum
|
|
21
|
+
from pygeodesy.formy import _isequalTo, _spherical_datum
|
|
22
22
|
# from pygeodesy.internals import _under # from .named
|
|
23
23
|
from pygeodesy.interns import NN, _1_, _2_, _3_, _bearing_, _coincident_, \
|
|
24
24
|
_COMMASPACE_, _distance_, _h_, _insufficient_, \
|
|
@@ -26,23 +26,23 @@ from pygeodesy.interns import NN, _1_, _2_, _3_, _bearing_, _coincident_, \
|
|
|
26
26
|
from pygeodesy.latlonBase import LatLonBase, _ALL_DOCS, _ALL_LAZY, _MODS
|
|
27
27
|
# from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS # from .latlonBase
|
|
28
28
|
from pygeodesy.named import _xother3, _under
|
|
29
|
-
from pygeodesy.namedTuples import
|
|
30
|
-
Vector4Tuple, map1
|
|
29
|
+
from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Trilaterate5Tuple, \
|
|
30
|
+
Vector3Tuple, Vector4Tuple, map1
|
|
31
31
|
from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
|
|
32
32
|
property_RO, property_ROnce, _update_all
|
|
33
33
|
from pygeodesy.streprs import Fmt, hstr, unstr
|
|
34
34
|
from pygeodesy.units import Bearing, Height, Radius_, Scalar
|
|
35
|
-
from pygeodesy.utily import sincos2d, _unrollon, _unrollon3
|
|
35
|
+
from pygeodesy.utily import atan2, sincos2d, _unrollon, _unrollon3
|
|
36
36
|
from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
37
37
|
|
|
38
|
-
from math import fabs, sqrt
|
|
38
|
+
from math import degrees, fabs, sqrt
|
|
39
39
|
|
|
40
40
|
__all__ = _ALL_LAZY.nvectorBase
|
|
41
|
-
__version__ = '24.
|
|
41
|
+
__version__ = '24.11.24'
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class NvectorBase(Vector3d): # XXX kept private
|
|
45
|
-
'''Base class for ellipsoidal and spherical C{Nvector}s.
|
|
45
|
+
'''(INTERNAL) Base class for ellipsoidal and spherical C{Nvector}s.
|
|
46
46
|
'''
|
|
47
47
|
_datum = None # L{Datum}, overriden
|
|
48
48
|
_h = Height(h=0) # height (C{meter})
|
|
@@ -51,8 +51,8 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
51
51
|
def __init__(self, x_xyz, y=None, z=None, h=0, datum=None, **ll_name):
|
|
52
52
|
'''New n-vector normal to the earth's surface.
|
|
53
53
|
|
|
54
|
-
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector
|
|
55
|
-
|
|
54
|
+
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Nvector},
|
|
55
|
+
L{Vector3d}, L{Vector3Tuple} or L{Vector4Tuple}).
|
|
56
56
|
@kwarg y: Y component of vector (C{scalar}), required if B{C{x_xyz}} is
|
|
57
57
|
C{scalar} and same units as B{C{x_xyz}}, ignored otherwise.
|
|
58
58
|
@kwarg z: Z component of vector (C{scalar}), like B{C{y}}.
|
|
@@ -159,7 +159,7 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
159
159
|
def latlon(self):
|
|
160
160
|
'''Get the (geodetic) lat-, longitude in C{degrees} (L{LatLon2Tuple}C{(lat, lon)}).
|
|
161
161
|
'''
|
|
162
|
-
return n_xyz2latlon(self
|
|
162
|
+
return n_xyz2latlon(self, name=self.name)
|
|
163
163
|
|
|
164
164
|
@Property_RO
|
|
165
165
|
def latlonheight(self):
|
|
@@ -189,7 +189,7 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
189
189
|
def philam(self):
|
|
190
190
|
'''Get the (geodetic) lat-, longitude in C{radians} (L{PhiLam2Tuple}C{(phi, lam)}).
|
|
191
191
|
'''
|
|
192
|
-
return n_xyz2philam(self
|
|
192
|
+
return n_xyz2philam(self, name=self.name)
|
|
193
193
|
|
|
194
194
|
@Property_RO
|
|
195
195
|
def philamheight(self):
|
|
@@ -211,89 +211,71 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
211
211
|
|
|
212
212
|
@deprecated_method
|
|
213
213
|
def to2ab(self): # PYCHOK no cover
|
|
214
|
-
'''DEPRECATED, use property L{philam}.
|
|
215
|
-
|
|
216
|
-
@return: A L{PhiLam2Tuple}C{(phi, lam)}.
|
|
217
|
-
'''
|
|
214
|
+
'''DEPRECATED, use property L{philam}.'''
|
|
218
215
|
return self.philam
|
|
219
216
|
|
|
220
217
|
@deprecated_method
|
|
221
218
|
def to3abh(self, height=None): # PYCHOK no cover
|
|
222
|
-
'''DEPRECATED, use property L{philamheight} or C{philam.to3Tuple(B{height})}.
|
|
223
|
-
|
|
224
|
-
@kwarg height: Optional height, overriding this
|
|
225
|
-
n-vector's height (C{meter}).
|
|
226
|
-
|
|
227
|
-
@return: A L{PhiLam3Tuple}C{(phi, lam, height)}.
|
|
228
|
-
|
|
229
|
-
@raise ValueError: Invalid B{C{height}}.
|
|
230
|
-
'''
|
|
219
|
+
'''DEPRECATED, use property L{philamheight} or C{philam.to3Tuple(B{height})}.'''
|
|
231
220
|
return self.philamheight if height in (None, self.h) else \
|
|
232
221
|
self.philam.to3Tuple(height)
|
|
233
222
|
|
|
234
|
-
def toCartesian(self, h=None, Cartesian=None, datum=None, **
|
|
223
|
+
def toCartesian(self, h=None, Cartesian=None, datum=None, **name_Cartesian_kwds): # PYCHOK signature
|
|
235
224
|
'''Convert this n-vector to C{Nvector}-based cartesian (ECEF) coordinates.
|
|
236
225
|
|
|
237
226
|
@kwarg h: Optional height, overriding this n-vector's height (C{meter}).
|
|
238
|
-
@kwarg Cartesian: Optional class to return the (ECEF) coordinates
|
|
239
|
-
(C{Cartesian}).
|
|
227
|
+
@kwarg Cartesian: Optional class to return the (ECEF) coordinates (C{Cartesian}).
|
|
240
228
|
@kwarg datum: Optional datum (C{Datum}), overriding this datum.
|
|
241
|
-
@kwarg
|
|
242
|
-
|
|
229
|
+
@kwarg name_Cartesian_kwds: Optional C{B{name}=NN} (C{str}) and optionally, additional
|
|
230
|
+
B{C{Cartesian}} keyword arguments, ignored if C{B{Cartesian} is None}.
|
|
243
231
|
|
|
244
|
-
@return: The
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
available.
|
|
232
|
+
@return: The (ECEF) coordinates (B{C{Cartesian}}) or if C{B{Cartesian} is None}, an
|
|
233
|
+
L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M}
|
|
234
|
+
if available.
|
|
248
235
|
|
|
249
|
-
@raise TypeError: Invalid B{C{Cartesian}} or B{C{
|
|
250
|
-
argument.
|
|
236
|
+
@raise TypeError: Invalid B{C{Cartesian}} or B{C{name_Cartesian_kwds}} argument.
|
|
251
237
|
|
|
252
238
|
@raise ValueError: Invalid B{C{h}}.
|
|
253
239
|
'''
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
r
|
|
262
|
-
|
|
263
|
-
x *= r
|
|
264
|
-
y *= r
|
|
265
|
-
z *= h + n
|
|
240
|
+
if h is None:
|
|
241
|
+
h = self.h
|
|
242
|
+
elif not isinstance(h, Height):
|
|
243
|
+
h = Height(h=h, Error=VectorError)
|
|
244
|
+
_, r, v = self._toEcefDrv3(Cartesian, None, datum, h, **name_Cartesian_kwds)
|
|
245
|
+
if r is None:
|
|
246
|
+
r = v.toCartesian(Cartesian, **self._name1__(name_Cartesian_kwds)) # h=0
|
|
247
|
+
return r
|
|
266
248
|
|
|
267
|
-
|
|
268
|
-
|
|
249
|
+
def _toEcefDrv3(self, CC, LL, datum, h, name=NN, **unused):
|
|
250
|
+
'''(INTERNAL) Helper for methods C{toCartesian} and C{toLatLon}.
|
|
251
|
+
'''
|
|
252
|
+
D = self.datum if datum in (None, self.datum) else \
|
|
253
|
+
_spherical_datum(datum, name=self.name)
|
|
254
|
+
if LL is None:
|
|
255
|
+
v = Vector3d(self, name=name or self.name) # .toVector3d(norm=False)
|
|
256
|
+
E = D.ellipsoid
|
|
257
|
+
r = E.a_b # Kenneth Gade eqn 22
|
|
258
|
+
n = v.times_(r, r, _1_0).length
|
|
259
|
+
n = (E.b / n) if n > EPS0 else _0_0
|
|
260
|
+
r = E.a2_b2 * n + h # fma
|
|
261
|
+
v = v.times_(r, r, n + h)
|
|
262
|
+
r = self.Ecef(D).reverse(v, M=True) if CC is None else None
|
|
269
263
|
else:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return self._xnamed(r)
|
|
264
|
+
r = v = None
|
|
265
|
+
return D, r, v
|
|
273
266
|
|
|
274
267
|
@deprecated_method
|
|
275
268
|
def to2ll(self): # PYCHOK no cover
|
|
276
|
-
'''DEPRECATED, use property L{latlon}.
|
|
277
|
-
|
|
278
|
-
@return: A L{LatLon2Tuple}C{(lat, lon)}.
|
|
279
|
-
'''
|
|
269
|
+
'''DEPRECATED, use property L{latlon}.'''
|
|
280
270
|
return self.latlon
|
|
281
271
|
|
|
282
272
|
@deprecated_method
|
|
283
273
|
def to3llh(self, height=None): # PYCHOK no cover
|
|
284
|
-
'''DEPRECATED, use property C{latlonheight} or C{latlon.to3Tuple(B{height})}.
|
|
285
|
-
|
|
286
|
-
@kwarg height: Optional height, overriding this
|
|
287
|
-
n-vector's height (C{meter}).
|
|
288
|
-
|
|
289
|
-
@return: A L{LatLon3Tuple}C{(lat, lon, height)}.
|
|
290
|
-
|
|
291
|
-
@raise ValueError: Invalid B{C{height}}.
|
|
292
|
-
'''
|
|
274
|
+
'''DEPRECATED, use property C{latlonheight} or C{latlon.to3Tuple(B{height})}.'''
|
|
293
275
|
return self.latlonheight if height in (None, self.h) else \
|
|
294
276
|
self.latlon.to3Tuple(height)
|
|
295
277
|
|
|
296
|
-
def toLatLon(self, height=None, LatLon=None, datum=None, **
|
|
278
|
+
def toLatLon(self, height=None, LatLon=None, datum=None, **name_LatLon_kwds):
|
|
297
279
|
'''Convert this n-vector to an C{Nvector}-based geodetic point.
|
|
298
280
|
|
|
299
281
|
@kwarg height: Optional height, overriding this n-vector's
|
|
@@ -301,26 +283,26 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
301
283
|
@kwarg LatLon: Optional class to return the geodetic point
|
|
302
284
|
(C{LatLon}) or C{None}.
|
|
303
285
|
@kwarg datum: Optional, spherical datum (C{Datum}).
|
|
304
|
-
@kwarg
|
|
305
|
-
|
|
286
|
+
@kwarg name_LatLon_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
|
|
287
|
+
additional B{C{LatLon}} keyword arguments, ignored if
|
|
288
|
+
C{B{LatLon} is None}.
|
|
306
289
|
|
|
307
290
|
@return: The geodetic point (C{LatLon}) or if C{B{LatLon} is None},
|
|
308
|
-
an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M,
|
|
309
|
-
|
|
291
|
+
an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
|
|
292
|
+
with C{C} and C{M} if available.
|
|
310
293
|
|
|
311
|
-
@raise TypeError: Invalid B{C{LatLon}} or B{C{
|
|
312
|
-
argument.
|
|
294
|
+
@raise TypeError: Invalid B{C{LatLon}} or B{C{name_LatLon_kwds}} argument.
|
|
313
295
|
|
|
314
296
|
@raise ValueError: Invalid B{C{height}}.
|
|
315
297
|
'''
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
#
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
kwds = _xkwds(
|
|
298
|
+
h = self.h if height is None else (
|
|
299
|
+
height if isinstance(height, Height) else
|
|
300
|
+
Height(height, Error=VectorError))
|
|
301
|
+
# use the .toCartesian() logic for better height accuracy instead of
|
|
302
|
+
# r = self.Ecef(D).forward(self.lat, self.lon, height=h, M=True)
|
|
303
|
+
D, r, _ = self._toEcefDrv3(None, LatLon, datum, h, **name_LatLon_kwds)
|
|
304
|
+
if r is None:
|
|
305
|
+
kwds = _xkwds(name_LatLon_kwds, height=h, datum=D)
|
|
324
306
|
r = LatLon(self.lat, self.lon, **self._name1__(kwds))
|
|
325
307
|
return r
|
|
326
308
|
|
|
@@ -349,7 +331,7 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
349
331
|
@return: The (normalized) vector (L{Vector3d}).
|
|
350
332
|
'''
|
|
351
333
|
v = Vector3d.unit(self) if norm else self
|
|
352
|
-
return Vector3d(v
|
|
334
|
+
return Vector3d(v, name=self.name)
|
|
353
335
|
|
|
354
336
|
@deprecated_method
|
|
355
337
|
def to4xyzh(self, h=None): # PYCHOK no cover
|
|
@@ -373,10 +355,6 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
373
355
|
return self.xyz.to4Tuple(self.h)
|
|
374
356
|
|
|
375
357
|
|
|
376
|
-
NorthPole = NvectorBase(0, 0, +1, name='NorthPole') # North pole (C{Nvector})
|
|
377
|
-
SouthPole = NvectorBase(0, 0, -1, name='SouthPole') # South pole (C{Nvector})
|
|
378
|
-
|
|
379
|
-
|
|
380
358
|
class _N_vector_(NvectorBase):
|
|
381
359
|
'''(INTERNAL) Minimal, low-overhead C{n-vector}.
|
|
382
360
|
'''
|
|
@@ -388,16 +366,19 @@ class _N_vector_(NvectorBase):
|
|
|
388
366
|
self.name = name
|
|
389
367
|
|
|
390
368
|
|
|
369
|
+
NorthPole = _N_vector_(0, 0, +1, name='NorthPole') # North pole
|
|
370
|
+
SouthPole = _N_vector_(0, 0, -1, name='SouthPole') # South pole
|
|
371
|
+
|
|
372
|
+
|
|
391
373
|
class LatLonNvectorBase(LatLonBase):
|
|
392
|
-
'''(INTERNAL) Base class for n-vector-based ellipsoidal and
|
|
393
|
-
spherical C{LatLon} classes.
|
|
374
|
+
'''(INTERNAL) Base class for n-vector-based ellipsoidal and spherical C{LatLon}s.
|
|
394
375
|
'''
|
|
395
376
|
|
|
396
377
|
def _update(self, updated, *attrs, **setters): # PYCHOK _Nv=None
|
|
397
378
|
'''(INTERNAL) Zap cached attributes if updated.
|
|
398
379
|
|
|
399
|
-
@see: C{ellipsoidalNvector.LatLon} and C{sphericalNvector.LatLon}
|
|
400
|
-
|
|
380
|
+
@see: C{ellipsoidalNvector.LatLon} and C{sphericalNvector.LatLon} for
|
|
381
|
+
the special case of B{C{_Nv}}.
|
|
401
382
|
'''
|
|
402
383
|
if updated:
|
|
403
384
|
_Nv, setters = _xkwds_pop2(setters, _Nv=None)
|
|
@@ -498,10 +479,10 @@ class LatLonNvectorBase(LatLonBase):
|
|
|
498
479
|
@raise ValueError: Some B{C{points}} coincide or invalid B{C{distance1}},
|
|
499
480
|
B{C{distance2}}, B{C{distance3}} or B{C{radius}}.
|
|
500
481
|
|
|
501
|
-
@see: U{Trilateration<https://WikiPedia.org/wiki/Trilateration>},
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
482
|
+
@see: U{Trilateration<https://WikiPedia.org/wiki/Trilateration>}, I{Veness}'
|
|
483
|
+
JavaScript U{Trilateration<https://www.Movable-Type.co.UK/scripts/
|
|
484
|
+
latlong-vectors.html>} and method C{LatLon.trilaterate5} of other,
|
|
485
|
+
non-C{Nvector LatLon} classes.
|
|
505
486
|
'''
|
|
506
487
|
return _trilaterate(self, distance1, self.others(point2=point2), distance2,
|
|
507
488
|
self.others(point3=point3), distance3,
|
|
@@ -510,16 +491,13 @@ class LatLonNvectorBase(LatLonBase):
|
|
|
510
491
|
|
|
511
492
|
def trilaterate5(self, distance1, point2, distance2, point3, distance3, # PYCHOK signature
|
|
512
493
|
area=False, eps=EPS1, radius=R_M, wrap=False):
|
|
513
|
-
'''B{Not implemented} for C{B{area}=True} and falls back to method
|
|
514
|
-
C{trilaterate} otherwise.
|
|
494
|
+
'''B{Not implemented} for C{B{area}=True} and falls back to method C{trilaterate}.
|
|
515
495
|
|
|
516
|
-
@return: A L{Trilaterate5Tuple}C{(min, minPoint, max, maxPoint, n)}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
margin and count C{n = 1}.
|
|
496
|
+
@return: A L{Trilaterate5Tuple}C{(min, minPoint, max, maxPoint, n)} with a
|
|
497
|
+
single trilaterated intersection C{minPoint I{is} maxPoint}, C{min
|
|
498
|
+
I{is} max} the nearest intersection margin and count C{n = 1}.
|
|
520
499
|
|
|
521
|
-
@raise NotImplementedError: Keyword argument C{B{area}=True} not
|
|
522
|
-
(yet) supported.
|
|
500
|
+
@raise NotImplementedError: Keyword argument C{B{area}=True} not (yet) supported.
|
|
523
501
|
|
|
524
502
|
@see: Method L{trilaterate} for other and more details.
|
|
525
503
|
'''
|
|
@@ -540,6 +518,45 @@ class LatLonNvectorBase(LatLonBase):
|
|
|
540
518
|
raise IntersectionError(area=area, eps=eps, radius=radius, wrap=wrap, txt=t)
|
|
541
519
|
|
|
542
520
|
|
|
521
|
+
def n_xyz2latlon(x_xyz, y=0, z=0, **name):
|
|
522
|
+
'''Convert C{n-vector} to (geodetic) lat- and longitude in C{degrees}.
|
|
523
|
+
|
|
524
|
+
@arg x_xyz: X component (C{scalar}) or (3-D) vector (C{Nvector},
|
|
525
|
+
L{Vector3d}, L{Vector3Tuple} or L{Vector4Tuple}).
|
|
526
|
+
@kwarg y: Y component of vector (C{scalar}), required if C{B{x_xyz} is
|
|
527
|
+
scalar} and same units as B{C{x_xyz}}, ignored otherwise.
|
|
528
|
+
@kwarg z: Z component of vector (C{scalar}), like B{C{y}}.
|
|
529
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
530
|
+
|
|
531
|
+
@return: A L{LatLon2Tuple}C{(lat, lon)}.
|
|
532
|
+
|
|
533
|
+
@see: Function L{n_xyz2philam}.
|
|
534
|
+
'''
|
|
535
|
+
ll = map(degrees, n_xyz2philam(x_xyz, y, z))
|
|
536
|
+
return LatLon2Tuple(*ll, **name)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def n_xyz2philam(x_xyz, y=0, z=0, **name):
|
|
540
|
+
'''Convert C{n-vector} to (geodetic) lat- and longitude in C{radians}.
|
|
541
|
+
|
|
542
|
+
@arg x_xyz: X component (C{scalar}) or (3-D) vector (C{Nvector},
|
|
543
|
+
L{Vector3d}, L{Vector3Tuple} or L{Vector4Tuple}).
|
|
544
|
+
@kwarg y: Y component of vector (C{scalar}), required if C{B{x_xyz} is
|
|
545
|
+
scalar} and same units as B{C{x_xyz}}, ignored otherwise.
|
|
546
|
+
@kwarg z: Z component of vector (C{scalar}), like B{C{y}}.
|
|
547
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
548
|
+
|
|
549
|
+
@return: A L{PhiLam2Tuple}C{(phi, lam)}.
|
|
550
|
+
|
|
551
|
+
@see: Function L{n_xyz2latlon}.
|
|
552
|
+
'''
|
|
553
|
+
try:
|
|
554
|
+
x, y, z = x_xyz.xyz
|
|
555
|
+
except AttributeError:
|
|
556
|
+
x = x_xyz
|
|
557
|
+
return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), **name)
|
|
558
|
+
|
|
559
|
+
|
|
543
560
|
def _nsumOf(nvs, h_None, Vector, Vector_kwds): # .sphericalNvector, .vector3d
|
|
544
561
|
'''(INTERNAL) Separated to allow callers to embellish exceptions.
|
|
545
562
|
'''
|
|
@@ -670,7 +687,7 @@ __all__ += _ALL_DOCS(LatLonNvectorBase, NvectorBase, sumOf) # classes
|
|
|
670
687
|
|
|
671
688
|
# **) MIT License
|
|
672
689
|
#
|
|
673
|
-
# Copyright (C) 2016-
|
|
690
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
674
691
|
#
|
|
675
692
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
676
693
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/osgr.py
CHANGED
|
@@ -722,7 +722,7 @@ if __name__ == '__main__':
|
|
|
722
722
|
|
|
723
723
|
# **) MIT License
|
|
724
724
|
#
|
|
725
|
-
# Copyright (C) 2016-
|
|
725
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
726
726
|
#
|
|
727
727
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
728
728
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/points.py
CHANGED
|
@@ -1665,7 +1665,7 @@ __all__ += _ALL_DOCS(_Array2LatLon, _Basequence)
|
|
|
1665
1665
|
|
|
1666
1666
|
# **) MIT License
|
|
1667
1667
|
#
|
|
1668
|
-
# Copyright (C) 2016-
|
|
1668
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1669
1669
|
#
|
|
1670
1670
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1671
1671
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/props.py
CHANGED
|
@@ -701,7 +701,7 @@ _throwarning = DeprecationWarnings.throw
|
|
|
701
701
|
|
|
702
702
|
# **) MIT License
|
|
703
703
|
#
|
|
704
|
-
# Copyright (C) 2016-
|
|
704
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
705
705
|
#
|
|
706
706
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
707
707
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/resections.py
CHANGED
|
@@ -15,26 +15,26 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
15
15
|
from pygeodesy.basics import map1, map2, _zip, _ALL_LAZY
|
|
16
16
|
from pygeodesy.constants import EPS, EPS0, EPS02, INT0, PI, PI2, PI_2, PI_4, \
|
|
17
17
|
_0_0, _0_5, _1_0, _N_1_0, _2_0, _N_2_0, _4_0, \
|
|
18
|
-
_16_0, _180_0, _360_0,
|
|
19
|
-
_over, _umod_360
|
|
18
|
+
_16_0, _180_0, _360_0, isnear0, _over, _umod_360
|
|
20
19
|
from pygeodesy.errors import _and, _or, TriangleError, _ValueError, _xcallable, \
|
|
21
20
|
_xkwds, _xkwds_pop2
|
|
22
21
|
from pygeodesy.fmath import favg, Fdot, fidw, fmean, hypot, hypot2_
|
|
23
22
|
from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1, fsum1f_
|
|
24
23
|
from pygeodesy.interns import _a_, _A_, _area_, _b_, _B_, _c_, _C_, _coincident_, \
|
|
25
|
-
_colinear_, _d_,
|
|
24
|
+
_colinear_, _d_, _invalid_, _negative_, _not_, \
|
|
26
25
|
_rIn_, _SPACE_
|
|
27
26
|
# from pygeodesy.lazily import _ALL_LAZY # from .basics
|
|
28
27
|
from pygeodesy.named import _NamedTuple, _Pass, Fmt
|
|
29
28
|
# from pygeodesy.streprs import Fmt # from .named
|
|
30
29
|
from pygeodesy.units import Degrees, Distance, Radians
|
|
31
|
-
from pygeodesy.utily import acos1, asin1, sincos2, sincos2_,
|
|
30
|
+
from pygeodesy.utily import acos1, asin1, atan2, sincos2, sincos2_, \
|
|
31
|
+
sincos2d, sincos2d_
|
|
32
32
|
from pygeodesy.vector3d import _otherV3d, Vector3d
|
|
33
33
|
|
|
34
|
-
from math import cos,
|
|
34
|
+
from math import cos, degrees, fabs, radians, sin, sqrt
|
|
35
35
|
|
|
36
36
|
__all__ = _ALL_LAZY.resections
|
|
37
|
-
__version__ = '24.11.
|
|
37
|
+
__version__ = '24.11.27'
|
|
38
38
|
|
|
39
39
|
_concyclic_ = 'concyclic'
|
|
40
40
|
_PA_ = 'PA'
|
|
@@ -340,7 +340,8 @@ def pierlot(point1, point2, point3, alpha12, alpha23, useZ=False, eps=EPS,
|
|
|
340
340
|
def _cot(s, c): # -eps < I{approximate} cotangent < eps
|
|
341
341
|
if eps > 0:
|
|
342
342
|
return c / (min(s, -eps) if s < 0 else max(s, eps))
|
|
343
|
-
|
|
343
|
+
t = Fmt.PARENSPACED(eps=eps)
|
|
344
|
+
raise ValueError(_SPACE_(t, _not_, _positive_))
|
|
344
345
|
|
|
345
346
|
B1, B2, B3 = _B3(useZ, point1, point2, point3)
|
|
346
347
|
try:
|
|
@@ -352,7 +353,7 @@ def pierlot(point1, point2, point3, alpha12, alpha23, useZ=False, eps=EPS,
|
|
|
352
353
|
alpha12=alpha12, alpha23=alpha23, eps=eps, cause=x)
|
|
353
354
|
|
|
354
355
|
|
|
355
|
-
def _pierlot3(B1, B2, B3, a12, a23, useZ,
|
|
356
|
+
def _pierlot3(B1, B2, B3, a12, a23, useZ, _cot):
|
|
356
357
|
'''(INTERNAL) Shared L{pierlot} and L{pierlotx}.
|
|
357
358
|
'''
|
|
358
359
|
x1_, y1_, _ = B1.minus(B2).xyz3
|
|
@@ -364,14 +365,14 @@ def _pierlot3(B1, B2, B3, a12, a23, useZ, cot):
|
|
|
364
365
|
# = (1 - (c12 * c23) / (s12 * s23)) / (c12 * s23 + s12 * c23) / (s12 * s23)
|
|
365
366
|
# = (s12 * s23 - c12 * c23) / (c12 * s23 + s12 * c23)
|
|
366
367
|
# = c31 / s31
|
|
367
|
-
cot31 =
|
|
368
|
-
|
|
368
|
+
cot31 = _cot(fsum1f_(c12 * s23, s12 * c23), # s31
|
|
369
|
+
fsum1f_(s12 * s23, -c12 * c23)) # c31
|
|
369
370
|
|
|
370
371
|
K = _Fsumf_(x3_ * x1_, cot31 * (y3_ * x1_),
|
|
371
372
|
y3_ * y1_, -cot31 * (x3_ * y1_))
|
|
372
373
|
if K:
|
|
373
|
-
cot12 =
|
|
374
|
-
cot23 =
|
|
374
|
+
cot12 = _cot(s12, c12)
|
|
375
|
+
cot23 = _cot(s23, c23)
|
|
375
376
|
|
|
376
377
|
# x12 = x1_ + cot12 * y1_
|
|
377
378
|
# y12 = y1_ - cot12 * x1_
|
|
@@ -449,7 +450,7 @@ def pierlotx(point1, point2, point3, alpha1, alpha2, alpha3, useZ=False,
|
|
|
449
450
|
|
|
450
451
|
def _cot(s, c): # I{exact} cotangent
|
|
451
452
|
try:
|
|
452
|
-
return (c / s) if c else _copysign_0_0(s)
|
|
453
|
+
return (c / s) # if c else _copysign_0_0(s)
|
|
453
454
|
except ZeroDivisionError:
|
|
454
455
|
raise ValueError(_or(_coincident_, _colinear_))
|
|
455
456
|
|
|
@@ -465,7 +466,7 @@ def pierlotx(point1, point2, point3, alpha1, alpha2, alpha3, useZ=False,
|
|
|
465
466
|
alpha1=alpha1, alpha2=alpha2, alpha3=alpha3, cause=x)
|
|
466
467
|
|
|
467
468
|
|
|
468
|
-
def _pierlotx3(a_z_Bs, useZ,
|
|
469
|
+
def _pierlotx3(a_z_Bs, useZ, _cot, Cs):
|
|
469
470
|
'''(INTERNAL) Core of L{pierlotx}.
|
|
470
471
|
'''
|
|
471
472
|
(a12, z12, B1), \
|
|
@@ -481,14 +482,14 @@ def _pierlotx3(a_z_Bs, useZ, cot, Cs):
|
|
|
481
482
|
a23, B2, B3 = a12, B3, B2
|
|
482
483
|
else:
|
|
483
484
|
Cs(4)
|
|
484
|
-
return _pierlot3(B1, B2, B3, a12, a23, useZ,
|
|
485
|
+
return _pierlot3(B1, B2, B3, a12, a23, useZ, _cot)
|
|
485
486
|
|
|
486
487
|
x1_, y1_, _ = B1.minus(B3).xyz3
|
|
487
488
|
x2_, y2_, _ = B2.minus(B3).xyz3
|
|
488
489
|
|
|
489
490
|
K = _Fsumf_(y1_ * x2_, -x1_ * y2_)
|
|
490
491
|
if K:
|
|
491
|
-
cot23 =
|
|
492
|
+
cot23 = _cot(*sincos2d(a23))
|
|
492
493
|
|
|
493
494
|
# x23 = x2_ + cot23 * y2_
|
|
494
495
|
# y23 = y2_ - cot23 * x2_
|
|
@@ -1018,7 +1019,7 @@ def _zidw(x, y, useZ, *ABC):
|
|
|
1018
1019
|
|
|
1019
1020
|
# **) MIT License
|
|
1020
1021
|
#
|
|
1021
|
-
# Copyright (C) 2016-
|
|
1022
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1022
1023
|
#
|
|
1023
1024
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1024
1025
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/rhumb/__init__.py
CHANGED
|
@@ -25,7 +25,7 @@ else: # lazily import modules and exported attrs
|
|
|
25
25
|
|
|
26
26
|
# **) MIT License
|
|
27
27
|
#
|
|
28
|
-
# Copyright (C) 2018-
|
|
28
|
+
# Copyright (C) 2018-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
29
29
|
#
|
|
30
30
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
31
31
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/rhumb/aux_.py
CHANGED
|
@@ -16,7 +16,7 @@ the background information on U{Rhumb lines<https://GeographicLib.SourceForge.io
|
|
|
16
16
|
utility U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>} and U{Online rhumb
|
|
17
17
|
line calculations<https://GeographicLib.SourceForge.io/cgi-bin/RhumbSolve>}.
|
|
18
18
|
|
|
19
|
-
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-
|
|
19
|
+
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-2024) and licensed under the MIT/X11
|
|
20
20
|
License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
21
21
|
|
|
22
22
|
@note: C{S12} area calculations in classes L{RhumbAux} and L{RhumbLineAux} depend on class L{AuxDST} which
|
|
@@ -356,7 +356,7 @@ __all__ += _ALL_DOCS(Caps)
|
|
|
356
356
|
|
|
357
357
|
# **) MIT License
|
|
358
358
|
#
|
|
359
|
-
# Copyright (C) 2023-
|
|
359
|
+
# Copyright (C) 2023-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
360
360
|
#
|
|
361
361
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
362
362
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/rhumb/bases.py
CHANGED
|
@@ -17,7 +17,7 @@ the background information on U{Rhumb lines<https://GeographicLib.SourceForge.io
|
|
|
17
17
|
the utily U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>} and U{Online
|
|
18
18
|
rhumb line calculations<https://GeographicLib.SourceForge.io/cgi-bin/RhumbSolve>}.
|
|
19
19
|
|
|
20
|
-
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-
|
|
20
|
+
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-2024) and licensed under the MIT/X11
|
|
21
21
|
License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
22
22
|
'''
|
|
23
23
|
# make sure int/int division yields float quotient
|
|
@@ -1133,7 +1133,7 @@ if __name__ == '__main__':
|
|
|
1133
1133
|
|
|
1134
1134
|
# **) MIT License
|
|
1135
1135
|
#
|
|
1136
|
-
# Copyright (C) 2022-
|
|
1136
|
+
# Copyright (C) 2022-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1137
1137
|
#
|
|
1138
1138
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1139
1139
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/rhumb/ekx.py
CHANGED
|
@@ -16,7 +16,7 @@ the background information on U{Rhumb lines<https://GeographicLib.SourceForge.io
|
|
|
16
16
|
the utily U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>} and U{Online
|
|
17
17
|
rhumb line calculations<https://GeographicLib.SourceForge.io/cgi-bin/RhumbSolve>}.
|
|
18
18
|
|
|
19
|
-
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-
|
|
19
|
+
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-2024) and licensed under the MIT/X11
|
|
20
20
|
License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
21
21
|
'''
|
|
22
22
|
# make sure int/int division yields float quotient
|
|
@@ -40,10 +40,10 @@ from pygeodesy.rhumb.bases import RhumbBase, RhumbLineBase, \
|
|
|
40
40
|
Caps, _update_all_rls, _WGS84
|
|
41
41
|
from pygeodesy.utily import atan1, sincos2_
|
|
42
42
|
|
|
43
|
-
from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan
|
|
43
|
+
from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan # as _tan
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.rhumb_ekx
|
|
46
|
-
__version__ = '24.
|
|
46
|
+
__version__ = '24.11.26'
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class Rhumb(RhumbBase):
|
|
@@ -547,7 +547,7 @@ __all__ += _ALL_DOCS(Caps)
|
|
|
547
547
|
|
|
548
548
|
# **) MIT License
|
|
549
549
|
#
|
|
550
|
-
# Copyright (C) 2022-
|
|
550
|
+
# Copyright (C) 2022-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
551
551
|
#
|
|
552
552
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
553
553
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/rhumb/solve.py
CHANGED
|
@@ -499,7 +499,7 @@ if __name__ == '__main__':
|
|
|
499
499
|
|
|
500
500
|
# **) MIT License
|
|
501
501
|
#
|
|
502
|
-
# Copyright (C) 2022-
|
|
502
|
+
# Copyright (C) 2022-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
503
503
|
#
|
|
504
504
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
505
505
|
# copy of this software and associated documentation files (the "Software"),
|