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.
Files changed (118) hide show
  1. {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/METADATA +34 -35
  2. PyGeodesy-25.1.5.dist-info/RECORD +118 -0
  3. {PyGeodesy-24.11.11.dist-info → PyGeodesy-25.1.5.dist-info}/WHEEL +1 -1
  4. pygeodesy/__init__.py +19 -19
  5. pygeodesy/__main__.py +1 -1
  6. pygeodesy/albers.py +5 -5
  7. pygeodesy/auxilats/_CX_4.py +1 -1
  8. pygeodesy/auxilats/_CX_6.py +1 -1
  9. pygeodesy/auxilats/_CX_8.py +1 -1
  10. pygeodesy/auxilats/_CX_Rs.py +1 -1
  11. pygeodesy/auxilats/__init__.py +1 -1
  12. pygeodesy/auxilats/__main__.py +1 -1
  13. pygeodesy/auxilats/auxAngle.py +5 -5
  14. pygeodesy/auxilats/auxDLat.py +6 -6
  15. pygeodesy/auxilats/auxDST.py +2 -2
  16. pygeodesy/auxilats/auxLat.py +5 -5
  17. pygeodesy/auxilats/auxily.py +2 -2
  18. pygeodesy/azimuthal.py +5 -5
  19. pygeodesy/basics.py +60 -8
  20. pygeodesy/booleans.py +1 -1
  21. pygeodesy/cartesianBase.py +22 -61
  22. pygeodesy/clipy.py +1 -1
  23. pygeodesy/constants.py +5 -5
  24. pygeodesy/css.py +1 -1
  25. pygeodesy/datums.py +1 -1
  26. pygeodesy/deprecated/__init__.py +2 -2
  27. pygeodesy/deprecated/bases.py +1 -1
  28. pygeodesy/deprecated/classes.py +86 -2
  29. pygeodesy/deprecated/consterns.py +1 -1
  30. pygeodesy/deprecated/datum.py +5 -5
  31. pygeodesy/deprecated/functions.py +42 -8
  32. pygeodesy/deprecated/nvector.py +1 -1
  33. pygeodesy/deprecated/rhumbBase.py +1 -1
  34. pygeodesy/deprecated/rhumbaux.py +1 -1
  35. pygeodesy/deprecated/rhumbsolve.py +1 -1
  36. pygeodesy/deprecated/rhumbx.py +1 -1
  37. pygeodesy/dms.py +1 -1
  38. pygeodesy/ecef.py +53 -56
  39. pygeodesy/elevations.py +1 -1
  40. pygeodesy/ellipsoidalBase.py +3 -3
  41. pygeodesy/ellipsoidalBaseDI.py +1 -1
  42. pygeodesy/ellipsoidalExact.py +1 -1
  43. pygeodesy/ellipsoidalGeodSolve.py +1 -1
  44. pygeodesy/ellipsoidalKarney.py +1 -1
  45. pygeodesy/ellipsoidalNvector.py +1 -1
  46. pygeodesy/ellipsoidalVincenty.py +6 -5
  47. pygeodesy/ellipsoids.py +4 -5
  48. pygeodesy/elliptic.py +6 -6
  49. pygeodesy/epsg.py +1 -1
  50. pygeodesy/errors.py +1 -1
  51. pygeodesy/etm.py +5 -5
  52. pygeodesy/fmath.py +18 -17
  53. pygeodesy/formy.py +409 -555
  54. pygeodesy/frechet.py +29 -86
  55. pygeodesy/fstats.py +1 -1
  56. pygeodesy/fsums.py +32 -33
  57. pygeodesy/gars.py +1 -1
  58. pygeodesy/geodesici.py +7 -7
  59. pygeodesy/geodesicw.py +1 -1
  60. pygeodesy/geodesicx/_C4_24.py +2 -2
  61. pygeodesy/geodesicx/_C4_27.py +2 -2
  62. pygeodesy/geodesicx/_C4_30.py +2 -2
  63. pygeodesy/geodesicx/__init__.py +2 -2
  64. pygeodesy/geodesicx/__main__.py +4 -5
  65. pygeodesy/geodesicx/gx.py +6 -5
  66. pygeodesy/geodesicx/gxarea.py +2 -2
  67. pygeodesy/geodesicx/gxbases.py +2 -2
  68. pygeodesy/geodesicx/gxline.py +16 -12
  69. pygeodesy/geodsolve.py +1 -1
  70. pygeodesy/geohash.py +1 -1
  71. pygeodesy/geoids.py +277 -203
  72. pygeodesy/hausdorff.py +23 -81
  73. pygeodesy/heights.py +115 -150
  74. pygeodesy/internals.py +1 -1
  75. pygeodesy/interns.py +2 -3
  76. pygeodesy/iters.py +1 -1
  77. pygeodesy/karney.py +3 -3
  78. pygeodesy/ktm.py +16 -15
  79. pygeodesy/latlonBase.py +323 -409
  80. pygeodesy/lazily.py +53 -44
  81. pygeodesy/lcc.py +1 -1
  82. pygeodesy/ltp.py +46 -50
  83. pygeodesy/ltpTuples.py +147 -130
  84. pygeodesy/mgrs.py +1 -1
  85. pygeodesy/named.py +149 -3
  86. pygeodesy/namedTuples.py +58 -7
  87. pygeodesy/nvectorBase.py +122 -105
  88. pygeodesy/osgr.py +1 -1
  89. pygeodesy/points.py +1 -1
  90. pygeodesy/props.py +1 -1
  91. pygeodesy/resections.py +18 -17
  92. pygeodesy/rhumb/__init__.py +1 -1
  93. pygeodesy/rhumb/aux_.py +2 -2
  94. pygeodesy/rhumb/bases.py +2 -2
  95. pygeodesy/rhumb/ekx.py +4 -4
  96. pygeodesy/rhumb/solve.py +1 -1
  97. pygeodesy/simplify.py +289 -401
  98. pygeodesy/solveBase.py +1 -1
  99. pygeodesy/sphericalBase.py +1 -1
  100. pygeodesy/sphericalNvector.py +5 -5
  101. pygeodesy/sphericalTrigonometry.py +7 -6
  102. pygeodesy/streprs.py +10 -5
  103. pygeodesy/trf.py +1 -1
  104. pygeodesy/triaxials.py +23 -16
  105. pygeodesy/units.py +16 -16
  106. pygeodesy/unitsBase.py +1 -1
  107. pygeodesy/ups.py +4 -4
  108. pygeodesy/utily.py +341 -211
  109. pygeodesy/utm.py +5 -5
  110. pygeodesy/utmups.py +1 -1
  111. pygeodesy/utmupsBase.py +1 -1
  112. pygeodesy/vector2d.py +5 -5
  113. pygeodesy/vector3d.py +14 -3
  114. pygeodesy/vector3dBase.py +5 -5
  115. pygeodesy/webmercator.py +1 -1
  116. pygeodesy/wgrs.py +1 -1
  117. PyGeodesy-24.11.11.dist-info/RECORD +0 -118
  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
- # from pygeodesy.ltp import Ltp, _xLtp # _MODS
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, property_ROnce, _update_all
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.11.10'
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} points on spherical or
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, latlonh, lon=None, height=0, datum=None, **wrap_name):
70
+ def __init__(self, lat_llh, lon=None, height=0, datum=None, **wrap_name):
73
71
  '''New C{LatLon}.
74
72
 
75
- @arg latlonh: Latitude (C{degrees} or DMS C{str} with N or S suffix) or
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) or
78
- C(None), indicating B{C{latlonh}} is a C{LatLon}.
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{latlonh}} is not a C{LatLon}.
90
+ @raise TypeError: If B{C{lat_llh}} is not a C{LatLon}.
93
91
 
94
- @raise UnitError: Invalid B{C{lat}}, B{C{lon}} or B{C{height}}.
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(latlonh, height, w)
99
+ lat, lon, height = _latlonheight3(lat_llh, height, w)
102
100
  elif w:
103
- lat, lon = _Wrap.latlonDMS2(latlonh, lon)
101
+ lat, lon = _Wrap.latlonDMS2(lat_llh, lon)
104
102
  else:
105
- lat = latlonh
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
- '''Compute the distance between this and an other point using the U{Andoyer-Lambert correction<https://
369
- navlib.net/wp-content/uploads/2013/10/admiralty-manual-of-navigation-vol-1-1964-english501c.pdf>}
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
- '''Compute the distance between this and an other point using
391
- the U{Forsythe-Andoyer-Lambert correction
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
- @see: Function L{pygeodesy.cosineForsytheAndoyerLambert} and methods
406
- L{cosineAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
407
- L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo},
408
- L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}.
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 radius: Mean earth radius (C{meter}) or C{None} for the mean radius
420
- of this point's datum ellipsoid.
421
- @kwarg wrap: Optional keyword argument C{B{wrap}=False}, if C{True}, wrap
422
- or I{normalize} and unroll the B{C{other}} point (C{bool}).
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 L{cosineAndoyerLambertTo},
429
- L{cosineForsytheAndoyerLambertTo}, C{distanceTo*}, L{equirectangularTo},
430
- L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo},
431
- L{haversineTo}, L{thomasTo} and L{vincentysTo}.
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
- return self._distanceTo(_formy.cosineLaw, other, radius, **wrap)
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
- L{Ned} or L{Local9Tuple}).
445
- @kwarg LatLon: Optional (geodetic) class to return the destination
446
- or C{None}.
447
- @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
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: Destination as a C{B{LatLon}(lat, lon, **B{LatLon_kwds})}
451
- instance or if C{B{LatLon} is None}, a L{LatLon3Tuple}C{(lat,
452
- lon, height)} respectively L{LatLon4Tuple}C{(lat, lon,
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, r = self.others(other, up=2), radius
465
- if r is None:
466
- r = self._datum.ellipsoid.R1 if self._datum else R_M
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 if radius is None else radius)
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{cosineAndoyerLambertTo},
532
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
533
- C{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo},
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{cosineAndoyerLambertTo},
554
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
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{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo},
580
- L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo},
581
- L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo} and
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 keyword arguments for function
596
- L{pygeodesy.flatPolar}, overriding the
597
- default mean C{radius} of this point's
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{cosineAndoyerLambertTo},
605
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
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 to
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
- U{Haversine<https://www.Movable-Type.co.UK/scripts/latlong.html>}
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 keyword arguments for function
642
- L{pygeodesy.haversine}, overriding the
643
- default mean C{radius} of this point's
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{cosineAndoyerLambertTo},
651
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
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
- the overriding height B{C{h}} (C{Height}).
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
- datum (C{LatLon}) or C{None}.
707
- @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments,
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: An instance of class B{C{LatLon}} or if C{B{LatLon} is None}, a
714
- L{Vector4Tuple}C{(x, y, z, h)} with the I{projection} C{x}, C{y}
715
- and C{z} coordinates and height C{h} in C{meter}, conventionally.
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{earth}} or triaxial B{C{earth}} couldn't be
720
- converted to biaxial B{C{LatLon}} datum.
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 intercant points accordingly.
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
- on diametrically opposite sides of the earth.
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
- tolerance, C{False} otherwise.
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
- I{ignoring} height, C{False} otherwise.
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
- or mismatch of the B{C{other}} and
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
- height, C{False} otherwise.
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
- or mismatch of the B{C{other}} and this
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
- (2- or 3-tuple or comma- or space-separated C{str}
884
- of C{degrees90}, C{degrees180} and C{meter}).
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
- B{C{latlonh}} not C{list} or C{tuple}.
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
- string into a 3-tuple C{(lat, lon, h)}.
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
- and rounded away from zero.
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
- if B{C{ndigits}} is omitted.
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
- I{geocentric}, cartesian space.
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
- this and all other points (C{meter}). If
980
- C{None}, take the height of points into
981
- account for distances.
982
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll
983
- the B{C{points}} (C{bool}).
984
-
985
- @return: A L{NearestOn6Tuple}C{(closest, distance, fi, j,
986
- start, end)} with the C{closest}, the C{start}
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 _formy.philam2n_xyz(self.phi, self.lam, name=self.name)
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
- and rounded away from zero.
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 always C{float}, also
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
- ignoring any duplicate or closing final
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
- and C{list} or C{tuple}.
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
- enum-/iterated B{C{points}} (C{bool}).
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
- and an other (ellipsoidal) point.
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
- method L{Ellipsoid.rhumb_}.
1178
- @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum},
1179
- L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding
1180
- this point's datum.
1181
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll the B{C{other}}
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
- exact=False, **name):
1197
- '''Return the destination point having travelled the given distance from
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
- datum (ellipsoid) axes or B{C{radius}}, may be negative.
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{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding
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
- method L{Ellipsoid.rhumb_}.
1230
- @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum},
1231
- L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding
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
- points or as a point and azimuth.
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
- or a point on the circle (same C{LatLon} class).
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
- I{of} (compass C{degrees}) the rhumb line.
1257
- @kwarg height: Optional height for the intersection points (C{meter},
1258
- conventionally) or C{None} for interpolated heights.
1259
- @kwarg exact_radius_wrap_eps_tol: Optional keyword arguments, see
1260
- methods L{rhumbLine} and L{RhumbLineAux.Intersecant2}
1261
- or L{RhumbLine.Intersecant2}.
1262
-
1263
- @return: 2-Tuple of the intersection points (representing a chord),
1264
- each an instance of this class. Both points are the same
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
- I{on} (same C{LatLon} class) the rhumb line.
1300
- @kwarg exact: Exact C{Rhumb...} to use (C{bool} or C{Rhumb...}), see
1301
- method L{Ellipsoid.rhumb_}.
1302
- @kwarg radius: Optional earth radius (C{meter}) or earth model
1303
- (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}),
1304
- overriding this point's datum.
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
- height=None, fraction=_0_5, **wrap_name):
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
- method L{Ellipsoid.rhumb_}.
1331
- @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum},
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
- 1 for the B{C{other}}, 0.5 for halfway between this and
1337
- the B{C{other}} point, may be negative or greater than 1.
1338
- @kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and optional keyword
1339
- argument C{B{wrap}=False}, if C{True}, wrap or I{normalize}
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{cosineAndoyerLambertTo},
1378
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
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
- also known as I{Earth-Centered, Earth-Fixed} (ECEF).
1392
-
1393
- @kwarg height: Optional height, overriding this point's height
1394
- (C{meter}, conventionally).
1395
- @kwarg Cartesian: Optional class to return the geocentric
1396
- coordinates (C{Cartesian}) or C{None}.
1397
- @kwarg Cartesian_kwds: Optional, additional B{C{Cartesian}} keyword
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
- with C{C=0} and C{M} if available.
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
- (C{meter}, conventionally).
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
- with C{C=0} and C{M} if available.
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
- components, I{including height}.
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
- (C{Nvector}) or C{None}.
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 named B{C{Nvector}} or if C{B{Nvector} is None} a named
1513
- L{Vector4Tuple}C{(x, y, z, h)}.
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
- in the given C{B{form}at}.
1533
-
1534
- @kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see
1535
- functions L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
1536
- @kwarg joined: Separator to join the lat-, longitude and height
1537
- strings (C{str} or C{None} or C{NN} for non-joined).
1538
- @kwarg m: Optional unit of the height (C{str}), use C{None} to
1539
- exclude height from the returned string.
1540
- @kwarg prec_sep_s_D_M_S: Optional C{B{prec}ision}, C{B{sep}arator},
1541
- B{C{s_D}}, B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}} keyword
1542
- arguments, see function L{pygeodesy.toDMS} for details.
1543
-
1544
- @return: This point in the specified C{B{form}at}, etc. (C{str} or
1545
- a 2- or 3-tuple C{(lat_str, lon_str[, height_str])} if
1546
- B{C{joined}} is C{NN} or C{None}).
1547
-
1548
- @see: Function L{pygeodesy.latDMS} or L{pygeodesy.lonDMS} for more
1549
- details about keyword arguments C{B{form}at}, C{B{prec}ision},
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
- y, z)} (ECEF) coordinates, I{ignoring height}.
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
- components (L{Vector3d}) or C{None}.
1564
- @kwarg Vector_kwds: Optional, additional B{C{Vector}} keyword
1565
- arguments, ignored if C{B{Vector} is None}.
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 named B{C{Vector}} or if C{B{Vector} is None} a
1568
- named L{Vector3Tuple}C{(x, y, z)}.
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
- z)} (ECEF) coordinates, I{ignoring height}.
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
- U{Vincenty's<https://WikiPedia.org/wiki/Great-circle_distance>}
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 keyword arguments for function
1625
- L{pygeodesy.vincentys}, overriding the
1626
- default mean C{radius} of this point's
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{cosineAndoyerLambertTo},
1634
- L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*},
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 _trilaterate5(p1, d1, p2, d2, p3, d3, area=True, eps=EPS1, # MCCABE 13
1696
- radius=R_M, wrap=False):
1697
- '''(INTERNAL) Trilaterate three points by I{area overlap} or by
1698
- I{perimeter intersection} of three circles.
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 needed for the n-vectorial and
1701
- C{sphericalTrigonometry.LatLon.distanceTo} methods and
1702
- silently ignored by the C{ellipsoidalExact}, C{-GeodSolve},
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, radius=radius, wrap=w)
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, radius=radius, wrap=w))
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-2024 -- mrJean1 at Gmail -- All Rights Reserved.
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"),