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/latlonBase.py
CHANGED
|
@@ -20,7 +20,7 @@ from pygeodesy.dms import F_D, F_DMS, latDMS, lonDMS, parse3llh
|
|
|
20
20
|
from pygeodesy.errors import _AttributeError, IntersectionError, \
|
|
21
21
|
_incompatible, _IsnotError, _TypeError, \
|
|
22
22
|
_ValueError, _xattr, _xdatum, _xError, \
|
|
23
|
-
_xkwds, _xkwds_item2, _xkwds_not
|
|
23
|
+
_xkwds, _xkwds_get, _xkwds_item2, _xkwds_not
|
|
24
24
|
# from pygeodesy.fmath import favg # _MODS
|
|
25
25
|
# from pygeodesy.formy import antipode, compassAngle, cosineAndoyerLambert_, \
|
|
26
26
|
# cosineForsytheAndoyerLambert_, cosineLaw, \
|
|
@@ -35,17 +35,16 @@ from pygeodesy.interns import NN, _COMMASPACE_, _concentric_, _height_, \
|
|
|
35
35
|
# from pygeodesy.iters import PointsIter, points2 # _MODS
|
|
36
36
|
# from pygeodesy.karney import Caps # _MODS
|
|
37
37
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
38
|
-
|
|
39
|
-
from pygeodesy.named import _name2__, _NamedBase, Fmt
|
|
38
|
+
from pygeodesy.named import _name2__, _NamedBase, _NamedLocal, Fmt
|
|
40
39
|
from pygeodesy.namedTuples import Bounds2Tuple, LatLon2Tuple, PhiLam2Tuple, \
|
|
41
|
-
Trilaterate5Tuple
|
|
40
|
+
Trilaterate5Tuple, Vector3Tuple
|
|
42
41
|
# from pygeodesy.nvectorBase import _N_vector_ # _MODS
|
|
43
42
|
from pygeodesy.props import deprecated_method, Property, Property_RO, \
|
|
44
|
-
property_RO,
|
|
43
|
+
property_RO, _update_all
|
|
45
44
|
# from pygeodesy.streprs import Fmt, hstr # from .named, _MODS
|
|
46
45
|
from pygeodesy.units import _isDegrees, _isRadius, Distance_, Lat, Lon, \
|
|
47
46
|
Height, Radius, Radius_, Scalar, Scalar_
|
|
48
|
-
from pygeodesy.utily import _unrollon, _unrollon3, _Wrap
|
|
47
|
+
from pygeodesy.utily import sincos2d_, _unrollon, _unrollon3, _Wrap
|
|
49
48
|
# from pygeodesy.vector2d import _circin6, Circin6Tuple, _circum3, circum4_, \
|
|
50
49
|
# Circum3Tuple, _radii11ABC4 # _MODS
|
|
51
50
|
# from pygeodesy.vector3d import nearestOn6, Vector3d # _MODS
|
|
@@ -54,14 +53,13 @@ from contextlib import contextmanager
|
|
|
54
53
|
from math import asin, cos, degrees, fabs, radians
|
|
55
54
|
|
|
56
55
|
__all__ = _ALL_LAZY.latlonBase
|
|
57
|
-
__version__ = '24.
|
|
56
|
+
__version__ = '24.12.31'
|
|
58
57
|
|
|
59
58
|
_formy = _MODS.into(formy=__name__)
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
class LatLonBase(_NamedBase):
|
|
63
|
-
'''(INTERNAL) Base class for C{LatLon}
|
|
64
|
-
ellipsoidal earth models.
|
|
61
|
+
class LatLonBase(_NamedBase, _NamedLocal):
|
|
62
|
+
'''(INTERNAL) Base class for ellipsoidal and spherical C{LatLon}s.
|
|
65
63
|
'''
|
|
66
64
|
_clipid = INT0 # polygonal clip, see .booleans
|
|
67
65
|
_datum = None # L{Datum}, to be overriden
|
|
@@ -69,13 +67,13 @@ class LatLonBase(_NamedBase):
|
|
|
69
67
|
_lat = 0 # latitude (C{degrees})
|
|
70
68
|
_lon = 0 # longitude (C{degrees})
|
|
71
69
|
|
|
72
|
-
def __init__(self,
|
|
70
|
+
def __init__(self, lat_llh, lon=None, height=0, datum=None, **wrap_name):
|
|
73
71
|
'''New C{LatLon}.
|
|
74
72
|
|
|
75
|
-
@arg
|
|
73
|
+
@arg lat_llh: Latitude (C{degrees} or DMS C{str} with N or S suffix) or
|
|
76
74
|
a previous C{LatLon} instance provided C{B{lon}=None}.
|
|
77
|
-
@kwarg lon: Longitude (C{degrees} or DMS C{str} with E or W suffix)
|
|
78
|
-
|
|
75
|
+
@kwarg lon: Longitude (C{degrees} or DMS C{str} with E or W suffix),
|
|
76
|
+
required if B{C{lat_llh}} is C{degrees} or C{str}.
|
|
79
77
|
@kwarg height: Optional height above (or below) the earth surface
|
|
80
78
|
(C{meter}, conventionally).
|
|
81
79
|
@kwarg datum: Optional datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
|
|
@@ -89,20 +87,20 @@ class LatLonBase(_NamedBase):
|
|
|
89
87
|
@raise RangeError: A B{C{lon}} or C{lat} value outside the valid
|
|
90
88
|
range and L{rangerrors} set to C{True}.
|
|
91
89
|
|
|
92
|
-
@raise TypeError: If B{C{
|
|
90
|
+
@raise TypeError: If B{C{lat_llh}} is not a C{LatLon}.
|
|
93
91
|
|
|
94
|
-
@raise UnitError: Invalid
|
|
92
|
+
@raise UnitError: Invalid C{lat}, B{C{lon}} or B{C{height}}.
|
|
95
93
|
'''
|
|
96
94
|
w, n = self._wrap_name2(**wrap_name)
|
|
97
95
|
if n:
|
|
98
96
|
self.name = n
|
|
99
97
|
|
|
100
98
|
if lon is None:
|
|
101
|
-
lat, lon, height = _latlonheight3(
|
|
99
|
+
lat, lon, height = _latlonheight3(lat_llh, height, w)
|
|
102
100
|
elif w:
|
|
103
|
-
lat, lon = _Wrap.latlonDMS2(
|
|
101
|
+
lat, lon = _Wrap.latlonDMS2(lat_llh, lon)
|
|
104
102
|
else:
|
|
105
|
-
lat =
|
|
103
|
+
lat = lat_llh
|
|
106
104
|
|
|
107
105
|
self._lat = Lat(lat) # parseDMS2(lat, lon)
|
|
108
106
|
self._lon = Lon(lon) # PYCHOK LatLon2Tuple
|
|
@@ -206,7 +204,7 @@ class LatLonBase(_NamedBase):
|
|
|
206
204
|
argument C{B{wrap}=False}, if C{True}, wrap or I{normalize}
|
|
207
205
|
the B{C{points}} (C{bool}).
|
|
208
206
|
|
|
209
|
-
@return: L{Circin6Tuple}C{(radius, center, deltas, cA, cB, cC)}. The
|
|
207
|
+
@return: A L{Circin6Tuple}C{(radius, center, deltas, cA, cB, cC)}. The
|
|
210
208
|
C{center} and contact points C{cA}, C{cB} and C{cC}, each an
|
|
211
209
|
instance of this (sub-)class, are co-planar with this and the
|
|
212
210
|
two given points, see the B{Note} below.
|
|
@@ -296,7 +294,7 @@ class LatLonBase(_NamedBase):
|
|
|
296
294
|
C{B{wrap}=False}, if C{True}, wrap or I{normalize} the B{C{points}}
|
|
297
295
|
(C{bool}).
|
|
298
296
|
|
|
299
|
-
@return: L{Circum4Tuple}C{(radius, center, rank, residuals)} with C{center} an
|
|
297
|
+
@return: A L{Circum4Tuple}C{(radius, center, rank, residuals)} with C{center} an
|
|
300
298
|
instance of this (sub-)class.
|
|
301
299
|
|
|
302
300
|
@raise ImportError: Package C{numpy} not found, not installed or older than
|
|
@@ -364,73 +362,39 @@ class LatLonBase(_NamedBase):
|
|
|
364
362
|
p = self.others(other)
|
|
365
363
|
return _formy.compassAngle(self.lat, self.lon, p.lat, p.lon, **adjust_wrap)
|
|
366
364
|
|
|
365
|
+
@deprecated_method
|
|
367
366
|
def cosineAndoyerLambertTo(self, other, **wrap):
|
|
368
|
-
'''
|
|
369
|
-
|
|
370
|
-
of the U{Law of Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>} formula.
|
|
371
|
-
|
|
372
|
-
@arg other: The other point (C{LatLon}).
|
|
373
|
-
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
374
|
-
or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
375
|
-
|
|
376
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
377
|
-
ellipsoid).
|
|
378
|
-
|
|
379
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
380
|
-
|
|
381
|
-
@see: Function L{pygeodesy.cosineAndoyerLambert} and methods
|
|
382
|
-
L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo},
|
|
383
|
-
C{distanceTo*}, L{equirectangularTo}, L{euclideanTo},
|
|
384
|
-
L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo},
|
|
385
|
-
L{thomasTo} and L{vincentysTo}.
|
|
386
|
-
'''
|
|
387
|
-
return self._distanceTo_(_formy.cosineAndoyerLambert_, other, **wrap)
|
|
367
|
+
'''DEPRECATED on 2024.12.31, use method L{cosineLawTo} with C{B{corr}=1}.'''
|
|
368
|
+
return self.cosineLawTo(other, corr=1, **wrap)
|
|
388
369
|
|
|
370
|
+
@deprecated_method
|
|
389
371
|
def cosineForsytheAndoyerLambertTo(self, other, **wrap):
|
|
390
|
-
'''
|
|
391
|
-
|
|
392
|
-
<https://www2.UNB.Ca/gge/Pubs/TR77.pdf>} of the U{Law of Cosines
|
|
393
|
-
<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
|
|
394
|
-
formula.
|
|
395
|
-
|
|
396
|
-
@arg other: The other point (C{LatLon}).
|
|
397
|
-
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
398
|
-
or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
399
|
-
|
|
400
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
401
|
-
ellipsoid).
|
|
402
|
-
|
|
403
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
372
|
+
'''DEPRECATED on 2024.12.31, use method L{cosineLawTo} with C{B{corr}=2}.'''
|
|
373
|
+
return self.cosineLawTo(other, corr=2, **wrap)
|
|
404
374
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
'''
|
|
410
|
-
return self._distanceTo_(_formy.cosineForsytheAndoyerLambert_, other, **wrap)
|
|
411
|
-
|
|
412
|
-
def cosineLawTo(self, other, radius=None, **wrap):
|
|
413
|
-
'''Compute the distance between this and an other point using the
|
|
414
|
-
U{spherical Law of Cosines
|
|
415
|
-
<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
|
|
416
|
-
formula.
|
|
375
|
+
def cosineLawTo(self, other, **radius__corr_wrap):
|
|
376
|
+
'''Compute the distance between this and an other point using the U{Law of
|
|
377
|
+
Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
|
|
378
|
+
formula, optionally corrected.
|
|
417
379
|
|
|
418
380
|
@arg other: The other point (C{LatLon}).
|
|
419
|
-
@kwarg
|
|
420
|
-
of this point's
|
|
421
|
-
|
|
422
|
-
|
|
381
|
+
@kwarg radius__corr_wrap: Optional earth C{B{radius}=None} (C{meter}),
|
|
382
|
+
overriding the equatorial or mean radius of this point's
|
|
383
|
+
datum's ellipsoid and keyword arguments for function
|
|
384
|
+
L{pygeodesy.cosineLaw}.
|
|
423
385
|
|
|
424
386
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
425
387
|
|
|
426
388
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
427
389
|
|
|
428
|
-
@see: Function L{pygeodesy.cosineLaw} and methods
|
|
429
|
-
L{
|
|
430
|
-
L{
|
|
431
|
-
L{
|
|
390
|
+
@see: Function L{pygeodesy.cosineLaw} and methods C{distanceTo*},
|
|
391
|
+
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo} /
|
|
392
|
+
L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and
|
|
393
|
+
L{vincentysTo}.
|
|
432
394
|
'''
|
|
433
|
-
|
|
395
|
+
c = _xkwds_get(radius__corr_wrap, corr=0)
|
|
396
|
+
return self._distanceTo_(_formy.cosineLaw_, other, **radius__corr_wrap) if c else \
|
|
397
|
+
self._distanceTo( _formy.cosineLaw, other, **radius__corr_wrap)
|
|
434
398
|
|
|
435
399
|
@property_RO
|
|
436
400
|
def datum(self): # PYCHOK no cover
|
|
@@ -440,20 +404,17 @@ class LatLonBase(_NamedBase):
|
|
|
440
404
|
def destinationXyz(self, delta, LatLon=None, **LatLon_kwds):
|
|
441
405
|
'''Calculate the destination using a I{local} delta from this point.
|
|
442
406
|
|
|
443
|
-
@arg delta: Local delta to the destination (L{XyzLocal}, L{Enu},
|
|
444
|
-
|
|
445
|
-
@kwarg LatLon: Optional (geodetic) class to return the destination
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
arguments, ignored if C{B{LatLon} is None}.
|
|
407
|
+
@arg delta: Local delta to the destination (L{XyzLocal}, L{Aer}, L{Enu}, L{Ned}
|
|
408
|
+
or L{Local9Tuple}).
|
|
409
|
+
@kwarg LatLon: Optional (geodetic) class to return the destination or C{None}.
|
|
410
|
+
@kwarg LatLon_kwds: Optionally, additional B{C{LatLon}} keyword arguments,
|
|
411
|
+
ignored if C{B{LatLon} is None}.
|
|
449
412
|
|
|
450
|
-
@return:
|
|
451
|
-
|
|
452
|
-
lon, height)}
|
|
453
|
-
height, datum)} depending on whether a C{datum} keyword
|
|
454
|
-
is un-/specified.
|
|
413
|
+
@return: An B{C{LatLon}} instance or if C{B{LatLon} is None}, a
|
|
414
|
+
L{LatLon4Tuple}C{(lat, lon, height, datum)} or L{LatLon3Tuple}C{(lat,
|
|
415
|
+
lon, height)} if a C{datum} keyword is specified or not.
|
|
455
416
|
|
|
456
|
-
@raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}}.
|
|
417
|
+
@raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}} item.
|
|
457
418
|
'''
|
|
458
419
|
t = self._Ltp._local2ecef(delta, nine=True)
|
|
459
420
|
return t.toLatLon(LatLon=LatLon, **_xkwds(LatLon_kwds, name=self.name))
|
|
@@ -461,25 +422,18 @@ class LatLonBase(_NamedBase):
|
|
|
461
422
|
def _distanceTo(self, func, other, radius=None, **kwds):
|
|
462
423
|
'''(INTERNAL) Helper for distance methods C{<func>To}.
|
|
463
424
|
'''
|
|
464
|
-
p
|
|
465
|
-
if
|
|
466
|
-
|
|
467
|
-
return func(self.lat, self.lon, p.lat, p.lon, radius=r, **kwds)
|
|
425
|
+
p = self.others(other, up=2)
|
|
426
|
+
R = radius or (self._datum.ellipsoid.R1 if self._datum else R_M)
|
|
427
|
+
return func(self.lat, self.lon, p.lat, p.lon, radius=R, **kwds)
|
|
468
428
|
|
|
469
|
-
def _distanceTo_(self, func_, other, wrap=False, radius=None):
|
|
429
|
+
def _distanceTo_(self, func_, other, wrap=False, radius=None, **kwds):
|
|
470
430
|
'''(INTERNAL) Helper for (ellipsoidal) distance methods C{<func>To}.
|
|
471
431
|
'''
|
|
472
432
|
p = self.others(other, up=2)
|
|
473
|
-
D = self.datum
|
|
433
|
+
D = self.datum or _spherical_datum(radius or R_M, func_)
|
|
474
434
|
lam21, phi2, _ = _Wrap.philam3(self.lam, p.phi, p.lam, wrap)
|
|
475
|
-
r = func_(phi2, self.phi, lam21, datum=D)
|
|
476
|
-
return r * (D.ellipsoid.a
|
|
477
|
-
|
|
478
|
-
@property_ROnce
|
|
479
|
-
def Ecef(self):
|
|
480
|
-
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
481
|
-
'''
|
|
482
|
-
return _MODS.ecef.EcefKarney
|
|
435
|
+
r = func_(phi2, self.phi, lam21, datum=D, **kwds)
|
|
436
|
+
return r * (radius or D.ellipsoid.a)
|
|
483
437
|
|
|
484
438
|
@Property_RO
|
|
485
439
|
def _Ecef_forward(self):
|
|
@@ -528,10 +482,9 @@ class LatLonBase(_NamedBase):
|
|
|
528
482
|
|
|
529
483
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
530
484
|
|
|
531
|
-
@see: Function L{pygeodesy.equirectangular} and methods L{
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
L{haversineTo}, L{thomasTo} and L{vincentysTo}.
|
|
485
|
+
@see: Function L{pygeodesy.equirectangular} and methods L{cosineLawTo},
|
|
486
|
+
C{distanceTo*}, C{euclideanTo}, L{flatLocalTo} / L{hubenyTo},
|
|
487
|
+
L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}.
|
|
535
488
|
'''
|
|
536
489
|
return self._distanceTo(_formy.equirectangular, other, **radius_adjust_limit_wrap)
|
|
537
490
|
|
|
@@ -550,9 +503,8 @@ class LatLonBase(_NamedBase):
|
|
|
550
503
|
|
|
551
504
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
552
505
|
|
|
553
|
-
@see: Function L{pygeodesy.euclidean} and methods L{
|
|
554
|
-
L{
|
|
555
|
-
L{equirectangularTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo},
|
|
506
|
+
@see: Function L{pygeodesy.euclidean} and methods L{cosineLawTo}, C{distanceTo*},
|
|
507
|
+
L{equirectangularTo}, L{flatLocalTo} / L{hubenyTo}, L{flatPolarTo},
|
|
556
508
|
L{haversineTo}, L{thomasTo} and L{vincentysTo}.
|
|
557
509
|
'''
|
|
558
510
|
return self._distanceTo(_formy.euclidean, other, **radius_adjust_wrap)
|
|
@@ -575,11 +527,10 @@ class LatLonBase(_NamedBase):
|
|
|
575
527
|
|
|
576
528
|
@raise ValueError: Invalid B{C{radius}}.
|
|
577
529
|
|
|
578
|
-
@see: Function L{pygeodesy.flatLocal}/L{pygeodesy.hubeny}, methods
|
|
579
|
-
L{
|
|
580
|
-
L{
|
|
581
|
-
|
|
582
|
-
U{local, flat Earth approximation<https://www.edwilliams.org/avform.htm#flat>}.
|
|
530
|
+
@see: Function L{pygeodesy.flatLocal}/L{pygeodesy.hubeny}, methods L{cosineLawTo},
|
|
531
|
+
C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatPolarTo},
|
|
532
|
+
L{haversineTo}, L{thomasTo} and L{vincentysTo} and U{local, flat Earth
|
|
533
|
+
approximation<https://www.edwilliams.org/avform.htm#flat>}.
|
|
583
534
|
'''
|
|
584
535
|
r = radius if radius in (None, R_M, _1_0, 1) else Radius(radius)
|
|
585
536
|
return self._distanceTo_(_formy.flatLocal_, other, radius=r, **wrap) # PYCHOK kwargs
|
|
@@ -592,18 +543,16 @@ class LatLonBase(_NamedBase):
|
|
|
592
543
|
Geographical_distance#Polar_coordinate_flat-Earth_formula>} formula.
|
|
593
544
|
|
|
594
545
|
@arg other: The other point (C{LatLon}).
|
|
595
|
-
@kwarg radius_wrap: Optional
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
datum ellipsoid.
|
|
546
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for
|
|
547
|
+
function L{pygeodesy.flatPolar}, overriding the default
|
|
548
|
+
C{mean radius} of this point's datum ellipsoid.
|
|
599
549
|
|
|
600
550
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
601
551
|
|
|
602
552
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
603
553
|
|
|
604
|
-
@see: Function L{pygeodesy.flatPolar} and methods L{
|
|
605
|
-
L{
|
|
606
|
-
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo},
|
|
554
|
+
@see: Function L{pygeodesy.flatPolar} and methods L{cosineLawTo}, C{distanceTo*},
|
|
555
|
+
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo} / L{hubenyTo},
|
|
607
556
|
L{haversineTo}, L{thomasTo} and L{vincentysTo}.
|
|
608
557
|
'''
|
|
609
558
|
return self._distanceTo(_formy.flatPolar, other, **radius_wrap)
|
|
@@ -619,8 +568,8 @@ class LatLonBase(_NamedBase):
|
|
|
619
568
|
or C{scalar} radius in C{meter}), overriding this point's C{datum}
|
|
620
569
|
ellipsoid.
|
|
621
570
|
|
|
622
|
-
@return: The intersection (C{LatLon}) with C{.height} set to the distance
|
|
623
|
-
this C{pov}.
|
|
571
|
+
@return: The intersection (C{LatLon}) with attribute C{.height} set to the distance
|
|
572
|
+
to this C{pov}.
|
|
624
573
|
|
|
625
574
|
@raise IntersectionError: Null or bad C{pov} or B{C{los}}, this C{pov} is inside
|
|
626
575
|
the ellipsoid or B{C{los}} points outside or away from
|
|
@@ -633,23 +582,20 @@ class LatLonBase(_NamedBase):
|
|
|
633
582
|
return _formy._hartzell(self, los, earth, LatLon=self.classof)
|
|
634
583
|
|
|
635
584
|
def haversineTo(self, other, **radius_wrap):
|
|
636
|
-
'''Compute the distance between this and an other point using the
|
|
637
|
-
|
|
638
|
-
formula.
|
|
585
|
+
'''Compute the distance between this and an other point using the U{Haversine
|
|
586
|
+
<https://www.Movable-Type.co.UK/scripts/latlong.html>} formula.
|
|
639
587
|
|
|
640
588
|
@arg other: The other point (C{LatLon}).
|
|
641
|
-
@kwarg radius_wrap: Optional
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
datum ellipsoid.
|
|
589
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for function
|
|
590
|
+
L{pygeodesy.haversine}, overriding the default C{mean radius} of
|
|
591
|
+
this point's datum ellipsoid.
|
|
645
592
|
|
|
646
593
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
647
594
|
|
|
648
595
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
649
596
|
|
|
650
|
-
@see: Function L{pygeodesy.haversine} and methods L{
|
|
651
|
-
L{
|
|
652
|
-
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo},
|
|
597
|
+
@see: Function L{pygeodesy.haversine} and methods L{cosineLawTo}, C{distanceTo*},
|
|
598
|
+
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo} / L{hubenyTo}, \
|
|
653
599
|
L{flatPolarTo}, L{thomasTo} and L{vincentysTo}.
|
|
654
600
|
'''
|
|
655
601
|
return self._distanceTo(_formy.haversine, other, **radius_wrap)
|
|
@@ -661,8 +607,8 @@ class LatLonBase(_NamedBase):
|
|
|
661
607
|
@kwarg f: Optional fraction (C{float}).
|
|
662
608
|
@kwarg h: Overriding height (C{meter}).
|
|
663
609
|
|
|
664
|
-
@return: Average, fractional height (C{float}) or
|
|
665
|
-
|
|
610
|
+
@return: Average, fractional height (C{float}) or the
|
|
611
|
+
overriding height B{C{h}} (C{Height}).
|
|
666
612
|
'''
|
|
667
613
|
return Height(h) if h is not None else \
|
|
668
614
|
_MODS.fmath.favg(self.height, other.height, f=f)
|
|
@@ -702,22 +648,23 @@ class LatLonBase(_NamedBase):
|
|
|
702
648
|
@kwarg normal: If C{True}, the projection is the normal to this ellipsoid's
|
|
703
649
|
surface, otherwise the intersection of the I{radial} line to
|
|
704
650
|
this ellipsoid's center (C{bool}).
|
|
705
|
-
@kwarg LatLon: Optional class to return the projection, height and
|
|
706
|
-
|
|
707
|
-
@kwarg LatLon_kwds:
|
|
651
|
+
@kwarg LatLon: Optional class to return the projection, height and datum
|
|
652
|
+
(C{LatLon}) or C{None}.
|
|
653
|
+
@kwarg LatLon_kwds: Optionally, additional B{C{LatLon}} keyword arguments,
|
|
708
654
|
ignored if C{B{LatLon} is None}.
|
|
709
655
|
|
|
710
656
|
@note: Use keyword argument C{height=0} to override C{B{LatLon}.height}
|
|
711
657
|
to {0} or any other C{scalar}, conventionally in C{meter}.
|
|
712
658
|
|
|
713
|
-
@return:
|
|
714
|
-
|
|
715
|
-
|
|
659
|
+
@return: A B{C{LatLon}} instance or if C{B{LatLon} is None}, a L{Vector4Tuple}C{(x,
|
|
660
|
+
y, z, h)} with the I{projection} C{x}, C{y} and C{z} coordinates and
|
|
661
|
+
height C{h} in C{meter}, conventionally.
|
|
716
662
|
|
|
717
663
|
@raise TriaxialError: No convergence in triaxial root finding.
|
|
718
664
|
|
|
719
|
-
@raise TypeError: Invalid B{C{
|
|
720
|
-
|
|
665
|
+
@raise TypeError: Invalid B{C{LatLon}}, B{C{LatLon_kwds}} item, B{C{earth}}
|
|
666
|
+
or triaxial B{C{earth}} couldn't be converted to biaxial
|
|
667
|
+
B{C{LatLon}} datum.
|
|
721
668
|
|
|
722
669
|
@see: Methods L{Ellipsoid.height4} and L{Triaxial_.height4} for more information.
|
|
723
670
|
'''
|
|
@@ -747,7 +694,7 @@ class LatLonBase(_NamedBase):
|
|
|
747
694
|
|
|
748
695
|
def _intersecend2(self, p, q, wrap, height, g_or_r, P, Q, unused): # in .LatLonEllipsoidalBaseDI.intersecant2
|
|
749
696
|
'''(INTERNAL) Interpolate 2 heights along a geodesic or rhumb
|
|
750
|
-
line and return the 2
|
|
697
|
+
line and return the 2 intersecant points accordingly.
|
|
751
698
|
'''
|
|
752
699
|
if height is None:
|
|
753
700
|
hp = hq = _xattr(p, height=INT0)
|
|
@@ -777,14 +724,14 @@ class LatLonBase(_NamedBase):
|
|
|
777
724
|
return self.isantipodeTo(other, eps=eps)
|
|
778
725
|
|
|
779
726
|
def isantipodeTo(self, other, eps=EPS):
|
|
780
|
-
'''Check whether this and an other point are antipodal,
|
|
781
|
-
|
|
727
|
+
'''Check whether this and an other point are antipodal, on diametrically
|
|
728
|
+
opposite sides of the earth.
|
|
782
729
|
|
|
783
730
|
@arg other: The other point (C{LatLon}).
|
|
784
731
|
@kwarg eps: Tolerance for near-equality (C{degrees}).
|
|
785
732
|
|
|
786
|
-
@return: C{True} if points are antipodal within the given
|
|
787
|
-
|
|
733
|
+
@return: C{True} if points are antipodal within the given tolerance,
|
|
734
|
+
C{False} otherwise.
|
|
788
735
|
'''
|
|
789
736
|
p = self.others(other)
|
|
790
737
|
return _formy.isantipode(*(self.latlon + p.latlon), eps=eps)
|
|
@@ -801,12 +748,11 @@ class LatLonBase(_NamedBase):
|
|
|
801
748
|
@arg other: The other point (C{LatLon}).
|
|
802
749
|
@kwarg eps: Tolerance for equality (C{degrees}).
|
|
803
750
|
|
|
804
|
-
@return: C{True} if both points are identical,
|
|
805
|
-
|
|
751
|
+
@return: C{True} if both points are identical, I{ignoring} height,
|
|
752
|
+
C{False} otherwise.
|
|
806
753
|
|
|
807
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}
|
|
808
|
-
|
|
809
|
-
this C{class} or C{type}.
|
|
754
|
+
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch
|
|
755
|
+
of the B{C{other}} and this C{class} or C{type}.
|
|
810
756
|
|
|
811
757
|
@raise UnitError: Invalid B{C{eps}}.
|
|
812
758
|
|
|
@@ -820,12 +766,11 @@ class LatLonBase(_NamedBase):
|
|
|
820
766
|
@arg other: The other point (C{LatLon}).
|
|
821
767
|
@kwarg eps: Tolerance for equality (C{degrees}).
|
|
822
768
|
|
|
823
|
-
@return: C{True} if both points are identical I{including}
|
|
824
|
-
|
|
769
|
+
@return: C{True} if both points are identical I{including} height,
|
|
770
|
+
C{False} otherwise.
|
|
825
771
|
|
|
826
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}
|
|
827
|
-
|
|
828
|
-
C{class} or C{type}.
|
|
772
|
+
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch
|
|
773
|
+
of the B{C{other}} and this C{class} or C{type}.
|
|
829
774
|
|
|
830
775
|
@see: Method L{isequalTo}.
|
|
831
776
|
'''
|
|
@@ -879,17 +824,17 @@ class LatLonBase(_NamedBase):
|
|
|
879
824
|
|
|
880
825
|
@latlon.setter # PYCHOK setter!
|
|
881
826
|
def latlon(self, latlonh):
|
|
882
|
-
'''Set the lat- and longitude and optionally the height
|
|
883
|
-
|
|
884
|
-
|
|
827
|
+
'''Set the lat- and longitude and optionally the height (2- or 3-tuple
|
|
828
|
+
or comma- or space-separated C{str} of C{degrees90}, C{degrees180}
|
|
829
|
+
and C{meter}).
|
|
885
830
|
|
|
886
|
-
@raise TypeError: Height of B{C{latlonh}} not C{scalar} or
|
|
887
|
-
|
|
831
|
+
@raise TypeError: Height of B{C{latlonh}} not C{scalar} or B{C{latlonh}}
|
|
832
|
+
not C{list} or C{tuple}.
|
|
888
833
|
|
|
889
834
|
@raise ValueError: Invalid B{C{latlonh}} or M{len(latlonh)}.
|
|
890
835
|
|
|
891
|
-
@see: Function L{pygeodesy.parse3llh} to parse a B{C{latlonh}}
|
|
892
|
-
|
|
836
|
+
@see: Function L{pygeodesy.parse3llh} to parse a B{C{latlonh}} string
|
|
837
|
+
into a 3-tuple C{(lat, lon, h)}.
|
|
893
838
|
'''
|
|
894
839
|
if isstr(latlonh):
|
|
895
840
|
latlonh = parse3llh(latlonh, height=self.height)
|
|
@@ -912,11 +857,11 @@ class LatLonBase(_NamedBase):
|
|
|
912
857
|
|
|
913
858
|
@kwarg ndigits: Number of (decimal) digits (C{int}).
|
|
914
859
|
|
|
915
|
-
@return: A L{LatLon2Tuple}C{(lat, lon)}, both C{float}
|
|
916
|
-
|
|
860
|
+
@return: A L{LatLon2Tuple}C{(lat, lon)}, both C{float} and rounded
|
|
861
|
+
away from zero.
|
|
917
862
|
|
|
918
|
-
@note: The C{round}ed values are always C{float}, also
|
|
919
|
-
|
|
863
|
+
@note: The C{round}ed values are always C{float}, also if B{C{ndigits}}
|
|
864
|
+
is omitted.
|
|
920
865
|
'''
|
|
921
866
|
return LatLon2Tuple(round(self.lat, ndigits),
|
|
922
867
|
round(self.lon, ndigits), name=self.name)
|
|
@@ -961,37 +906,28 @@ class LatLonBase(_NamedBase):
|
|
|
961
906
|
_update_all(self)
|
|
962
907
|
self._lon = lon
|
|
963
908
|
|
|
964
|
-
@Property_RO
|
|
965
|
-
def _Ltp(self):
|
|
966
|
-
'''(INTERNAL) Cache for L{toLtp}.
|
|
967
|
-
'''
|
|
968
|
-
return _MODS.ltp.Ltp(self, ecef=self.Ecef(self.datum), name=self.name)
|
|
969
|
-
|
|
970
909
|
def nearestOn6(self, points, closed=False, height=None, wrap=False):
|
|
971
910
|
'''Locate the point on a path or polygon closest to this point.
|
|
972
911
|
|
|
973
|
-
Points are converted to and distances are computed in
|
|
974
|
-
|
|
912
|
+
Points are converted to and distances are computed in I{geocentric},
|
|
913
|
+
cartesian space.
|
|
975
914
|
|
|
976
915
|
@arg points: The path or polygon points (C{LatLon}[]).
|
|
977
916
|
@kwarg closed: Optionally, close the polygon (C{bool}).
|
|
978
|
-
@kwarg height: Optional height, overriding the height of
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
and the C{end} point each an instance of this
|
|
988
|
-
C{LatLon} and C{distance} in C{meter}, same
|
|
917
|
+
@kwarg height: Optional height, overriding the height of this and all
|
|
918
|
+
other points (C{meter}). If C{None}, take the height
|
|
919
|
+
of points into account for distances.
|
|
920
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}}
|
|
921
|
+
(C{bool}).
|
|
922
|
+
|
|
923
|
+
@return: A L{NearestOn6Tuple}C{(closest, distance, fi, j, start, end)}
|
|
924
|
+
with the C{closest}, the C{start} and the C{end} point each an
|
|
925
|
+
instance of this C{LatLon} and C{distance} in C{meter}, same
|
|
989
926
|
units as the cartesian axes.
|
|
990
927
|
|
|
991
928
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
992
929
|
|
|
993
|
-
@raise TypeError: Some B{C{points}} or some B{C{points}}'
|
|
994
|
-
C{Ecef} invalid.
|
|
930
|
+
@raise TypeError: Some B{C{points}} or some B{C{points}}' C{Ecef} invalid.
|
|
995
931
|
|
|
996
932
|
@raise ValueError: Some B{C{points}}' C{Ecef} is incompatible.
|
|
997
933
|
|
|
@@ -1025,11 +961,9 @@ class LatLonBase(_NamedBase):
|
|
|
1025
961
|
self._notImplemented(*args, **kwds)
|
|
1026
962
|
|
|
1027
963
|
def normal(self):
|
|
1028
|
-
'''Normalize this point I{in-place} to C{abs(lat) <= 90} and
|
|
1029
|
-
C{abs(lon) <= 180}.
|
|
964
|
+
'''Normalize this point I{in-place} to C{abs(lat) <= 90} and C{abs(lon) <= 180}.
|
|
1030
965
|
|
|
1031
|
-
@return: C{True} if this point was I{normal}, C{False} if it
|
|
1032
|
-
wasn't (but is now).
|
|
966
|
+
@return: C{True} if this point was I{normal}, C{False} if it wasn't (but is now).
|
|
1033
967
|
|
|
1034
968
|
@see: Property L{isnormal} and method L{toNormal}.
|
|
1035
969
|
'''
|
|
@@ -1049,7 +983,7 @@ class LatLonBase(_NamedBase):
|
|
|
1049
983
|
def _n_xyz3(self):
|
|
1050
984
|
'''(INTERNAL) Get the n-vector components as L{Vector3Tuple}.
|
|
1051
985
|
'''
|
|
1052
|
-
return
|
|
986
|
+
return philam2n_xyz(self.phi, self.lam, name=self.name)
|
|
1053
987
|
|
|
1054
988
|
@Property_RO
|
|
1055
989
|
def phi(self):
|
|
@@ -1068,11 +1002,10 @@ class LatLonBase(_NamedBase):
|
|
|
1068
1002
|
|
|
1069
1003
|
@kwarg ndigits: Number of (decimal) digits (C{int}).
|
|
1070
1004
|
|
|
1071
|
-
@return: A L{PhiLam2Tuple}C{(phi, lam)}, both C{float}
|
|
1072
|
-
|
|
1005
|
+
@return: A L{PhiLam2Tuple}C{(phi, lam)}, both C{float} and rounded
|
|
1006
|
+
away from zero.
|
|
1073
1007
|
|
|
1074
|
-
@note: The C{round}ed values are
|
|
1075
|
-
if B{C{ndigits}} is omitted.
|
|
1008
|
+
@note: The C{round}ed values are C{float}, always.
|
|
1076
1009
|
'''
|
|
1077
1010
|
return PhiLam2Tuple(round(self.phi, ndigits),
|
|
1078
1011
|
round(self.lam, ndigits), name=self.name)
|
|
@@ -1092,12 +1025,11 @@ class LatLonBase(_NamedBase):
|
|
|
1092
1025
|
'''Check a path or polygon represented by points.
|
|
1093
1026
|
|
|
1094
1027
|
@arg points: The path or polygon points (C{LatLon}[])
|
|
1095
|
-
@kwarg closed: Optionally, consider the polygon closed,
|
|
1096
|
-
|
|
1097
|
-
B{C{points}} (C{bool}).
|
|
1028
|
+
@kwarg closed: Optionally, consider the polygon closed, ignoring any
|
|
1029
|
+
duplicate or closing final B{C{points}} (C{bool}).
|
|
1098
1030
|
|
|
1099
|
-
@return: A L{Points2Tuple}C{(number, points)}, an C{int}
|
|
1100
|
-
|
|
1031
|
+
@return: A L{Points2Tuple}C{(number, points)}, an C{int} and a C{list}
|
|
1032
|
+
or C{tuple}.
|
|
1101
1033
|
|
|
1102
1034
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
1103
1035
|
|
|
@@ -1111,8 +1043,8 @@ class LatLonBase(_NamedBase):
|
|
|
1111
1043
|
@arg points: The path or polygon points (C{LatLon}[])
|
|
1112
1044
|
@kwarg loop: Number of loop-back points (non-negative C{int}).
|
|
1113
1045
|
@kwarg dedup: If C{True}, skip duplicate points (C{bool}).
|
|
1114
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} the
|
|
1115
|
-
|
|
1046
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} the enum-/iterated
|
|
1047
|
+
B{C{points}} (C{bool}).
|
|
1116
1048
|
|
|
1117
1049
|
@return: A new C{PointsIter} iterator.
|
|
1118
1050
|
|
|
@@ -1169,51 +1101,43 @@ class LatLonBase(_NamedBase):
|
|
|
1169
1101
|
return {} # 3-item cache
|
|
1170
1102
|
|
|
1171
1103
|
def rhumbAzimuthTo(self, other, exact=False, radius=None, wrap=False, b360=False):
|
|
1172
|
-
'''Return the azimuth (bearing) of a rhumb line (loxodrome) between this
|
|
1173
|
-
|
|
1104
|
+
'''Return the azimuth (bearing) of a rhumb line (loxodrome) between this and
|
|
1105
|
+
an other (ellipsoidal) point.
|
|
1174
1106
|
|
|
1175
1107
|
@arg other: The other point (C{LatLon}).
|
|
1176
|
-
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
|
|
1177
|
-
|
|
1178
|
-
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum},
|
|
1179
|
-
L{
|
|
1180
|
-
|
|
1181
|
-
@kwarg
|
|
1182
|
-
point (C{bool}).
|
|
1183
|
-
@kwarg b360: If C{True}, return the azimuth as bearing in compass
|
|
1184
|
-
degrees (C{bool}).
|
|
1108
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method
|
|
1109
|
+
L{Ellipsoid.rhumb_}.
|
|
1110
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1111
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1112
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1113
|
+
@kwarg b360: If C{True}, return the azimuth as bearing in compass degrees (C{bool}).
|
|
1185
1114
|
|
|
1186
1115
|
@return: Rhumb azimuth (C{degrees180} or compass C{degrees360}).
|
|
1187
1116
|
|
|
1188
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1189
|
-
is invalid.
|
|
1117
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1190
1118
|
'''
|
|
1191
1119
|
r, _, Cs = self._rhumb3(exact, radius)
|
|
1192
1120
|
z = r._Inverse(self, other, wrap, outmask=Cs.AZIMUTH).azi12
|
|
1193
1121
|
return _umod_360(z + _360_0) if b360 else z
|
|
1194
1122
|
|
|
1195
|
-
def rhumbDestination(self, distance, azimuth, radius=None, height=None,
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
this point along a rhumb line (loxodrome) of the given azimuth.
|
|
1123
|
+
def rhumbDestination(self, distance, azimuth, radius=None, height=None, exact=False, **name):
|
|
1124
|
+
'''Return the destination point having travelled the given distance from this point along
|
|
1125
|
+
a rhumb line (loxodrome) of the given azimuth.
|
|
1199
1126
|
|
|
1200
|
-
@arg distance: Distance travelled (C{meter}, same units as this point's
|
|
1201
|
-
|
|
1127
|
+
@arg distance: Distance travelled (C{meter}, same units as this point's datum (ellipsoid)
|
|
1128
|
+
axes or B{C{radius}}, may be negative.
|
|
1202
1129
|
@arg azimuth: Azimuth (bearing) of the rhumb line (compass C{degrees}).
|
|
1203
|
-
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum},
|
|
1204
|
-
L{
|
|
1205
|
-
this point's datum.
|
|
1130
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1131
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1206
1132
|
@kwarg height: Optional height, overriding the default height (C{meter}).
|
|
1207
|
-
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
|
|
1208
|
-
method L{Ellipsoid.rhumb_}.
|
|
1133
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1209
1134
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1210
1135
|
|
|
1211
1136
|
@return: The destination point (ellipsoidal C{LatLon}).
|
|
1212
1137
|
|
|
1213
1138
|
@raise TypeError: Invalid B{C{radius}}.
|
|
1214
1139
|
|
|
1215
|
-
@raise ValueError: Invalid B{C{distance}}, B{C{azimuth}}, B{C{radius}}
|
|
1216
|
-
or B{C{height}}.
|
|
1140
|
+
@raise ValueError: Invalid B{C{distance}}, B{C{azimuth}}, B{C{radius}} or B{C{height}}.
|
|
1217
1141
|
'''
|
|
1218
1142
|
r, D, _ = self._rhumb3(exact, radius)
|
|
1219
1143
|
d = r._Direct(self, azimuth, distance)
|
|
@@ -1221,23 +1145,17 @@ class LatLonBase(_NamedBase):
|
|
|
1221
1145
|
return self.classof(d.lat2, d.lon2, datum=D, height=h, **name)
|
|
1222
1146
|
|
|
1223
1147
|
def rhumbDistanceTo(self, other, exact=False, radius=None, wrap=False):
|
|
1224
|
-
'''Return the distance from this to an other point along a rhumb line
|
|
1225
|
-
(loxodrome).
|
|
1148
|
+
'''Return the distance from this to an other point along a rhumb line (loxodrome).
|
|
1226
1149
|
|
|
1227
1150
|
@arg other: The other point (C{LatLon}).
|
|
1228
|
-
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
this point's datum.
|
|
1233
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}}
|
|
1234
|
-
point (C{bool}).
|
|
1151
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1152
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1153
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1154
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1235
1155
|
|
|
1236
|
-
@return: Distance (C{meter}, the same units as this point's datum
|
|
1237
|
-
(ellipsoid) axes or B{C{radius}}.
|
|
1156
|
+
@return: Distance (C{meter}, the same units as this point's datum (ellipsoid) axes or B{C{radius}}.
|
|
1238
1157
|
|
|
1239
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1240
|
-
is invalid.
|
|
1158
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1241
1159
|
|
|
1242
1160
|
@raise ValueError: Invalid B{C{radius}}.
|
|
1243
1161
|
'''
|
|
@@ -1246,30 +1164,28 @@ class LatLonBase(_NamedBase):
|
|
|
1246
1164
|
|
|
1247
1165
|
def rhumbIntersecant2(self, circle, point, other, height=None,
|
|
1248
1166
|
**exact_radius_wrap_eps_tol):
|
|
1249
|
-
'''Compute the intersections of a circle and a rhumb line given as two
|
|
1250
|
-
|
|
1167
|
+
'''Compute the intersections of a circle and a rhumb line given as two points or as a
|
|
1168
|
+
point and azimuth.
|
|
1251
1169
|
|
|
1252
|
-
@arg circle: Radius of the circle centered at this location (C{meter}),
|
|
1253
|
-
|
|
1170
|
+
@arg circle: Radius of the circle centered at this location (C{meter}), or a point
|
|
1171
|
+
on the circle (same C{LatLon} class).
|
|
1254
1172
|
@arg point: The start point of the rhumb line (same C{LatLon} class).
|
|
1255
|
-
@arg other: An other point I{on} (same C{LatLon} class) or the azimuth
|
|
1256
|
-
|
|
1257
|
-
@kwarg height: Optional height for the intersection points (C{meter},
|
|
1258
|
-
|
|
1259
|
-
@kwarg exact_radius_wrap_eps_tol: Optional keyword arguments, see
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
instance if the rhumb line is tangent to the circle.
|
|
1173
|
+
@arg other: An other point I{on} (same C{LatLon} class) or the azimuth I{of} (compass
|
|
1174
|
+
C{degrees}) the rhumb line.
|
|
1175
|
+
@kwarg height: Optional height for the intersection points (C{meter}, conventionally)
|
|
1176
|
+
or C{None} for interpolated heights.
|
|
1177
|
+
@kwarg exact_radius_wrap_eps_tol: Optional keyword arguments, see methods L{rhumbLine}
|
|
1178
|
+
and L{RhumbLineAux.Intersecant2} or L{RhumbLine.Intersecant2}.
|
|
1179
|
+
|
|
1180
|
+
@return: 2-Tuple of the intersection points (representing a chord), each an instance of
|
|
1181
|
+
this class. Both points are the same instance if the rhumb line is tangent to
|
|
1182
|
+
the circle.
|
|
1266
1183
|
|
|
1267
1184
|
@raise IntersectionError: The circle and rhumb line do not intersect.
|
|
1268
1185
|
|
|
1269
1186
|
@raise TypeError: Invalid B{C{point}}, B{C{circle}} or B{C{other}}.
|
|
1270
1187
|
|
|
1271
|
-
@raise ValueError: Invalid B{C{circle}}, B{C{other}}, B{C{height}}
|
|
1272
|
-
or B{C{exact_radius_wrap}}.
|
|
1188
|
+
@raise ValueError: Invalid B{C{circle}}, B{C{other}}, B{C{height}} or B{C{exact_radius_wrap}}.
|
|
1273
1189
|
|
|
1274
1190
|
@see: Methods L{RhumbLineAux.Intersecant2} and L{RhumbLine.Intersecant2}.
|
|
1275
1191
|
'''
|
|
@@ -1292,25 +1208,19 @@ class LatLonBase(_NamedBase):
|
|
|
1292
1208
|
**exact_radius_wrap_eps_tol)
|
|
1293
1209
|
|
|
1294
1210
|
def rhumbLine(self, other, exact=False, radius=None, wrap=False, **name_caps):
|
|
1295
|
-
'''Get a rhumb line through this point at a given azimuth or through
|
|
1296
|
-
this and an other point.
|
|
1211
|
+
'''Get a rhumb line through this point at a given azimuth or through this and an other point.
|
|
1297
1212
|
|
|
1298
|
-
@arg other: The azimuth I{of} (compass C{degrees}) or an other point
|
|
1299
|
-
|
|
1300
|
-
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}}
|
|
1306
|
-
point (C{bool}).
|
|
1307
|
-
@kwarg name_caps: Optional C{B{name}=str} and C{caps}, see L{RhumbLine}
|
|
1308
|
-
or L{RhumbLineAux} C{B{caps}}.
|
|
1213
|
+
@arg other: The azimuth I{of} (compass C{degrees}) or an other point I{on} (same
|
|
1214
|
+
C{LatLon} class) the rhumb line.
|
|
1215
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1216
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1217
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's C{datum}.
|
|
1218
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1219
|
+
@kwarg name_caps: Optional C{B{name}=str} and C{caps}, see L{RhumbLine} or L{RhumbLineAux} C{B{caps}}.
|
|
1309
1220
|
|
|
1310
|
-
@return: A C{RhumbLine} instance.
|
|
1221
|
+
@return: A C{RhumbLine} instance (C{RhumbLine} or C{RhumbLineAux}).
|
|
1311
1222
|
|
|
1312
|
-
@raise TypeError: Invalid B{C{radius}} or B{C{other}} not C{scalar} nor
|
|
1313
|
-
same C{LatLon} class.
|
|
1223
|
+
@raise TypeError: Invalid B{C{radius}} or B{C{other}} not C{scalar} nor same C{LatLon} class.
|
|
1314
1224
|
|
|
1315
1225
|
@see: Modules L{rhumb.aux_} and L{rhumb.ekx}.
|
|
1316
1226
|
'''
|
|
@@ -1320,30 +1230,23 @@ class LatLonBase(_NamedBase):
|
|
|
1320
1230
|
r._InverseLine(self, self.others(other), wrap, **kwds)
|
|
1321
1231
|
return rl
|
|
1322
1232
|
|
|
1323
|
-
def rhumbMidpointTo(self, other, exact=False, radius=None,
|
|
1324
|
-
|
|
1325
|
-
'''Return the (loxodromic) midpoint on the rhumb line between this and
|
|
1326
|
-
an other point.
|
|
1233
|
+
def rhumbMidpointTo(self, other, exact=False, radius=None, height=None, fraction=_0_5, **wrap_name):
|
|
1234
|
+
'''Return the (loxodromic) midpoint on the rhumb line between this and an other point.
|
|
1327
1235
|
|
|
1328
1236
|
@arg other: The other point (same C{LatLon} class).
|
|
1329
|
-
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding
|
|
1333
|
-
this point's datum.
|
|
1237
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1238
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1239
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1334
1240
|
@kwarg height: Optional height, overriding the mean height (C{meter}).
|
|
1335
|
-
@kwarg fraction: Midpoint location from this point (C{scalar}), 0 for this,
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
@kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and
|
|
1339
|
-
|
|
1340
|
-
and unroll the B{C{other}} point (C{bool}).
|
|
1241
|
+
@kwarg fraction: Midpoint location from this point (C{scalar}), 0 for this, 1 for the B{C{other}},
|
|
1242
|
+
0.5 for halfway between this and the B{C{other}} point, may be negative or
|
|
1243
|
+
greater than 1.
|
|
1244
|
+
@kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and C{B{wrap}=False}, if C{True}, wrap or
|
|
1245
|
+
I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1341
1246
|
|
|
1342
|
-
@return: The midpoint at the given B{C{fraction}} along the rhumb line
|
|
1343
|
-
(same C{LatLon} class).
|
|
1247
|
+
@return: The midpoint at the given B{C{fraction}} along the rhumb line (same C{LatLon} class).
|
|
1344
1248
|
|
|
1345
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1346
|
-
is invalid.
|
|
1249
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1347
1250
|
|
|
1348
1251
|
@raise ValueError: Invalid B{C{height}} or B{C{fraction}}.
|
|
1349
1252
|
'''
|
|
@@ -1369,14 +1272,12 @@ class LatLonBase(_NamedBase):
|
|
|
1369
1272
|
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
1370
1273
|
or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1371
1274
|
|
|
1372
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
1373
|
-
ellipsoid).
|
|
1275
|
+
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
|
|
1374
1276
|
|
|
1375
1277
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
1376
1278
|
|
|
1377
|
-
@see: Function L{pygeodesy.thomas} and methods L{
|
|
1378
|
-
L{
|
|
1379
|
-
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo},
|
|
1279
|
+
@see: Function L{pygeodesy.thomas} and methods L{cosineLawTo}, C{distanceTo*},
|
|
1280
|
+
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo} / L{hubenyTo},
|
|
1380
1281
|
L{flatPolarTo}, L{haversineTo} and L{vincentysTo}.
|
|
1381
1282
|
'''
|
|
1382
1283
|
return self._distanceTo_(_formy.thomas_, other, **wrap)
|
|
@@ -1387,21 +1288,21 @@ class LatLonBase(_NamedBase):
|
|
|
1387
1288
|
return self.philam
|
|
1388
1289
|
|
|
1389
1290
|
def toCartesian(self, height=None, Cartesian=None, **Cartesian_kwds):
|
|
1390
|
-
'''Convert this point to cartesian, I{geocentric} coordinates,
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
@kwarg height: Optional height, overriding this point's height
|
|
1394
|
-
|
|
1395
|
-
@kwarg Cartesian: Optional class to return the geocentric
|
|
1396
|
-
|
|
1397
|
-
@kwarg Cartesian_kwds:
|
|
1291
|
+
'''Convert this point to cartesian, I{geocentric} coordinates, also known as
|
|
1292
|
+
I{Earth-Centered, Earth-Fixed} (ECEF).
|
|
1293
|
+
|
|
1294
|
+
@kwarg height: Optional height, overriding this point's height (C{meter},
|
|
1295
|
+
conventionally).
|
|
1296
|
+
@kwarg Cartesian: Optional class to return the geocentric coordinates
|
|
1297
|
+
(C{Cartesian}) or C{None}.
|
|
1298
|
+
@kwarg Cartesian_kwds: Optionally, additional B{C{Cartesian}} keyword
|
|
1398
1299
|
arguments, ignored if C{B{Cartesian} is None}.
|
|
1399
1300
|
|
|
1400
|
-
@return: A B{C{Cartesian}} or if B{C{Cartesian} is None}, an
|
|
1401
|
-
L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
|
|
1402
|
-
|
|
1301
|
+
@return: A B{C{Cartesian}} instance or if B{C{Cartesian} is None}, an
|
|
1302
|
+
L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
|
|
1303
|
+
C{C=0} and C{M} if available.
|
|
1403
1304
|
|
|
1404
|
-
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}}.
|
|
1305
|
+
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}} item.
|
|
1405
1306
|
|
|
1406
1307
|
@see: Methods C{toNvector}, C{toVector} and C{toVector3d}.
|
|
1407
1308
|
'''
|
|
@@ -1434,12 +1335,12 @@ class LatLonBase(_NamedBase):
|
|
|
1434
1335
|
'''Convert this point to I{geocentric} coordinates, also known as
|
|
1435
1336
|
I{Earth-Centered, Earth-Fixed} (U{ECEF<https://WikiPedia.org/wiki/ECEF>}).
|
|
1436
1337
|
|
|
1437
|
-
@kwarg height: Optional height, overriding this point's height
|
|
1438
|
-
|
|
1338
|
+
@kwarg height: Optional height, overriding this point's height (C{meter},
|
|
1339
|
+
conventionally).
|
|
1439
1340
|
@kwarg M: Optionally, include the rotation L{EcefMatrix} (C{bool}).
|
|
1440
1341
|
|
|
1441
|
-
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
|
|
1442
|
-
|
|
1342
|
+
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
|
|
1343
|
+
C{C=0} and C{M} if available.
|
|
1443
1344
|
|
|
1444
1345
|
@raise EcefError: A C{.datum} or an ECEF issue.
|
|
1445
1346
|
'''
|
|
@@ -1452,45 +1353,15 @@ class LatLonBase(_NamedBase):
|
|
|
1452
1353
|
return self.latlonheight if height in (None, self.height) else \
|
|
1453
1354
|
self.latlon.to3Tuple(height)
|
|
1454
1355
|
|
|
1455
|
-
def toLocal(self, Xyz=None, ltp=None, **Xyz_kwds):
|
|
1456
|
-
'''Convert this I{geodetic} point to I{local} C{X}, C{Y} and C{Z}.
|
|
1457
|
-
|
|
1458
|
-
@kwarg Xyz: Optional class to return C{X}, C{Y} and C{Z} (L{XyzLocal},
|
|
1459
|
-
L{Enu}, L{Ned}) or C{None}.
|
|
1460
|
-
@kwarg ltp: The I{local tangent plane} (LTP) to use, overriding this
|
|
1461
|
-
point's LTP (L{Ltp}).
|
|
1462
|
-
@kwarg Xyz_kwds: Optional, additional B{C{Xyz}} keyword arguments,
|
|
1463
|
-
ignored if C{B{Xyz} is None}.
|
|
1464
|
-
|
|
1465
|
-
@return: An B{C{Xyz}} instance or a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
1466
|
-
height, ltp, ecef, M)} if C{B{Xyz} is None} (with C{M=None}).
|
|
1467
|
-
|
|
1468
|
-
@raise TypeError: Invalid B{C{ltp}}.
|
|
1469
|
-
'''
|
|
1470
|
-
return _MODS.ltp._toLocal(self, ltp, Xyz, Xyz_kwds) # self._ecef9
|
|
1471
|
-
|
|
1472
|
-
def toLtp(self, Ecef=None, **name):
|
|
1473
|
-
'''Return the I{local tangent plane} (LTP) for this point.
|
|
1474
|
-
|
|
1475
|
-
@kwarg Ecef: Optional ECEF I{class} (L{EcefKarney}, ...
|
|
1476
|
-
L{EcefYou}), overriding this point's C{Ecef}.
|
|
1477
|
-
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1478
|
-
'''
|
|
1479
|
-
return _MODS.ltp._toLtp(self, Ecef, self, name) # self._Ltp
|
|
1480
|
-
|
|
1481
1356
|
def toNormal(self, deep=False, **name):
|
|
1482
|
-
'''Get this point I{normalized} to C{abs(lat) <= 90}
|
|
1483
|
-
and C{abs(lon) <= 180}.
|
|
1357
|
+
'''Get this point I{normalized} to C{abs(lat) <= 90} and C{abs(lon) <= 180}.
|
|
1484
1358
|
|
|
1485
|
-
@kwarg deep: If C{True}, make a deep, otherwise a shallow
|
|
1486
|
-
copy (C{bool}).
|
|
1359
|
+
@kwarg deep: If C{True}, make a deep, otherwise a shallow copy (C{bool}).
|
|
1487
1360
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1488
1361
|
|
|
1489
|
-
@return: A copy of this point, I{normalized} (C{LatLon}),
|
|
1490
|
-
optionally renamed.
|
|
1362
|
+
@return: A copy of this point, I{normalized} (C{LatLon}), optionally renamed.
|
|
1491
1363
|
|
|
1492
|
-
@see: Property L{isnormal}, method L{normal} and function
|
|
1493
|
-
L{pygeodesy.normal}.
|
|
1364
|
+
@see: Property L{isnormal}, method L{normal} and function L{pygeodesy.normal}.
|
|
1494
1365
|
'''
|
|
1495
1366
|
ll = self.copy(deep=deep)
|
|
1496
1367
|
_ = ll.normal()
|
|
@@ -1499,18 +1370,18 @@ class LatLonBase(_NamedBase):
|
|
|
1499
1370
|
return ll
|
|
1500
1371
|
|
|
1501
1372
|
def toNvector(self, h=None, Nvector=None, **name_Nvector_kwds):
|
|
1502
|
-
'''Convert this point to C{n-vector} (normal to the earth's surface)
|
|
1503
|
-
|
|
1373
|
+
'''Convert this point to C{n-vector} (normal to the earth's surface) components,
|
|
1374
|
+
I{including height}.
|
|
1504
1375
|
|
|
1505
1376
|
@kwarg h: Optional height, overriding this point's height (C{meter}).
|
|
1506
|
-
@kwarg Nvector: Optional class to return the C{n-vector} components
|
|
1507
|
-
|
|
1377
|
+
@kwarg Nvector: Optional class to return the C{n-vector} components (C{Nvector})
|
|
1378
|
+
or C{None}.
|
|
1508
1379
|
@kwarg name_Nvector_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
|
|
1509
1380
|
additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector}
|
|
1510
1381
|
is None}.
|
|
1511
1382
|
|
|
1512
|
-
@return: An
|
|
1513
|
-
|
|
1383
|
+
@return: An B{C{Nvector}} instance or a L{Vector4Tuple}C{(x, y, z, h)} if
|
|
1384
|
+
C{B{Nvector} is None}.
|
|
1514
1385
|
|
|
1515
1386
|
@raise TypeError: Invalid B{C{h}}, B{C{Nvector}} or B{C{name_Nvector_kwds}}.
|
|
1516
1387
|
|
|
@@ -1528,26 +1399,25 @@ class LatLonBase(_NamedBase):
|
|
|
1528
1399
|
return r
|
|
1529
1400
|
|
|
1530
1401
|
def toStr(self, form=F_DMS, joined=_COMMASPACE_, m=_m_, **prec_sep_s_D_M_S): # PYCHOK expected
|
|
1531
|
-
'''Convert this point to a "lat, lon[, +/-height]" string, formatted
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see
|
|
1535
|
-
|
|
1536
|
-
@kwarg joined: Separator to join the lat-, longitude and height
|
|
1537
|
-
|
|
1538
|
-
@kwarg m: Optional unit of the height (C{str}), use C{None} to
|
|
1539
|
-
|
|
1540
|
-
@kwarg prec_sep_s_D_M_S: Optional C{B{prec}ision}, C{B{sep}arator},
|
|
1541
|
-
B{C{
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
@return: This point in the specified C{B{form}at}, etc. (C{str} or
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
C{B{sep}arator}, B{C{s_D}}, B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}}.
|
|
1402
|
+
'''Convert this point to a "lat, lon[, +/-height]" string, formatted in the
|
|
1403
|
+
given C{B{form}at}.
|
|
1404
|
+
|
|
1405
|
+
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see functions
|
|
1406
|
+
L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
|
|
1407
|
+
@kwarg joined: Separator to join the lat-, longitude and height strings (C{str}
|
|
1408
|
+
or C{None} or C{NN} for non-joined).
|
|
1409
|
+
@kwarg m: Optional unit of the height (C{str}), use C{None} to exclude height
|
|
1410
|
+
from the returned string.
|
|
1411
|
+
@kwarg prec_sep_s_D_M_S: Optional C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}},
|
|
1412
|
+
B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}} keyword arguments, see function
|
|
1413
|
+
L{pygeodesy.toDMS} for details.
|
|
1414
|
+
|
|
1415
|
+
@return: This point in the specified C{B{form}at}, etc. (C{str} or a 2- or 3-tuple
|
|
1416
|
+
C{(lat_str, lon_str[, height_str])} if B{C{joined}} is C{NN} or C{None}).
|
|
1417
|
+
|
|
1418
|
+
@see: Function L{pygeodesy.latDMS} or L{pygeodesy.lonDMS} for more details about
|
|
1419
|
+
keyword arguments C{B{form}at}, C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}},
|
|
1420
|
+
B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}}.
|
|
1551
1421
|
'''
|
|
1552
1422
|
t = (latDMS(self.lat, form=form, **prec_sep_s_D_M_S),
|
|
1553
1423
|
lonDMS(self.lon, form=form, **prec_sep_s_D_M_S))
|
|
@@ -1556,16 +1426,16 @@ class LatLonBase(_NamedBase):
|
|
|
1556
1426
|
return joined.join(t) if joined else t
|
|
1557
1427
|
|
|
1558
1428
|
def toVector(self, Vector=None, **Vector_kwds):
|
|
1559
|
-
'''Convert this point to a C{Vector} with the I{geocentric} C{(x,
|
|
1560
|
-
|
|
1429
|
+
'''Convert this point to a C{Vector} with the I{geocentric} C{(x, y, z)} (ECEF)
|
|
1430
|
+
coordinates, I{ignoring height}.
|
|
1561
1431
|
|
|
1562
|
-
@kwarg Vector: Optional class to return the I{geocentric}
|
|
1563
|
-
|
|
1564
|
-
@kwarg Vector_kwds:
|
|
1565
|
-
|
|
1432
|
+
@kwarg Vector: Optional class to return the I{geocentric} components (L{Vector3d})
|
|
1433
|
+
or C{None}.
|
|
1434
|
+
@kwarg Vector_kwds: Optionally, additional B{C{Vector}} keyword arguments,
|
|
1435
|
+
ignored if C{B{Vector} is None}.
|
|
1566
1436
|
|
|
1567
|
-
@return: A
|
|
1568
|
-
|
|
1437
|
+
@return: A B{C{Vector}} instance or a L{Vector3Tuple}C{(x, y, z)} if C{B{Vector}
|
|
1438
|
+
is None}.
|
|
1569
1439
|
|
|
1570
1440
|
@raise TypeError: Invalid B{C{Vector}} or B{C{Vector_kwds}}.
|
|
1571
1441
|
|
|
@@ -1574,8 +1444,8 @@ class LatLonBase(_NamedBase):
|
|
|
1574
1444
|
return self._ecef9.toVector(Vector=Vector, **self._name1__(Vector_kwds))
|
|
1575
1445
|
|
|
1576
1446
|
def toVector3d(self, norm=True, **Vector3d_kwds):
|
|
1577
|
-
'''Convert this point to a L{Vector3d} with the I{geocentric} C{(x, y,
|
|
1578
|
-
|
|
1447
|
+
'''Convert this point to a L{Vector3d} with the I{geocentric} C{(x, y, z)}
|
|
1448
|
+
(ECEF) coordinates, I{ignoring height}.
|
|
1579
1449
|
|
|
1580
1450
|
@kwarg norm: If C{False}, don't normalize the coordinates (C{bool}).
|
|
1581
1451
|
@kwarg Vector3d_kwds: Optional L{Vector3d} keyword arguments.
|
|
@@ -1616,23 +1486,20 @@ class LatLonBase(_NamedBase):
|
|
|
1616
1486
|
# return _NamedBase._update(self, updated, *attrs, **setters)
|
|
1617
1487
|
|
|
1618
1488
|
def vincentysTo(self, other, **radius_wrap):
|
|
1619
|
-
'''Compute the distance between this and an other point using
|
|
1620
|
-
|
|
1621
|
-
spherical formula.
|
|
1489
|
+
'''Compute the distance between this and an other point using U{Vincenty's
|
|
1490
|
+
<https://WikiPedia.org/wiki/Great-circle_distance>} spherical formula.
|
|
1622
1491
|
|
|
1623
1492
|
@arg other: The other point (C{LatLon}).
|
|
1624
|
-
@kwarg radius_wrap: Optional
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
datum ellipsoid.
|
|
1493
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for
|
|
1494
|
+
function L{pygeodesy.vincentys}, overriding the default
|
|
1495
|
+
C{mean radius} of this point's datum ellipsoid.
|
|
1628
1496
|
|
|
1629
1497
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
1630
1498
|
|
|
1631
1499
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
1632
1500
|
|
|
1633
|
-
@see: Function L{pygeodesy.vincentys} and methods L{
|
|
1634
|
-
L{
|
|
1635
|
-
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo},
|
|
1501
|
+
@see: Function L{pygeodesy.vincentys} and methods L{cosineLawTo}, C{distanceTo*},
|
|
1502
|
+
L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo} / L{hubenyTo},
|
|
1636
1503
|
L{flatPolarTo}, L{haversineTo} and L{thomasTo}.
|
|
1637
1504
|
'''
|
|
1638
1505
|
return self._distanceTo(_formy.vincentys, other, **_xkwds(radius_wrap, radius=None))
|
|
@@ -1692,17 +1559,64 @@ def _latlonheight3(latlonh, height, wrap): # in .points.LatLon_.__init__
|
|
|
1692
1559
|
return lat, lon, height
|
|
1693
1560
|
|
|
1694
1561
|
|
|
1695
|
-
def
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1562
|
+
def latlon2n_xyz(lat_ll, lon=None, **name):
|
|
1563
|
+
'''Convert lat-, longitude to C{n-vector} (I{normal} to the earth's surface) X, Y and Z components.
|
|
1564
|
+
|
|
1565
|
+
@arg lat_ll: Latitude (C{degrees}) or a C{LatLon} instance, L{LatLon2Tuple} or other C{LatLon*Tuple}.
|
|
1566
|
+
@kwarg lon: Longitude (C{degrees}), required if C{B{lon_ll} is degrees}, ignored otherwise.
|
|
1567
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1568
|
+
|
|
1569
|
+
@return: A L{Vector3Tuple}C{(x, y, z)}.
|
|
1570
|
+
|
|
1571
|
+
@see: Function L{philam2n_xyz}.
|
|
1572
|
+
|
|
1573
|
+
@note: These are C{n-vector} x, y and z components, I{NOT geocentric} x, y and z (ECEF) coordinates!
|
|
1574
|
+
'''
|
|
1575
|
+
lat = lat_ll
|
|
1576
|
+
if lon is None:
|
|
1577
|
+
try:
|
|
1578
|
+
lat, lon = lat_ll.latlon
|
|
1579
|
+
except AttributeError:
|
|
1580
|
+
lat = lat_ll.lat
|
|
1581
|
+
lon = lat_ll.lon
|
|
1582
|
+
# Kenneth Gade eqn 3, but using right-handed
|
|
1583
|
+
# vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N
|
|
1584
|
+
sa, ca, sb, cb = sincos2d_(lat, lon)
|
|
1585
|
+
return Vector3Tuple(ca * cb, ca * sb, sa, **name)
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
def philam2n_xyz(phi_ll, lam=None, **name):
|
|
1589
|
+
'''Convert lat-, longitude to C{n-vector} (I{normal} to the earth's surface) X, Y and Z components.
|
|
1590
|
+
|
|
1591
|
+
@arg phi_ll: Latitude (C{radians}) or a C{LatLon} instance with C{phi}, C{lam} or C{philam} attributes.
|
|
1592
|
+
@kwarg lam: Longitude (C{radians}), required if C{B{phi_ll} is radians}, ignored otherwise.
|
|
1593
|
+
@kwarg name: Optional name (C{str}).
|
|
1594
|
+
|
|
1595
|
+
@return: A L{Vector3Tuple}C{(x, y, z)}.
|
|
1596
|
+
|
|
1597
|
+
@see: Function L{latlon2n_xyz}.
|
|
1598
|
+
|
|
1599
|
+
@note: These are C{n-vector} x, y and z components, I{NOT geocentric} x, y and z (ECEF) coordinates!
|
|
1600
|
+
'''
|
|
1601
|
+
phi = phi_ll
|
|
1602
|
+
if lam is None:
|
|
1603
|
+
try:
|
|
1604
|
+
phi, lam = phi_ll.philam
|
|
1605
|
+
except AttributeError:
|
|
1606
|
+
phi = phi_ll.phi
|
|
1607
|
+
lam = phi_ll.lam
|
|
1608
|
+
return latlon2n_xyz(degrees(phi), degrees(lam), **name)
|
|
1609
|
+
|
|
1610
|
+
|
|
1611
|
+
def _trilaterate5(p1, d1, p2, d2, p3, d3, area=True, eps=EPS1, radius=R_M, wrap=False): # MCCABE 13
|
|
1612
|
+
'''(INTERNAL) Trilaterate three points by I{area overlap} or by I{perimeter intersection} of three circles.
|
|
1699
1613
|
|
|
1700
|
-
@note: The B{C{radius}} is only
|
|
1701
|
-
C{
|
|
1702
|
-
|
|
1703
|
-
C{-Karney} and C{-Vincenty.LatLon.distanceTo} methods.
|
|
1614
|
+
@note: The B{C{radius}} is needed only for C{n-vectorial} and C{sphericalTrigonometry.LatLon.distanceTo}
|
|
1615
|
+
methods and silently ignored by the C{ellipsoidalExact}, C{-GeodSolve}, C{-Karney} and
|
|
1616
|
+
C{-Vincenty.LatLon.distanceTo} methods.
|
|
1704
1617
|
'''
|
|
1705
1618
|
p2, p3, w = _unrollon3(p1, p2, p3, wrap)
|
|
1619
|
+
rw = dict(radius=radius, wrap=w)
|
|
1706
1620
|
|
|
1707
1621
|
r1 = Distance_(distance1=d1)
|
|
1708
1622
|
r2 = Distance_(distance2=d2)
|
|
@@ -1719,14 +1633,14 @@ def _trilaterate5(p1, d1, p2, d2, p3, d3, area=True, eps=EPS1, # MCCABE 13
|
|
|
1719
1633
|
c = c1
|
|
1720
1634
|
else: # nearest point on radical
|
|
1721
1635
|
c = p3.nearestOn(c1, c2, within=True, wrap=w)
|
|
1722
|
-
d = r3 - p3.distanceTo(c,
|
|
1636
|
+
d = r3 - p3.distanceTo(c, **rw)
|
|
1723
1637
|
if d > eps: # sufficient overlap
|
|
1724
1638
|
t.append((d, c))
|
|
1725
1639
|
m = max(m, d)
|
|
1726
1640
|
|
|
1727
1641
|
else: # check intersection
|
|
1728
1642
|
for c in ((c1,) if c1 is c2 else (c1, c2)):
|
|
1729
|
-
d = fabs(r3 - p3.distanceTo(c,
|
|
1643
|
+
d = fabs(r3 - p3.distanceTo(c, **rw))
|
|
1730
1644
|
if d < eps: # below margin
|
|
1731
1645
|
t.append((d, c))
|
|
1732
1646
|
m = min(m, d)
|
|
@@ -1760,7 +1674,7 @@ __all__ += _ALL_DOCS(LatLonBase)
|
|
|
1760
1674
|
|
|
1761
1675
|
# **) MIT License
|
|
1762
1676
|
#
|
|
1763
|
-
# Copyright (C) 2016-
|
|
1677
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1764
1678
|
#
|
|
1765
1679
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1766
1680
|
# copy of this software and associated documentation files (the "Software"),
|