pygeodesy 24.10.24__py2.py3-none-any.whl → 24.12.12__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/METADATA +6 -6
- PyGeodesy-24.12.12.dist-info/RECORD +118 -0
- {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +5 -5
- 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 +55 -65
- pygeodesy/basics.py +35 -34
- pygeodesy/booleans.py +37 -37
- pygeodesy/cartesianBase.py +26 -65
- pygeodesy/clipy.py +1 -1
- pygeodesy/constants.py +7 -7
- pygeodesy/css.py +8 -9
- pygeodesy/datums.py +1 -1
- pygeodesy/deprecated/__init__.py +2 -2
- pygeodesy/deprecated/bases.py +1 -1
- pygeodesy/deprecated/classes.py +10 -10
- pygeodesy/deprecated/consterns.py +1 -1
- pygeodesy/deprecated/datum.py +1 -1
- pygeodesy/deprecated/functions.py +23 -13
- 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 +63 -69
- pygeodesy/elevations.py +1 -1
- pygeodesy/ellipsoidalBase.py +106 -121
- pygeodesy/ellipsoidalBaseDI.py +115 -119
- pygeodesy/ellipsoidalExact.py +36 -38
- pygeodesy/ellipsoidalGeodSolve.py +1 -1
- pygeodesy/ellipsoidalKarney.py +1 -1
- pygeodesy/ellipsoidalNvector.py +1 -1
- pygeodesy/ellipsoidalVincenty.py +6 -5
- pygeodesy/ellipsoids.py +7 -8
- pygeodesy/elliptic.py +6 -6
- pygeodesy/epsg.py +1 -1
- pygeodesy/errors.py +25 -25
- pygeodesy/etm.py +84 -76
- pygeodesy/fmath.py +54 -51
- pygeodesy/formy.py +74 -106
- pygeodesy/frechet.py +1 -1
- pygeodesy/fstats.py +1 -1
- pygeodesy/fsums.py +82 -72
- pygeodesy/gars.py +1 -1
- pygeodesy/geodesici.py +4 -4
- pygeodesy/geodesicw.py +16 -15
- 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 +3 -3
- pygeodesy/geodesicx/__main__.py +1 -1
- 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 +8 -17
- pygeodesy/geohash.py +1 -1
- pygeodesy/geoids.py +6 -6
- pygeodesy/hausdorff.py +1 -1
- pygeodesy/heights.py +3 -3
- pygeodesy/internals.py +64 -80
- pygeodesy/interns.py +2 -3
- pygeodesy/iters.py +1 -1
- pygeodesy/karney.py +4 -4
- pygeodesy/ktm.py +20 -21
- pygeodesy/latlonBase.py +296 -346
- pygeodesy/lazily.py +15 -15
- pygeodesy/lcc.py +5 -5
- pygeodesy/ltp.py +55 -59
- pygeodesy/ltpTuples.py +208 -192
- pygeodesy/mgrs.py +9 -10
- pygeodesy/named.py +153 -3
- pygeodesy/namedTuples.py +58 -7
- pygeodesy/nvectorBase.py +122 -105
- pygeodesy/osgr.py +10 -13
- pygeodesy/points.py +1 -1
- pygeodesy/props.py +3 -3
- pygeodesy/resections.py +26 -26
- pygeodesy/rhumb/__init__.py +2 -2
- pygeodesy/rhumb/aux_.py +2 -2
- pygeodesy/rhumb/bases.py +2 -2
- pygeodesy/rhumb/ekx.py +4 -4
- pygeodesy/rhumb/solve.py +4 -4
- pygeodesy/simplify.py +291 -403
- pygeodesy/solveBase.py +1 -1
- pygeodesy/sphericalBase.py +1 -1
- pygeodesy/sphericalNvector.py +84 -127
- pygeodesy/sphericalTrigonometry.py +66 -71
- pygeodesy/streprs.py +10 -5
- pygeodesy/trf.py +1 -1
- pygeodesy/triaxials.py +23 -16
- pygeodesy/units.py +17 -17
- pygeodesy/unitsBase.py +1 -1
- pygeodesy/ups.py +4 -4
- pygeodesy/utily.py +202 -145
- pygeodesy/utm.py +10 -10
- pygeodesy/utmups.py +1 -1
- pygeodesy/utmupsBase.py +1 -1
- pygeodesy/vector2d.py +17 -17
- pygeodesy/vector3d.py +32 -23
- pygeodesy/vector3dBase.py +22 -19
- pygeodesy/webmercator.py +5 -5
- pygeodesy/wgrs.py +5 -5
- PyGeodesy-24.10.24.dist-info/RECORD +0 -118
- {PyGeodesy-24.10.24.dist-info → PyGeodesy-24.12.12.dist-info}/top_level.txt +0 -0
pygeodesy/latlonBase.py
CHANGED
|
@@ -35,33 +35,31 @@ 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
|
-
# Circum3Tuple,
|
|
49
|
+
# Circum3Tuple, _radii11ABC4 # _MODS
|
|
51
50
|
# from pygeodesy.vector3d import nearestOn6, Vector3d # _MODS
|
|
52
51
|
|
|
53
52
|
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.06'
|
|
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
75
|
@kwarg lon: Longitude (C{degrees} or DMS C{str} with E or W suffix) or
|
|
78
|
-
C(None), indicating B{C{
|
|
76
|
+
C(None), indicating B{C{lat_llh}} is a C{LatLon}.
|
|
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
|
|
@@ -370,11 +368,10 @@ class LatLonBase(_NamedBase):
|
|
|
370
368
|
of the U{Law of Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>} formula.
|
|
371
369
|
|
|
372
370
|
@arg other: The other point (C{LatLon}).
|
|
373
|
-
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
374
|
-
|
|
371
|
+
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap or I{normalize}
|
|
372
|
+
and unroll the B{C{other}} point (C{bool}).
|
|
375
373
|
|
|
376
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
377
|
-
ellipsoid).
|
|
374
|
+
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
|
|
378
375
|
|
|
379
376
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
380
377
|
|
|
@@ -387,18 +384,15 @@ class LatLonBase(_NamedBase):
|
|
|
387
384
|
return self._distanceTo_(_formy.cosineAndoyerLambert_, other, **wrap)
|
|
388
385
|
|
|
389
386
|
def cosineForsytheAndoyerLambertTo(self, other, **wrap):
|
|
390
|
-
'''Compute the distance between this and an other point using
|
|
391
|
-
the U{
|
|
392
|
-
<https://
|
|
393
|
-
<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
|
|
394
|
-
formula.
|
|
387
|
+
'''Compute the distance between this and an other point using the U{Forsythe-Andoyer-Lambert
|
|
388
|
+
correction<https://www2.UNB.Ca/gge/Pubs/TR77.pdf>} of the U{Law of Cosines
|
|
389
|
+
<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>} formula.
|
|
395
390
|
|
|
396
391
|
@arg other: The other point (C{LatLon}).
|
|
397
|
-
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
398
|
-
|
|
392
|
+
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap or I{normalize}
|
|
393
|
+
and unroll the B{C{other}} point (C{bool}).
|
|
399
394
|
|
|
400
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
401
|
-
ellipsoid).
|
|
395
|
+
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
|
|
402
396
|
|
|
403
397
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
404
398
|
|
|
@@ -410,16 +404,14 @@ class LatLonBase(_NamedBase):
|
|
|
410
404
|
return self._distanceTo_(_formy.cosineForsytheAndoyerLambert_, other, **wrap)
|
|
411
405
|
|
|
412
406
|
def cosineLawTo(self, other, radius=None, **wrap):
|
|
413
|
-
'''Compute the distance between this and an other point using the
|
|
414
|
-
|
|
415
|
-
<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
|
|
416
|
-
formula.
|
|
407
|
+
'''Compute the distance between this and an other point using the U{spherical Law of
|
|
408
|
+
Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>} formula.
|
|
417
409
|
|
|
418
410
|
@arg other: The other point (C{LatLon}).
|
|
419
|
-
@kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius
|
|
420
|
-
|
|
421
|
-
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
422
|
-
|
|
411
|
+
@kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this
|
|
412
|
+
point's datum ellipsoid.
|
|
413
|
+
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap or
|
|
414
|
+
I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
423
415
|
|
|
424
416
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
425
417
|
|
|
@@ -440,20 +432,17 @@ class LatLonBase(_NamedBase):
|
|
|
440
432
|
def destinationXyz(self, delta, LatLon=None, **LatLon_kwds):
|
|
441
433
|
'''Calculate the destination using a I{local} delta from this point.
|
|
442
434
|
|
|
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}.
|
|
435
|
+
@arg delta: Local delta to the destination (L{XyzLocal}, L{Aer}, L{Enu}, L{Ned}
|
|
436
|
+
or L{Local9Tuple}).
|
|
437
|
+
@kwarg LatLon: Optional (geodetic) class to return the destination or C{None}.
|
|
438
|
+
@kwarg LatLon_kwds: Optionally, additional B{C{LatLon}} keyword arguments,
|
|
439
|
+
ignored if C{B{LatLon} is None}.
|
|
449
440
|
|
|
450
|
-
@return:
|
|
451
|
-
|
|
452
|
-
lon, height)}
|
|
453
|
-
height, datum)} depending on whether a C{datum} keyword
|
|
454
|
-
is un-/specified.
|
|
441
|
+
@return: An B{C{LatLon}} instance or if C{B{LatLon} is None}, a
|
|
442
|
+
L{LatLon4Tuple}C{(lat, lon, height, datum)} or L{LatLon3Tuple}C{(lat,
|
|
443
|
+
lon, height)} if a C{datum} keyword is specified or not.
|
|
455
444
|
|
|
456
|
-
@raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}}.
|
|
445
|
+
@raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}} item.
|
|
457
446
|
'''
|
|
458
447
|
t = self._Ltp._local2ecef(delta, nine=True)
|
|
459
448
|
return t.toLatLon(LatLon=LatLon, **_xkwds(LatLon_kwds, name=self.name))
|
|
@@ -475,12 +464,6 @@ class LatLonBase(_NamedBase):
|
|
|
475
464
|
r = func_(phi2, self.phi, lam21, datum=D)
|
|
476
465
|
return r * (D.ellipsoid.a if radius is None else radius)
|
|
477
466
|
|
|
478
|
-
@property_ROnce
|
|
479
|
-
def Ecef(self):
|
|
480
|
-
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
481
|
-
'''
|
|
482
|
-
return _MODS.ecef.EcefKarney
|
|
483
|
-
|
|
484
467
|
@Property_RO
|
|
485
468
|
def _Ecef_forward(self):
|
|
486
469
|
'''(INTERNAL) Helper for L{_ecef9} and L{toEcef} (C{callable}).
|
|
@@ -592,10 +575,9 @@ class LatLonBase(_NamedBase):
|
|
|
592
575
|
Geographical_distance#Polar_coordinate_flat-Earth_formula>} formula.
|
|
593
576
|
|
|
594
577
|
@arg other: The other point (C{LatLon}).
|
|
595
|
-
@kwarg radius_wrap: Optional
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
datum ellipsoid.
|
|
578
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for
|
|
579
|
+
function L{pygeodesy.flatPolar}, overriding the default
|
|
580
|
+
C{mean radius} of this point's datum ellipsoid.
|
|
599
581
|
|
|
600
582
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
601
583
|
|
|
@@ -619,8 +601,8 @@ class LatLonBase(_NamedBase):
|
|
|
619
601
|
or C{scalar} radius in C{meter}), overriding this point's C{datum}
|
|
620
602
|
ellipsoid.
|
|
621
603
|
|
|
622
|
-
@return: The intersection (C{LatLon}) with C{.height} set to the distance
|
|
623
|
-
this C{pov}.
|
|
604
|
+
@return: The intersection (C{LatLon}) with attribute C{.height} set to the distance
|
|
605
|
+
to this C{pov}.
|
|
624
606
|
|
|
625
607
|
@raise IntersectionError: Null or bad C{pov} or B{C{los}}, this C{pov} is inside
|
|
626
608
|
the ellipsoid or B{C{los}} points outside or away from
|
|
@@ -633,15 +615,13 @@ class LatLonBase(_NamedBase):
|
|
|
633
615
|
return _formy._hartzell(self, los, earth, LatLon=self.classof)
|
|
634
616
|
|
|
635
617
|
def haversineTo(self, other, **radius_wrap):
|
|
636
|
-
'''Compute the distance between this and an other point using the
|
|
637
|
-
|
|
638
|
-
formula.
|
|
618
|
+
'''Compute the distance between this and an other point using the U{Haversine
|
|
619
|
+
<https://www.Movable-Type.co.UK/scripts/latlong.html>} formula.
|
|
639
620
|
|
|
640
621
|
@arg other: The other point (C{LatLon}).
|
|
641
|
-
@kwarg radius_wrap: Optional
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
datum ellipsoid.
|
|
622
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for function
|
|
623
|
+
L{pygeodesy.haversine}, overriding the default C{mean radius} of
|
|
624
|
+
this point's datum ellipsoid.
|
|
645
625
|
|
|
646
626
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
647
627
|
|
|
@@ -661,8 +641,8 @@ class LatLonBase(_NamedBase):
|
|
|
661
641
|
@kwarg f: Optional fraction (C{float}).
|
|
662
642
|
@kwarg h: Overriding height (C{meter}).
|
|
663
643
|
|
|
664
|
-
@return: Average, fractional height (C{float}) or
|
|
665
|
-
|
|
644
|
+
@return: Average, fractional height (C{float}) or the
|
|
645
|
+
overriding height B{C{h}} (C{Height}).
|
|
666
646
|
'''
|
|
667
647
|
return Height(h) if h is not None else \
|
|
668
648
|
_MODS.fmath.favg(self.height, other.height, f=f)
|
|
@@ -702,22 +682,23 @@ class LatLonBase(_NamedBase):
|
|
|
702
682
|
@kwarg normal: If C{True}, the projection is the normal to this ellipsoid's
|
|
703
683
|
surface, otherwise the intersection of the I{radial} line to
|
|
704
684
|
this ellipsoid's center (C{bool}).
|
|
705
|
-
@kwarg LatLon: Optional class to return the projection, height and
|
|
706
|
-
|
|
707
|
-
@kwarg LatLon_kwds:
|
|
685
|
+
@kwarg LatLon: Optional class to return the projection, height and datum
|
|
686
|
+
(C{LatLon}) or C{None}.
|
|
687
|
+
@kwarg LatLon_kwds: Optionally, additional B{C{LatLon}} keyword arguments,
|
|
708
688
|
ignored if C{B{LatLon} is None}.
|
|
709
689
|
|
|
710
690
|
@note: Use keyword argument C{height=0} to override C{B{LatLon}.height}
|
|
711
691
|
to {0} or any other C{scalar}, conventionally in C{meter}.
|
|
712
692
|
|
|
713
|
-
@return:
|
|
714
|
-
|
|
715
|
-
|
|
693
|
+
@return: A B{C{LatLon}} instance or if C{B{LatLon} is None}, a L{Vector4Tuple}C{(x,
|
|
694
|
+
y, z, h)} with the I{projection} C{x}, C{y} and C{z} coordinates and
|
|
695
|
+
height C{h} in C{meter}, conventionally.
|
|
716
696
|
|
|
717
697
|
@raise TriaxialError: No convergence in triaxial root finding.
|
|
718
698
|
|
|
719
|
-
@raise TypeError: Invalid B{C{
|
|
720
|
-
|
|
699
|
+
@raise TypeError: Invalid B{C{LatLon}}, B{C{LatLon_kwds}} item, B{C{earth}}
|
|
700
|
+
or triaxial B{C{earth}} couldn't be converted to biaxial
|
|
701
|
+
B{C{LatLon}} datum.
|
|
721
702
|
|
|
722
703
|
@see: Methods L{Ellipsoid.height4} and L{Triaxial_.height4} for more information.
|
|
723
704
|
'''
|
|
@@ -747,7 +728,7 @@ class LatLonBase(_NamedBase):
|
|
|
747
728
|
|
|
748
729
|
def _intersecend2(self, p, q, wrap, height, g_or_r, P, Q, unused): # in .LatLonEllipsoidalBaseDI.intersecant2
|
|
749
730
|
'''(INTERNAL) Interpolate 2 heights along a geodesic or rhumb
|
|
750
|
-
line and return the 2
|
|
731
|
+
line and return the 2 intersecant points accordingly.
|
|
751
732
|
'''
|
|
752
733
|
if height is None:
|
|
753
734
|
hp = hq = _xattr(p, height=INT0)
|
|
@@ -777,14 +758,14 @@ class LatLonBase(_NamedBase):
|
|
|
777
758
|
return self.isantipodeTo(other, eps=eps)
|
|
778
759
|
|
|
779
760
|
def isantipodeTo(self, other, eps=EPS):
|
|
780
|
-
'''Check whether this and an other point are antipodal,
|
|
781
|
-
|
|
761
|
+
'''Check whether this and an other point are antipodal, on diametrically
|
|
762
|
+
opposite sides of the earth.
|
|
782
763
|
|
|
783
764
|
@arg other: The other point (C{LatLon}).
|
|
784
765
|
@kwarg eps: Tolerance for near-equality (C{degrees}).
|
|
785
766
|
|
|
786
|
-
@return: C{True} if points are antipodal within the given
|
|
787
|
-
|
|
767
|
+
@return: C{True} if points are antipodal within the given tolerance,
|
|
768
|
+
C{False} otherwise.
|
|
788
769
|
'''
|
|
789
770
|
p = self.others(other)
|
|
790
771
|
return _formy.isantipode(*(self.latlon + p.latlon), eps=eps)
|
|
@@ -801,12 +782,11 @@ class LatLonBase(_NamedBase):
|
|
|
801
782
|
@arg other: The other point (C{LatLon}).
|
|
802
783
|
@kwarg eps: Tolerance for equality (C{degrees}).
|
|
803
784
|
|
|
804
|
-
@return: C{True} if both points are identical,
|
|
805
|
-
|
|
785
|
+
@return: C{True} if both points are identical, I{ignoring} height,
|
|
786
|
+
C{False} otherwise.
|
|
806
787
|
|
|
807
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}
|
|
808
|
-
|
|
809
|
-
this C{class} or C{type}.
|
|
788
|
+
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch
|
|
789
|
+
of the B{C{other}} and this C{class} or C{type}.
|
|
810
790
|
|
|
811
791
|
@raise UnitError: Invalid B{C{eps}}.
|
|
812
792
|
|
|
@@ -820,12 +800,11 @@ class LatLonBase(_NamedBase):
|
|
|
820
800
|
@arg other: The other point (C{LatLon}).
|
|
821
801
|
@kwarg eps: Tolerance for equality (C{degrees}).
|
|
822
802
|
|
|
823
|
-
@return: C{True} if both points are identical I{including}
|
|
824
|
-
|
|
803
|
+
@return: C{True} if both points are identical I{including} height,
|
|
804
|
+
C{False} otherwise.
|
|
825
805
|
|
|
826
|
-
@raise TypeError: The B{C{other}} point is not C{LatLon}
|
|
827
|
-
|
|
828
|
-
C{class} or C{type}.
|
|
806
|
+
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch
|
|
807
|
+
of the B{C{other}} and this C{class} or C{type}.
|
|
829
808
|
|
|
830
809
|
@see: Method L{isequalTo}.
|
|
831
810
|
'''
|
|
@@ -879,17 +858,17 @@ class LatLonBase(_NamedBase):
|
|
|
879
858
|
|
|
880
859
|
@latlon.setter # PYCHOK setter!
|
|
881
860
|
def latlon(self, latlonh):
|
|
882
|
-
'''Set the lat- and longitude and optionally the height
|
|
883
|
-
|
|
884
|
-
|
|
861
|
+
'''Set the lat- and longitude and optionally the height (2- or 3-tuple
|
|
862
|
+
or comma- or space-separated C{str} of C{degrees90}, C{degrees180}
|
|
863
|
+
and C{meter}).
|
|
885
864
|
|
|
886
|
-
@raise TypeError: Height of B{C{latlonh}} not C{scalar} or
|
|
887
|
-
|
|
865
|
+
@raise TypeError: Height of B{C{latlonh}} not C{scalar} or B{C{latlonh}}
|
|
866
|
+
not C{list} or C{tuple}.
|
|
888
867
|
|
|
889
868
|
@raise ValueError: Invalid B{C{latlonh}} or M{len(latlonh)}.
|
|
890
869
|
|
|
891
|
-
@see: Function L{pygeodesy.parse3llh} to parse a B{C{latlonh}}
|
|
892
|
-
|
|
870
|
+
@see: Function L{pygeodesy.parse3llh} to parse a B{C{latlonh}} string
|
|
871
|
+
into a 3-tuple C{(lat, lon, h)}.
|
|
893
872
|
'''
|
|
894
873
|
if isstr(latlonh):
|
|
895
874
|
latlonh = parse3llh(latlonh, height=self.height)
|
|
@@ -912,11 +891,11 @@ class LatLonBase(_NamedBase):
|
|
|
912
891
|
|
|
913
892
|
@kwarg ndigits: Number of (decimal) digits (C{int}).
|
|
914
893
|
|
|
915
|
-
@return: A L{LatLon2Tuple}C{(lat, lon)}, both C{float}
|
|
916
|
-
|
|
894
|
+
@return: A L{LatLon2Tuple}C{(lat, lon)}, both C{float} and rounded
|
|
895
|
+
away from zero.
|
|
917
896
|
|
|
918
|
-
@note: The C{round}ed values are always C{float}, also
|
|
919
|
-
|
|
897
|
+
@note: The C{round}ed values are always C{float}, also if B{C{ndigits}}
|
|
898
|
+
is omitted.
|
|
920
899
|
'''
|
|
921
900
|
return LatLon2Tuple(round(self.lat, ndigits),
|
|
922
901
|
round(self.lon, ndigits), name=self.name)
|
|
@@ -961,37 +940,28 @@ class LatLonBase(_NamedBase):
|
|
|
961
940
|
_update_all(self)
|
|
962
941
|
self._lon = lon
|
|
963
942
|
|
|
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
943
|
def nearestOn6(self, points, closed=False, height=None, wrap=False):
|
|
971
944
|
'''Locate the point on a path or polygon closest to this point.
|
|
972
945
|
|
|
973
|
-
Points are converted to and distances are computed in
|
|
974
|
-
|
|
946
|
+
Points are converted to and distances are computed in I{geocentric},
|
|
947
|
+
cartesian space.
|
|
975
948
|
|
|
976
949
|
@arg points: The path or polygon points (C{LatLon}[]).
|
|
977
950
|
@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
|
|
951
|
+
@kwarg height: Optional height, overriding the height of this and all
|
|
952
|
+
other points (C{meter}). If C{None}, take the height
|
|
953
|
+
of points into account for distances.
|
|
954
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{points}}
|
|
955
|
+
(C{bool}).
|
|
956
|
+
|
|
957
|
+
@return: A L{NearestOn6Tuple}C{(closest, distance, fi, j, start, end)}
|
|
958
|
+
with the C{closest}, the C{start} and the C{end} point each an
|
|
959
|
+
instance of this C{LatLon} and C{distance} in C{meter}, same
|
|
989
960
|
units as the cartesian axes.
|
|
990
961
|
|
|
991
962
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
992
963
|
|
|
993
|
-
@raise TypeError: Some B{C{points}} or some B{C{points}}'
|
|
994
|
-
C{Ecef} invalid.
|
|
964
|
+
@raise TypeError: Some B{C{points}} or some B{C{points}}' C{Ecef} invalid.
|
|
995
965
|
|
|
996
966
|
@raise ValueError: Some B{C{points}}' C{Ecef} is incompatible.
|
|
997
967
|
|
|
@@ -1025,11 +995,9 @@ class LatLonBase(_NamedBase):
|
|
|
1025
995
|
self._notImplemented(*args, **kwds)
|
|
1026
996
|
|
|
1027
997
|
def normal(self):
|
|
1028
|
-
'''Normalize this point I{in-place} to C{abs(lat) <= 90} and
|
|
1029
|
-
C{abs(lon) <= 180}.
|
|
998
|
+
'''Normalize this point I{in-place} to C{abs(lat) <= 90} and C{abs(lon) <= 180}.
|
|
1030
999
|
|
|
1031
|
-
@return: C{True} if this point was I{normal}, C{False} if it
|
|
1032
|
-
wasn't (but is now).
|
|
1000
|
+
@return: C{True} if this point was I{normal}, C{False} if it wasn't (but is now).
|
|
1033
1001
|
|
|
1034
1002
|
@see: Property L{isnormal} and method L{toNormal}.
|
|
1035
1003
|
'''
|
|
@@ -1049,7 +1017,7 @@ class LatLonBase(_NamedBase):
|
|
|
1049
1017
|
def _n_xyz3(self):
|
|
1050
1018
|
'''(INTERNAL) Get the n-vector components as L{Vector3Tuple}.
|
|
1051
1019
|
'''
|
|
1052
|
-
return
|
|
1020
|
+
return philam2n_xyz(self.phi, self.lam, name=self.name)
|
|
1053
1021
|
|
|
1054
1022
|
@Property_RO
|
|
1055
1023
|
def phi(self):
|
|
@@ -1068,11 +1036,10 @@ class LatLonBase(_NamedBase):
|
|
|
1068
1036
|
|
|
1069
1037
|
@kwarg ndigits: Number of (decimal) digits (C{int}).
|
|
1070
1038
|
|
|
1071
|
-
@return: A L{PhiLam2Tuple}C{(phi, lam)}, both C{float}
|
|
1072
|
-
|
|
1039
|
+
@return: A L{PhiLam2Tuple}C{(phi, lam)}, both C{float} and rounded
|
|
1040
|
+
away from zero.
|
|
1073
1041
|
|
|
1074
|
-
@note: The C{round}ed values are
|
|
1075
|
-
if B{C{ndigits}} is omitted.
|
|
1042
|
+
@note: The C{round}ed values are C{float}, always.
|
|
1076
1043
|
'''
|
|
1077
1044
|
return PhiLam2Tuple(round(self.phi, ndigits),
|
|
1078
1045
|
round(self.lam, ndigits), name=self.name)
|
|
@@ -1092,12 +1059,11 @@ class LatLonBase(_NamedBase):
|
|
|
1092
1059
|
'''Check a path or polygon represented by points.
|
|
1093
1060
|
|
|
1094
1061
|
@arg points: The path or polygon points (C{LatLon}[])
|
|
1095
|
-
@kwarg closed: Optionally, consider the polygon closed,
|
|
1096
|
-
|
|
1097
|
-
B{C{points}} (C{bool}).
|
|
1062
|
+
@kwarg closed: Optionally, consider the polygon closed, ignoring any
|
|
1063
|
+
duplicate or closing final B{C{points}} (C{bool}).
|
|
1098
1064
|
|
|
1099
|
-
@return: A L{Points2Tuple}C{(number, points)}, an C{int}
|
|
1100
|
-
|
|
1065
|
+
@return: A L{Points2Tuple}C{(number, points)}, an C{int} and a C{list}
|
|
1066
|
+
or C{tuple}.
|
|
1101
1067
|
|
|
1102
1068
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
1103
1069
|
|
|
@@ -1111,8 +1077,8 @@ class LatLonBase(_NamedBase):
|
|
|
1111
1077
|
@arg points: The path or polygon points (C{LatLon}[])
|
|
1112
1078
|
@kwarg loop: Number of loop-back points (non-negative C{int}).
|
|
1113
1079
|
@kwarg dedup: If C{True}, skip duplicate points (C{bool}).
|
|
1114
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} the
|
|
1115
|
-
|
|
1080
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} the enum-/iterated
|
|
1081
|
+
B{C{points}} (C{bool}).
|
|
1116
1082
|
|
|
1117
1083
|
@return: A new C{PointsIter} iterator.
|
|
1118
1084
|
|
|
@@ -1142,7 +1108,7 @@ class LatLonBase(_NamedBase):
|
|
|
1142
1108
|
Circles<https://MathWorld.Wolfram.com/TangentCircles.html>}.
|
|
1143
1109
|
'''
|
|
1144
1110
|
with _toCartesian3(self, point2, point3, wrap) as cs:
|
|
1145
|
-
return _MODS.vector2d.
|
|
1111
|
+
return _MODS.vector2d._radii11ABC4(*cs, useZ=True)[0]
|
|
1146
1112
|
|
|
1147
1113
|
def _rhumb3(self, exact, radius): # != .sphericalBase._rhumbs3
|
|
1148
1114
|
'''(INTERNAL) Get the C{rhumb} for this point's datum or for
|
|
@@ -1169,51 +1135,43 @@ class LatLonBase(_NamedBase):
|
|
|
1169
1135
|
return {} # 3-item cache
|
|
1170
1136
|
|
|
1171
1137
|
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
|
-
|
|
1138
|
+
'''Return the azimuth (bearing) of a rhumb line (loxodrome) between this and
|
|
1139
|
+
an other (ellipsoidal) point.
|
|
1174
1140
|
|
|
1175
1141
|
@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}).
|
|
1142
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method
|
|
1143
|
+
L{Ellipsoid.rhumb_}.
|
|
1144
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1145
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1146
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1147
|
+
@kwarg b360: If C{True}, return the azimuth as bearing in compass degrees (C{bool}).
|
|
1185
1148
|
|
|
1186
1149
|
@return: Rhumb azimuth (C{degrees180} or compass C{degrees360}).
|
|
1187
1150
|
|
|
1188
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1189
|
-
is invalid.
|
|
1151
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1190
1152
|
'''
|
|
1191
1153
|
r, _, Cs = self._rhumb3(exact, radius)
|
|
1192
1154
|
z = r._Inverse(self, other, wrap, outmask=Cs.AZIMUTH).azi12
|
|
1193
1155
|
return _umod_360(z + _360_0) if b360 else z
|
|
1194
1156
|
|
|
1195
|
-
def rhumbDestination(self, distance, azimuth, radius=None, height=None,
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
this point along a rhumb line (loxodrome) of the given azimuth.
|
|
1157
|
+
def rhumbDestination(self, distance, azimuth, radius=None, height=None, exact=False, **name):
|
|
1158
|
+
'''Return the destination point having travelled the given distance from this point along
|
|
1159
|
+
a rhumb line (loxodrome) of the given azimuth.
|
|
1199
1160
|
|
|
1200
|
-
@arg distance: Distance travelled (C{meter}, same units as this point's
|
|
1201
|
-
|
|
1161
|
+
@arg distance: Distance travelled (C{meter}, same units as this point's datum (ellipsoid)
|
|
1162
|
+
axes or B{C{radius}}, may be negative.
|
|
1202
1163
|
@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.
|
|
1164
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1165
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1206
1166
|
@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_}.
|
|
1167
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1209
1168
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1210
1169
|
|
|
1211
1170
|
@return: The destination point (ellipsoidal C{LatLon}).
|
|
1212
1171
|
|
|
1213
1172
|
@raise TypeError: Invalid B{C{radius}}.
|
|
1214
1173
|
|
|
1215
|
-
@raise ValueError: Invalid B{C{distance}}, B{C{azimuth}}, B{C{radius}}
|
|
1216
|
-
or B{C{height}}.
|
|
1174
|
+
@raise ValueError: Invalid B{C{distance}}, B{C{azimuth}}, B{C{radius}} or B{C{height}}.
|
|
1217
1175
|
'''
|
|
1218
1176
|
r, D, _ = self._rhumb3(exact, radius)
|
|
1219
1177
|
d = r._Direct(self, azimuth, distance)
|
|
@@ -1221,23 +1179,17 @@ class LatLonBase(_NamedBase):
|
|
|
1221
1179
|
return self.classof(d.lat2, d.lon2, datum=D, height=h, **name)
|
|
1222
1180
|
|
|
1223
1181
|
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).
|
|
1182
|
+
'''Return the distance from this to an other point along a rhumb line (loxodrome).
|
|
1226
1183
|
|
|
1227
1184
|
@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}).
|
|
1185
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1186
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1187
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1188
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1235
1189
|
|
|
1236
|
-
@return: Distance (C{meter}, the same units as this point's datum
|
|
1237
|
-
(ellipsoid) axes or B{C{radius}}.
|
|
1190
|
+
@return: Distance (C{meter}, the same units as this point's datum (ellipsoid) axes or B{C{radius}}.
|
|
1238
1191
|
|
|
1239
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1240
|
-
is invalid.
|
|
1192
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1241
1193
|
|
|
1242
1194
|
@raise ValueError: Invalid B{C{radius}}.
|
|
1243
1195
|
'''
|
|
@@ -1246,30 +1198,28 @@ class LatLonBase(_NamedBase):
|
|
|
1246
1198
|
|
|
1247
1199
|
def rhumbIntersecant2(self, circle, point, other, height=None,
|
|
1248
1200
|
**exact_radius_wrap_eps_tol):
|
|
1249
|
-
'''Compute the intersections of a circle and a rhumb line given as two
|
|
1250
|
-
|
|
1201
|
+
'''Compute the intersections of a circle and a rhumb line given as two points or as a
|
|
1202
|
+
point and azimuth.
|
|
1251
1203
|
|
|
1252
|
-
@arg circle: Radius of the circle centered at this location (C{meter}),
|
|
1253
|
-
|
|
1204
|
+
@arg circle: Radius of the circle centered at this location (C{meter}), or a point
|
|
1205
|
+
on the circle (same C{LatLon} class).
|
|
1254
1206
|
@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.
|
|
1207
|
+
@arg other: An other point I{on} (same C{LatLon} class) or the azimuth I{of} (compass
|
|
1208
|
+
C{degrees}) the rhumb line.
|
|
1209
|
+
@kwarg height: Optional height for the intersection points (C{meter}, conventionally)
|
|
1210
|
+
or C{None} for interpolated heights.
|
|
1211
|
+
@kwarg exact_radius_wrap_eps_tol: Optional keyword arguments, see methods L{rhumbLine}
|
|
1212
|
+
and L{RhumbLineAux.Intersecant2} or L{RhumbLine.Intersecant2}.
|
|
1213
|
+
|
|
1214
|
+
@return: 2-Tuple of the intersection points (representing a chord), each an instance of
|
|
1215
|
+
this class. Both points are the same instance if the rhumb line is tangent to
|
|
1216
|
+
the circle.
|
|
1266
1217
|
|
|
1267
1218
|
@raise IntersectionError: The circle and rhumb line do not intersect.
|
|
1268
1219
|
|
|
1269
1220
|
@raise TypeError: Invalid B{C{point}}, B{C{circle}} or B{C{other}}.
|
|
1270
1221
|
|
|
1271
|
-
@raise ValueError: Invalid B{C{circle}}, B{C{other}}, B{C{height}}
|
|
1272
|
-
or B{C{exact_radius_wrap}}.
|
|
1222
|
+
@raise ValueError: Invalid B{C{circle}}, B{C{other}}, B{C{height}} or B{C{exact_radius_wrap}}.
|
|
1273
1223
|
|
|
1274
1224
|
@see: Methods L{RhumbLineAux.Intersecant2} and L{RhumbLine.Intersecant2}.
|
|
1275
1225
|
'''
|
|
@@ -1292,25 +1242,19 @@ class LatLonBase(_NamedBase):
|
|
|
1292
1242
|
**exact_radius_wrap_eps_tol)
|
|
1293
1243
|
|
|
1294
1244
|
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.
|
|
1245
|
+
'''Get a rhumb line through this point at a given azimuth or through this and an other point.
|
|
1297
1246
|
|
|
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}}.
|
|
1247
|
+
@arg other: The azimuth I{of} (compass C{degrees}) or an other point I{on} (same
|
|
1248
|
+
C{LatLon} class) the rhumb line.
|
|
1249
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1250
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1251
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's C{datum}.
|
|
1252
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1253
|
+
@kwarg name_caps: Optional C{B{name}=str} and C{caps}, see L{RhumbLine} or L{RhumbLineAux} C{B{caps}}.
|
|
1309
1254
|
|
|
1310
|
-
@return: A C{RhumbLine} instance.
|
|
1255
|
+
@return: A C{RhumbLine} instance (C{RhumbLine} or C{RhumbLineAux}).
|
|
1311
1256
|
|
|
1312
|
-
@raise TypeError: Invalid B{C{radius}} or B{C{other}} not C{scalar} nor
|
|
1313
|
-
same C{LatLon} class.
|
|
1257
|
+
@raise TypeError: Invalid B{C{radius}} or B{C{other}} not C{scalar} nor same C{LatLon} class.
|
|
1314
1258
|
|
|
1315
1259
|
@see: Modules L{rhumb.aux_} and L{rhumb.ekx}.
|
|
1316
1260
|
'''
|
|
@@ -1320,30 +1264,23 @@ class LatLonBase(_NamedBase):
|
|
|
1320
1264
|
r._InverseLine(self, self.others(other), wrap, **kwds)
|
|
1321
1265
|
return rl
|
|
1322
1266
|
|
|
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.
|
|
1267
|
+
def rhumbMidpointTo(self, other, exact=False, radius=None, height=None, fraction=_0_5, **wrap_name):
|
|
1268
|
+
'''Return the (loxodromic) midpoint on the rhumb line between this and an other point.
|
|
1327
1269
|
|
|
1328
1270
|
@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.
|
|
1271
|
+
@kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see method L{Ellipsoid.rhumb_}.
|
|
1272
|
+
@kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid},
|
|
1273
|
+
L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
|
|
1334
1274
|
@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}).
|
|
1275
|
+
@kwarg fraction: Midpoint location from this point (C{scalar}), 0 for this, 1 for the B{C{other}},
|
|
1276
|
+
0.5 for halfway between this and the B{C{other}} point, may be negative or
|
|
1277
|
+
greater than 1.
|
|
1278
|
+
@kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and C{B{wrap}=False}, if C{True}, wrap or
|
|
1279
|
+
I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1341
1280
|
|
|
1342
|
-
@return: The midpoint at the given B{C{fraction}} along the rhumb line
|
|
1343
|
-
(same C{LatLon} class).
|
|
1281
|
+
@return: The midpoint at the given B{C{fraction}} along the rhumb line (same C{LatLon} class).
|
|
1344
1282
|
|
|
1345
|
-
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}}
|
|
1346
|
-
is invalid.
|
|
1283
|
+
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
|
|
1347
1284
|
|
|
1348
1285
|
@raise ValueError: Invalid B{C{height}} or B{C{fraction}}.
|
|
1349
1286
|
'''
|
|
@@ -1369,8 +1306,7 @@ class LatLonBase(_NamedBase):
|
|
|
1369
1306
|
@kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
|
|
1370
1307
|
or I{normalize} and unroll the B{C{other}} point (C{bool}).
|
|
1371
1308
|
|
|
1372
|
-
@return: Distance (C{meter}, same units as the axes of this point's datum
|
|
1373
|
-
ellipsoid).
|
|
1309
|
+
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
|
|
1374
1310
|
|
|
1375
1311
|
@raise TypeError: The B{C{other}} point is not C{LatLon}.
|
|
1376
1312
|
|
|
@@ -1387,21 +1323,21 @@ class LatLonBase(_NamedBase):
|
|
|
1387
1323
|
return self.philam
|
|
1388
1324
|
|
|
1389
1325
|
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:
|
|
1326
|
+
'''Convert this point to cartesian, I{geocentric} coordinates, also known
|
|
1327
|
+
as I{Earth-Centered, Earth-Fixed} (ECEF).
|
|
1328
|
+
|
|
1329
|
+
@kwarg height: Optional height, overriding this point's height (C{meter},
|
|
1330
|
+
conventionally).
|
|
1331
|
+
@kwarg Cartesian: Optional class to return the geocentric coordinates
|
|
1332
|
+
(C{Cartesian}) or C{None}.
|
|
1333
|
+
@kwarg Cartesian_kwds: Optionally, additional B{C{Cartesian}} keyword
|
|
1398
1334
|
arguments, ignored if C{B{Cartesian} is None}.
|
|
1399
1335
|
|
|
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
|
-
|
|
1336
|
+
@return: A B{C{Cartesian}} instance or if B{C{Cartesian} is None}, an
|
|
1337
|
+
L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
|
|
1338
|
+
C{C=0} and C{M} if available.
|
|
1403
1339
|
|
|
1404
|
-
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}}.
|
|
1340
|
+
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}} item.
|
|
1405
1341
|
|
|
1406
1342
|
@see: Methods C{toNvector}, C{toVector} and C{toVector3d}.
|
|
1407
1343
|
'''
|
|
@@ -1434,12 +1370,12 @@ class LatLonBase(_NamedBase):
|
|
|
1434
1370
|
'''Convert this point to I{geocentric} coordinates, also known as
|
|
1435
1371
|
I{Earth-Centered, Earth-Fixed} (U{ECEF<https://WikiPedia.org/wiki/ECEF>}).
|
|
1436
1372
|
|
|
1437
|
-
@kwarg height: Optional height, overriding this point's height
|
|
1438
|
-
|
|
1373
|
+
@kwarg height: Optional height, overriding this point's height (C{meter},
|
|
1374
|
+
conventionally).
|
|
1439
1375
|
@kwarg M: Optionally, include the rotation L{EcefMatrix} (C{bool}).
|
|
1440
1376
|
|
|
1441
|
-
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
|
|
1442
|
-
|
|
1377
|
+
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
|
|
1378
|
+
C{C=0} and C{M} if available.
|
|
1443
1379
|
|
|
1444
1380
|
@raise EcefError: A C{.datum} or an ECEF issue.
|
|
1445
1381
|
'''
|
|
@@ -1452,45 +1388,15 @@ class LatLonBase(_NamedBase):
|
|
|
1452
1388
|
return self.latlonheight if height in (None, self.height) else \
|
|
1453
1389
|
self.latlon.to3Tuple(height)
|
|
1454
1390
|
|
|
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
1391
|
def toNormal(self, deep=False, **name):
|
|
1482
|
-
'''Get this point I{normalized} to C{abs(lat) <= 90}
|
|
1483
|
-
and C{abs(lon) <= 180}.
|
|
1392
|
+
'''Get this point I{normalized} to C{abs(lat) <= 90} and C{abs(lon) <= 180}.
|
|
1484
1393
|
|
|
1485
|
-
@kwarg deep: If C{True}, make a deep, otherwise a shallow
|
|
1486
|
-
copy (C{bool}).
|
|
1394
|
+
@kwarg deep: If C{True}, make a deep, otherwise a shallow copy (C{bool}).
|
|
1487
1395
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1488
1396
|
|
|
1489
|
-
@return: A copy of this point, I{normalized} (C{LatLon}),
|
|
1490
|
-
optionally renamed.
|
|
1397
|
+
@return: A copy of this point, I{normalized} (C{LatLon}), optionally renamed.
|
|
1491
1398
|
|
|
1492
|
-
@see: Property L{isnormal}, method L{normal} and function
|
|
1493
|
-
L{pygeodesy.normal}.
|
|
1399
|
+
@see: Property L{isnormal}, method L{normal} and function L{pygeodesy.normal}.
|
|
1494
1400
|
'''
|
|
1495
1401
|
ll = self.copy(deep=deep)
|
|
1496
1402
|
_ = ll.normal()
|
|
@@ -1499,18 +1405,18 @@ class LatLonBase(_NamedBase):
|
|
|
1499
1405
|
return ll
|
|
1500
1406
|
|
|
1501
1407
|
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
|
-
|
|
1408
|
+
'''Convert this point to C{n-vector} (normal to the earth's surface) components,
|
|
1409
|
+
I{including height}.
|
|
1504
1410
|
|
|
1505
1411
|
@kwarg h: Optional height, overriding this point's height (C{meter}).
|
|
1506
|
-
@kwarg Nvector: Optional class to return the C{n-vector} components
|
|
1507
|
-
|
|
1508
|
-
@kwarg name_Nvector_kwds: Optional C{B{name}=NN} (C{str}) and
|
|
1509
|
-
additional B{C{Nvector}} keyword arguments, ignored if
|
|
1510
|
-
|
|
1412
|
+
@kwarg Nvector: Optional class to return the C{n-vector} components (C{Nvector})
|
|
1413
|
+
or C{None}.
|
|
1414
|
+
@kwarg name_Nvector_kwds: Optional C{B{name}=NN} (C{str}) and optionally,
|
|
1415
|
+
additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector}
|
|
1416
|
+
is None}.
|
|
1511
1417
|
|
|
1512
|
-
@return: An
|
|
1513
|
-
|
|
1418
|
+
@return: An B{C{Nvector}} instance or a L{Vector4Tuple}C{(x, y, z, h)} if
|
|
1419
|
+
C{B{Nvector} is None}.
|
|
1514
1420
|
|
|
1515
1421
|
@raise TypeError: Invalid B{C{h}}, B{C{Nvector}} or B{C{name_Nvector_kwds}}.
|
|
1516
1422
|
|
|
@@ -1528,26 +1434,25 @@ class LatLonBase(_NamedBase):
|
|
|
1528
1434
|
return r
|
|
1529
1435
|
|
|
1530
1436
|
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}}.
|
|
1437
|
+
'''Convert this point to a "lat, lon[, +/-height]" string, formatted in the
|
|
1438
|
+
given C{B{form}at}.
|
|
1439
|
+
|
|
1440
|
+
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see functions
|
|
1441
|
+
L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
|
|
1442
|
+
@kwarg joined: Separator to join the lat-, longitude and height strings (C{str}
|
|
1443
|
+
or C{None} or C{NN} for non-joined).
|
|
1444
|
+
@kwarg m: Optional unit of the height (C{str}), use C{None} to exclude height
|
|
1445
|
+
from the returned string.
|
|
1446
|
+
@kwarg prec_sep_s_D_M_S: Optional C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}},
|
|
1447
|
+
B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}} keyword arguments, see function
|
|
1448
|
+
L{pygeodesy.toDMS} for details.
|
|
1449
|
+
|
|
1450
|
+
@return: This point in the specified C{B{form}at}, etc. (C{str} or a 2- or 3-tuple
|
|
1451
|
+
C{(lat_str, lon_str[, height_str])} if B{C{joined}} is C{NN} or C{None}).
|
|
1452
|
+
|
|
1453
|
+
@see: Function L{pygeodesy.latDMS} or L{pygeodesy.lonDMS} for more details about
|
|
1454
|
+
keyword arguments C{B{form}at}, C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}},
|
|
1455
|
+
B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}}.
|
|
1551
1456
|
'''
|
|
1552
1457
|
t = (latDMS(self.lat, form=form, **prec_sep_s_D_M_S),
|
|
1553
1458
|
lonDMS(self.lon, form=form, **prec_sep_s_D_M_S))
|
|
@@ -1556,16 +1461,16 @@ class LatLonBase(_NamedBase):
|
|
|
1556
1461
|
return joined.join(t) if joined else t
|
|
1557
1462
|
|
|
1558
1463
|
def toVector(self, Vector=None, **Vector_kwds):
|
|
1559
|
-
'''Convert this point to a C{Vector} with the I{geocentric} C{(x,
|
|
1560
|
-
|
|
1464
|
+
'''Convert this point to a C{Vector} with the I{geocentric} C{(x, y, z)} (ECEF)
|
|
1465
|
+
coordinates, I{ignoring height}.
|
|
1561
1466
|
|
|
1562
|
-
@kwarg Vector: Optional class to return the I{geocentric}
|
|
1563
|
-
|
|
1564
|
-
@kwarg Vector_kwds:
|
|
1565
|
-
|
|
1467
|
+
@kwarg Vector: Optional class to return the I{geocentric} components (L{Vector3d})
|
|
1468
|
+
or C{None}.
|
|
1469
|
+
@kwarg Vector_kwds: Optionally, additional B{C{Vector}} keyword arguments,
|
|
1470
|
+
ignored if C{B{Vector} is None}.
|
|
1566
1471
|
|
|
1567
|
-
@return: A
|
|
1568
|
-
|
|
1472
|
+
@return: A B{C{Vector}} instance or a L{Vector3Tuple}C{(x, y, z)} if C{B{Vector}
|
|
1473
|
+
is None}.
|
|
1569
1474
|
|
|
1570
1475
|
@raise TypeError: Invalid B{C{Vector}} or B{C{Vector_kwds}}.
|
|
1571
1476
|
|
|
@@ -1574,8 +1479,8 @@ class LatLonBase(_NamedBase):
|
|
|
1574
1479
|
return self._ecef9.toVector(Vector=Vector, **self._name1__(Vector_kwds))
|
|
1575
1480
|
|
|
1576
1481
|
def toVector3d(self, norm=True, **Vector3d_kwds):
|
|
1577
|
-
'''Convert this point to a L{Vector3d} with the I{geocentric} C{(x, y,
|
|
1578
|
-
|
|
1482
|
+
'''Convert this point to a L{Vector3d} with the I{geocentric} C{(x, y, z)}
|
|
1483
|
+
(ECEF) coordinates, I{ignoring height}.
|
|
1579
1484
|
|
|
1580
1485
|
@kwarg norm: If C{False}, don't normalize the coordinates (C{bool}).
|
|
1581
1486
|
@kwarg Vector3d_kwds: Optional L{Vector3d} keyword arguments.
|
|
@@ -1616,15 +1521,13 @@ class LatLonBase(_NamedBase):
|
|
|
1616
1521
|
# return _NamedBase._update(self, updated, *attrs, **setters)
|
|
1617
1522
|
|
|
1618
1523
|
def vincentysTo(self, other, **radius_wrap):
|
|
1619
|
-
'''Compute the distance between this and an other point using
|
|
1620
|
-
|
|
1621
|
-
spherical formula.
|
|
1524
|
+
'''Compute the distance between this and an other point using U{Vincenty's
|
|
1525
|
+
<https://WikiPedia.org/wiki/Great-circle_distance>} spherical formula.
|
|
1622
1526
|
|
|
1623
1527
|
@arg other: The other point (C{LatLon}).
|
|
1624
|
-
@kwarg radius_wrap: Optional
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
datum ellipsoid.
|
|
1528
|
+
@kwarg radius_wrap: Optional C{B{radius}=R_M} and C{B{wrap}=False} for
|
|
1529
|
+
function L{pygeodesy.vincentys}, overriding the default
|
|
1530
|
+
C{mean radius} of this point's datum ellipsoid.
|
|
1628
1531
|
|
|
1629
1532
|
@return: Distance (C{meter}, same units as B{C{radius}}).
|
|
1630
1533
|
|
|
@@ -1692,17 +1595,64 @@ def _latlonheight3(latlonh, height, wrap): # in .points.LatLon_.__init__
|
|
|
1692
1595
|
return lat, lon, height
|
|
1693
1596
|
|
|
1694
1597
|
|
|
1695
|
-
def
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1598
|
+
def latlon2n_xyz(lat_ll, lon=None, **name):
|
|
1599
|
+
'''Convert lat-, longitude to C{n-vector} (I{normal} to the earth's surface) X, Y and Z components.
|
|
1600
|
+
|
|
1601
|
+
@arg lat_ll: Latitude (C{degrees}) or a C{LatLon} instance, L{LatLon2Tuple} or other C{LatLon*Tuple}.
|
|
1602
|
+
@kwarg lon: Longitude (C{degrees}), required if C{B{lon_ll} is degrees}, ignored otherwise.
|
|
1603
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1604
|
+
|
|
1605
|
+
@return: A L{Vector3Tuple}C{(x, y, z)}.
|
|
1606
|
+
|
|
1607
|
+
@see: Function L{philam2n_xyz}.
|
|
1608
|
+
|
|
1609
|
+
@note: These are C{n-vector} x, y and z components, I{NOT geocentric} x, y and z (ECEF) coordinates!
|
|
1610
|
+
'''
|
|
1611
|
+
lat = lat_ll
|
|
1612
|
+
if lon is None:
|
|
1613
|
+
try:
|
|
1614
|
+
lat, lon = lat_ll.latlon
|
|
1615
|
+
except AttributeError:
|
|
1616
|
+
lat = lat_ll.lat
|
|
1617
|
+
lon = lat_ll.lon
|
|
1618
|
+
# Kenneth Gade eqn 3, but using right-handed
|
|
1619
|
+
# vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N
|
|
1620
|
+
sa, ca, sb, cb = sincos2d_(lat, lon)
|
|
1621
|
+
return Vector3Tuple(ca * cb, ca * sb, sa, **name)
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
def philam2n_xyz(phi_ll, lam=None, **name):
|
|
1625
|
+
'''Convert lat-, longitude to C{n-vector} (I{normal} to the earth's surface) X, Y and Z components.
|
|
1626
|
+
|
|
1627
|
+
@arg phi_ll: Latitude (C{radians}) or a C{LatLon} instance with C{phi}, C{lam} or C{philam} attributes.
|
|
1628
|
+
@kwarg lam: Longitude (C{radians}), required if C{B{phi_ll} is radians}, ignored otherwise.
|
|
1629
|
+
@kwarg name: Optional name (C{str}).
|
|
1630
|
+
|
|
1631
|
+
@return: A L{Vector3Tuple}C{(x, y, z)}.
|
|
1632
|
+
|
|
1633
|
+
@see: Function L{latlon2n_xyz}.
|
|
1634
|
+
|
|
1635
|
+
@note: These are C{n-vector} x, y and z components, I{NOT geocentric} x, y and z (ECEF) coordinates!
|
|
1636
|
+
'''
|
|
1637
|
+
phi = phi_ll
|
|
1638
|
+
if lam is None:
|
|
1639
|
+
try:
|
|
1640
|
+
phi, lam = phi_ll.philam
|
|
1641
|
+
except AttributeError:
|
|
1642
|
+
phi = phi_ll.phi
|
|
1643
|
+
lam = phi_ll.lam
|
|
1644
|
+
return latlon2n_xyz(degrees(phi), degrees(lam), **name)
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
def _trilaterate5(p1, d1, p2, d2, p3, d3, area=True, eps=EPS1, radius=R_M, wrap=False): # MCCABE 13
|
|
1648
|
+
'''(INTERNAL) Trilaterate three points by I{area overlap} or by I{perimeter intersection} of three circles.
|
|
1699
1649
|
|
|
1700
|
-
@note: The B{C{radius}} is only
|
|
1701
|
-
C{
|
|
1702
|
-
|
|
1703
|
-
C{-Karney} and C{-Vincenty.LatLon.distanceTo} methods.
|
|
1650
|
+
@note: The B{C{radius}} is needed only for C{n-vectorial} and C{sphericalTrigonometry.LatLon.distanceTo}
|
|
1651
|
+
methods and silently ignored by the C{ellipsoidalExact}, C{-GeodSolve}, C{-Karney} and
|
|
1652
|
+
C{-Vincenty.LatLon.distanceTo} methods.
|
|
1704
1653
|
'''
|
|
1705
1654
|
p2, p3, w = _unrollon3(p1, p2, p3, wrap)
|
|
1655
|
+
rw = dict(radius=radius, wrap=w)
|
|
1706
1656
|
|
|
1707
1657
|
r1 = Distance_(distance1=d1)
|
|
1708
1658
|
r2 = Distance_(distance2=d2)
|
|
@@ -1719,14 +1669,14 @@ def _trilaterate5(p1, d1, p2, d2, p3, d3, area=True, eps=EPS1, # MCCABE 13
|
|
|
1719
1669
|
c = c1
|
|
1720
1670
|
else: # nearest point on radical
|
|
1721
1671
|
c = p3.nearestOn(c1, c2, within=True, wrap=w)
|
|
1722
|
-
d = r3 - p3.distanceTo(c,
|
|
1672
|
+
d = r3 - p3.distanceTo(c, **rw)
|
|
1723
1673
|
if d > eps: # sufficient overlap
|
|
1724
1674
|
t.append((d, c))
|
|
1725
1675
|
m = max(m, d)
|
|
1726
1676
|
|
|
1727
1677
|
else: # check intersection
|
|
1728
1678
|
for c in ((c1,) if c1 is c2 else (c1, c2)):
|
|
1729
|
-
d = fabs(r3 - p3.distanceTo(c,
|
|
1679
|
+
d = fabs(r3 - p3.distanceTo(c, **rw))
|
|
1730
1680
|
if d < eps: # below margin
|
|
1731
1681
|
t.append((d, c))
|
|
1732
1682
|
m = min(m, d)
|
|
@@ -1760,7 +1710,7 @@ __all__ += _ALL_DOCS(LatLonBase)
|
|
|
1760
1710
|
|
|
1761
1711
|
# **) MIT License
|
|
1762
1712
|
#
|
|
1763
|
-
# Copyright (C) 2016-
|
|
1713
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1764
1714
|
#
|
|
1765
1715
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1766
1716
|
# copy of this software and associated documentation files (the "Software"),
|