pygeodesy 24.5.15__py2.py3-none-any.whl → 24.6.1__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 (90) hide show
  1. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
  2. PyGeodesy-24.6.1.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +4 -4
  4. pygeodesy/albers.py +41 -41
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/__main__.py +2 -2
  7. pygeodesy/auxilats/auxAngle.py +32 -31
  8. pygeodesy/auxilats/auxLat.py +80 -51
  9. pygeodesy/azimuthal.py +123 -124
  10. pygeodesy/basics.py +46 -10
  11. pygeodesy/booleans.py +13 -14
  12. pygeodesy/cartesianBase.py +25 -23
  13. pygeodesy/clipy.py +3 -3
  14. pygeodesy/constants.py +3 -3
  15. pygeodesy/css.py +50 -42
  16. pygeodesy/datums.py +42 -41
  17. pygeodesy/deprecated/functions.py +9 -3
  18. pygeodesy/dms.py +6 -6
  19. pygeodesy/ecef.py +41 -41
  20. pygeodesy/ellipsoidalBase.py +41 -41
  21. pygeodesy/ellipsoidalBaseDI.py +3 -4
  22. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  23. pygeodesy/ellipsoidalKarney.py +3 -3
  24. pygeodesy/ellipsoidalNvector.py +11 -12
  25. pygeodesy/ellipsoids.py +45 -38
  26. pygeodesy/elliptic.py +3 -4
  27. pygeodesy/epsg.py +4 -3
  28. pygeodesy/errors.py +52 -20
  29. pygeodesy/etm.py +68 -65
  30. pygeodesy/fmath.py +44 -49
  31. pygeodesy/formy.py +129 -115
  32. pygeodesy/frechet.py +118 -103
  33. pygeodesy/fstats.py +21 -14
  34. pygeodesy/fsums.py +124 -80
  35. pygeodesy/gars.py +10 -9
  36. pygeodesy/geodesicw.py +19 -17
  37. pygeodesy/geodesicx/__init__.py +1 -1
  38. pygeodesy/geodesicx/__main__.py +2 -2
  39. pygeodesy/geodesicx/gx.py +39 -33
  40. pygeodesy/geodesicx/gxarea.py +12 -9
  41. pygeodesy/geodesicx/gxbases.py +3 -4
  42. pygeodesy/geodesicx/gxline.py +6 -8
  43. pygeodesy/geodsolve.py +29 -28
  44. pygeodesy/geohash.py +60 -57
  45. pygeodesy/geoids.py +34 -32
  46. pygeodesy/hausdorff.py +114 -101
  47. pygeodesy/heights.py +137 -130
  48. pygeodesy/internals.py +16 -11
  49. pygeodesy/interns.py +3 -6
  50. pygeodesy/iters.py +19 -17
  51. pygeodesy/karney.py +21 -17
  52. pygeodesy/ktm.py +25 -18
  53. pygeodesy/latlonBase.py +12 -11
  54. pygeodesy/lazily.py +6 -6
  55. pygeodesy/lcc.py +24 -25
  56. pygeodesy/ltp.py +143 -113
  57. pygeodesy/ltpTuples.py +207 -150
  58. pygeodesy/mgrs.py +26 -26
  59. pygeodesy/named.py +172 -90
  60. pygeodesy/namedTuples.py +33 -25
  61. pygeodesy/nvectorBase.py +8 -8
  62. pygeodesy/osgr.py +40 -48
  63. pygeodesy/points.py +18 -18
  64. pygeodesy/props.py +29 -16
  65. pygeodesy/rhumb/__init__.py +1 -1
  66. pygeodesy/rhumb/aux_.py +13 -15
  67. pygeodesy/rhumb/bases.py +12 -5
  68. pygeodesy/rhumb/ekx.py +24 -18
  69. pygeodesy/rhumb/solve.py +13 -10
  70. pygeodesy/simplify.py +16 -16
  71. pygeodesy/solveBase.py +18 -18
  72. pygeodesy/sphericalBase.py +17 -21
  73. pygeodesy/sphericalTrigonometry.py +21 -21
  74. pygeodesy/streprs.py +5 -5
  75. pygeodesy/trf.py +13 -11
  76. pygeodesy/triaxials.py +68 -64
  77. pygeodesy/units.py +35 -35
  78. pygeodesy/unitsBase.py +24 -11
  79. pygeodesy/ups.py +66 -70
  80. pygeodesy/utily.py +3 -3
  81. pygeodesy/utm.py +183 -187
  82. pygeodesy/utmups.py +38 -38
  83. pygeodesy/utmupsBase.py +104 -106
  84. pygeodesy/vector2d.py +6 -7
  85. pygeodesy/vector3d.py +16 -17
  86. pygeodesy/vector3dBase.py +4 -5
  87. pygeodesy/webmercator.py +43 -51
  88. PyGeodesy-24.5.15.dist-info/RECORD +0 -116
  89. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
  90. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/formy.py CHANGED
@@ -8,7 +8,7 @@ from __future__ import division as _; del _ # PYCHOK semicolon
8
8
 
9
9
  # from pygeodesy.cartesianBase import CartesianBase # _MODS
10
10
  from pygeodesy.constants import EPS, EPS0, EPS1, PI, PI2, PI3, PI_2, R_M, \
11
- _umod_PI2, float0_, isnon0, remainder, \
11
+ _0_0s, float0_, isnon0, remainder, _umod_PI2, \
12
12
  _0_0, _0_125, _0_25, _0_5, _1_0, _2_0, _4_0, \
13
13
  _32_0, _90_0, _180_0, _360_0
14
14
  from pygeodesy.datums import Datum, Ellipsoid, _ellipsoidal_datum, \
@@ -16,16 +16,18 @@ from pygeodesy.datums import Datum, Ellipsoid, _ellipsoidal_datum, \
16
16
  # from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # from .datums
17
17
  from pygeodesy.errors import IntersectionError, LimitError, limiterrors, \
18
18
  _TypeError, _ValueError, _xattr, _xError, \
19
- _xkwds, _xkwds_pop2
19
+ _xcallable,_xkwds, _xkwds_pop2
20
20
  from pygeodesy.fmath import euclid, hypot, hypot2, sqrt0
21
- from pygeodesy.fsums import fsumf_
22
- from pygeodesy.interns import NN, _delta_, _distant_, _inside_, _SPACE_, _too_
21
+ from pygeodesy.fsums import fsumf_, Fmt, unstr
22
+ # from pygeodesy.internals import _dunder_nameof # from .named
23
+ from pygeodesy.interns import _delta_, _distant_, _inside_, _SPACE_, _too_
23
24
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
24
- from pygeodesy.named import _NamedTuple, _xnamed, Fmt, unstr
25
- from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, Intersection3Tuple, \
26
- LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
27
- # from pygeodesy.streprs import Fmt, unstr # from .named
28
- # from pygeodesy.triaxials import _hartzell2 # _MODS
25
+ from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed, \
26
+ _dunder_nameof
27
+ from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
28
+ Intersection3Tuple, PhiLam2Tuple, Vector3Tuple
29
+ # from pygeodesy.streprs import Fmt, unstr # from .fsums
30
+ # from pygeodesy.triaxials import _hartzell3 # _MODS
29
31
  from pygeodesy.units import _isHeight, _isRadius, Bearing, Degrees_, Distance, \
30
32
  Distance_, Height, Lam_, Lat, Lon, Meter_, Phi_, \
31
33
  Radians, Radians_, Radius, Radius_, Scalar, _100km
@@ -40,7 +42,7 @@ from contextlib import contextmanager
40
42
  from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
41
43
 
42
44
  __all__ = _ALL_LAZY.formy
43
- __version__ = '24.02.18'
45
+ __version__ = '24.05.28'
44
46
 
45
47
  _RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
46
48
  _ratio_ = 'ratio'
@@ -59,36 +61,36 @@ def _anti2(a, b, n_2, n, n2):
59
61
  return float0_(r, b)
60
62
 
61
63
 
62
- def antipode(lat, lon, name=NN):
64
+ def antipode(lat, lon, **name):
63
65
  '''Return the antipode, the point diametrically opposite
64
66
  to a given point in C{degrees}.
65
67
 
66
68
  @arg lat: Latitude (C{degrees}).
67
69
  @arg lon: Longitude (C{degrees}).
68
- @kwarg name: Optional name (C{str}).
70
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
69
71
 
70
72
  @return: A L{LatLon2Tuple}C{(lat, lon)}.
71
73
 
72
74
  @see: Functions L{antipode_} and L{normal} and U{Geosphere
73
75
  <https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
74
76
  '''
75
- return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), name=name)
77
+ return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), **name)
76
78
 
77
79
 
78
- def antipode_(phi, lam, name=NN):
80
+ def antipode_(phi, lam, **name):
79
81
  '''Return the antipode, the point diametrically opposite
80
82
  to a given point in C{radians}.
81
83
 
82
84
  @arg phi: Latitude (C{radians}).
83
85
  @arg lam: Longitude (C{radians}).
84
- @kwarg name: Optional name (C{str}).
86
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
85
87
 
86
88
  @return: A L{PhiLam2Tuple}C{(phi, lam)}.
87
89
 
88
90
  @see: Functions L{antipode} and L{normal_} and U{Geosphere
89
91
  <https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
90
92
  '''
91
- return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), name=name)
93
+ return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), **name)
92
94
 
93
95
 
94
96
  def bearing(lat1, lon1, lat2, lon2, **final_wrap):
@@ -118,16 +120,17 @@ def bearing_(phi1, lam1, phi2, lam2, final=False, wrap=False):
118
120
  @arg lam1: Start longitude (C{radians}).
119
121
  @arg phi2: End latitude (C{radians}).
120
122
  @arg lam2: End longitude (C{radians}).
121
- @kwarg final: Return final bearing if C{True}, initial otherwise (C{bool}).
122
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}} and
123
- B{C{lam2}} (C{bool}).
123
+ @kwarg final: If C{True}, return the final, otherwise the initial
124
+ bearing (C{bool}).
125
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}}
126
+ and B{C{lam2}} (C{bool}).
124
127
 
125
- @return: Initial or final bearing (compass C{radiansPI2}) or zero if start
126
- and end point coincide.
128
+ @return: Initial or final bearing (compass C{radiansPI2}) or zero if
129
+ start and end point coincide.
127
130
 
128
- @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>}, U{Course
129
- between two points<https://www.EdWilliams.org/avform147.htm#Crs>} and
130
- U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
131
+ @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>},
132
+ U{Course between two points<https://www.EdWilliams.org/avform147.htm#Crs>}
133
+ and U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
131
134
  https://MathForum.org/library/drmath/view/55417.html>}.
132
135
  '''
133
136
  db, phi2, lam2 = _Wrap.philam3(lam1, phi2, lam2, wrap)
@@ -154,7 +157,7 @@ def _bearingTo2(p1, p2, wrap=False): # for points.ispolar, sphericalTrigonometr
154
157
  t = p1.philam + p2.philam
155
158
  return Bearing2Tuple(degrees(bearing_(*t, final=False, wrap=wrap)),
156
159
  degrees(bearing_(*t, final=True, wrap=wrap)),
157
- name=_bearingTo2.__name__)
160
+ name__=_bearingTo2)
158
161
 
159
162
 
160
163
  def compassAngle(lat1, lon1, lat2, lon2, adjust=True, wrap=False):
@@ -229,8 +232,8 @@ def cosineAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
229
232
  @raise TypeError: Invalid B{C{datum}}.
230
233
 
231
234
  @see: Functions L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert_},
232
- L{cosineLaw_}, L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
233
- L{flatPolar_}, L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
235
+ L{cosineLaw_}, L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
236
+ L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
234
237
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/Distance/
235
238
  AndoyerLambert.php>}.
236
239
  '''
@@ -295,8 +298,8 @@ def cosineForsytheAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
295
298
  @raise TypeError: Invalid B{C{datum}}.
296
299
 
297
300
  @see: Functions L{cosineForsytheAndoyerLambert}, L{cosineAndoyerLambert_},
298
- L{cosineLaw_}, L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
299
- L{flatPolar_}, L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
301
+ L{cosineLaw_}, L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
302
+ L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
300
303
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
301
304
  Distance/ForsytheCorrection.php>}.
302
305
  '''
@@ -363,9 +366,9 @@ def cosineLaw_(phi2, phi1, lam21):
363
366
  @return: Angular distance (C{radians}).
364
367
 
365
368
  @see: Functions L{cosineLaw}, L{cosineAndoyerLambert_},
366
- L{cosineForsytheAndoyerLambert_}, L{equirectangular_},
367
- L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
368
- L{haversine_}, L{thomas_} and L{vincentys_}.
369
+ L{cosineForsytheAndoyerLambert_}, L{euclidean_},
370
+ L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
371
+ L{thomas_} and L{vincentys_}.
369
372
 
370
373
  @note: See note at function L{vincentys_}.
371
374
  '''
@@ -416,7 +419,7 @@ def _ellipsoidal(earth, where):
416
419
  return _EWGS84 if earth in (_WGS84, _EWGS84) else (
417
420
  earth if isinstance(earth, Ellipsoid) else
418
421
  (earth if isinstance(earth, Datum) else # PYCHOK indent
419
- _ellipsoidal_datum(earth, name=where.__name__)).ellipsoid)
422
+ _ellipsoidal_datum(earth, name__=where)).ellipsoid)
420
423
 
421
424
 
422
425
  def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
@@ -427,35 +430,31 @@ def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
427
430
  @arg lon1: Start longitude (C{degrees}).
428
431
  @arg lat2: End latitude (C{degrees}).
429
432
  @arg lon2: End longitude (C{degrees}).
430
- @kwarg radius: Mean earth radius (C{meter}), datum (L{Datum})
431
- or ellipsoid (L{Ellipsoid}, L{Ellipsoid2} or
432
- L{a_f2Tuple}).
433
- @kwarg adjust_limit_wrap: Optional keyword arguments for
434
- function L{equirectangular_}.
433
+ @kwarg radius: Mean earth radius (C{meter}), datum (L{Datum}) or ellipsoid
434
+ (L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}).
435
+ @kwarg adjust_limit_wrap: Optional keyword arguments for function L{equirectangular4}.
435
436
 
436
- @return: Distance (C{meter}, same units as B{C{radius}} or
437
- the ellipsoid or datum axes).
437
+ @return: Distance (C{meter}, same units as B{C{radius}} or the ellipsoid or datum axes).
438
438
 
439
439
  @raise TypeError: Invalid B{C{radius}}.
440
440
 
441
- @see: Function L{equirectangular_} for more details, the
442
- available B{C{options}}, errors, restrictions and other,
443
- approximate or accurate distance functions.
441
+ @see: Function L{equirectangular4} for more details, the available B{C{options}},
442
+ errors, restrictions and other, approximate or accurate distance functions.
444
443
  '''
445
- d = sqrt(equirectangular_(Lat(lat1=lat1), Lon(lon1=lon1),
444
+ d = sqrt(equirectangular4(Lat(lat1=lat1), Lon(lon1=lon1),
446
445
  Lat(lat2=lat2), Lon(lon2=lon2),
447
446
  **adjust_limit_wrap).distance2) # PYCHOK 4 vs 2-3
448
447
  return degrees2m(d, radius=_mean_radius(radius, lat1, lat2))
449
448
 
450
449
 
451
450
  def _equirectangular(lat1, lon1, lat2, lon2, **adjust_limit_wrap):
452
- '''(INTERNAL) Helper for the L{frechet._FrecherMeterRadians}
451
+ '''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
453
452
  and L{hausdorff._HausdorffMeterRedians} classes.
454
453
  '''
455
- return equirectangular_(lat1, lon1, lat2, lon2, **adjust_limit_wrap).distance2 * _RADIANS2
454
+ return equirectangular4(lat1, lon1, lat2, lon2, **adjust_limit_wrap).distance2 * _RADIANS2
456
455
 
457
456
 
458
- def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
457
+ def equirectangular4(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
459
458
  '''Compute the distance between two points using the U{Equirectangular Approximation
460
459
  / Projection<https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}.
461
460
 
@@ -466,15 +465,15 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
466
465
  @arg lon1: Start longitude (C{degrees}).
467
466
  @arg lat2: End latitude (C{degrees}).
468
467
  @arg lon2: End longitude (C{degrees}).
469
- @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta
470
- by the cosine of the mean latitude (C{bool}).
471
- @kwarg limit: Optional limit for lat- and longitudinal deltas
472
- (C{degrees}) or C{None} or C{0} for unlimited.
473
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}}
474
- and B{C{lon2}} (C{bool}).
468
+ @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine
469
+ of the mean latitude (C{bool}).
470
+ @kwarg limit: Optional limit for lat- and longitudinal deltas (C{degrees}) or
471
+ C{None} or C{0} for unlimited.
472
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and
473
+ B{C{lon2}} (C{bool}).
475
474
 
476
- @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon,
477
- unroll_lon2)} in C{degrees squared}.
475
+ @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon, unroll_lon2)}
476
+ in C{degrees squared}.
478
477
 
479
478
  @raise LimitError: If the lat- and/or longitudinal delta exceeds the
480
479
  B{C{-limit..limit}} range and L{pygeodesy.limiterrors}
@@ -495,7 +494,7 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
495
494
  d = max(fabs(d_lat), fabs(d_lon))
496
495
  if d > limit:
497
496
  t = _SPACE_(_delta_, Fmt.PAREN_g(d), Fmt.exceeds_limit(limit))
498
- s = unstr(equirectangular_, lat1, lon1, lat2, lon2,
497
+ s = unstr(equirectangular4, lat1, lon1, lat2, lon2,
499
498
  limit=limit, wrap=wrap)
500
499
  raise LimitError(s, txt=t)
501
500
 
@@ -548,9 +547,9 @@ def euclidean_(phi2, phi1, lam21, adjust=True):
548
547
  @return: Angular distance (C{radians}).
549
548
 
550
549
  @see: Functions L{euclid}, L{euclidean}, L{cosineAndoyerLambert_},
551
- L{cosineForsytheAndoyerLambert_}, L{cosineLaw_}, L{equirectangular_},
552
- L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_}, L{thomas_}
553
- and L{vincentys_}.
550
+ L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
551
+ L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
552
+ L{thomas_} and L{vincentys_}.
554
553
  '''
555
554
  if adjust:
556
555
  lam21 *= _scale_rad(phi2, phi1)
@@ -863,8 +862,8 @@ def flatLocal_(phi2, phi1, lam21, datum=_WGS84, scaled=True):
863
862
 
864
863
  @see: Functions L{flatLocal} or L{hubeny}, L{cosineAndoyerLambert_},
865
864
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_}, L{flatPolar_},
866
- L{equirectangular_}, L{euclidean_}, L{haversine_}, L{thomas_}
867
- and L{vincentys_} and U{local, flat earth approximation
865
+ L{euclidean_}, L{haversine_}, L{thomas_} and L{vincentys_} and
866
+ U{local, flat earth approximation
868
867
  <https://www.EdWilliams.org/avform.htm#flat>}.
869
868
  '''
870
869
  E = _ellipsoidal(datum, flatLocal_)
@@ -917,8 +916,8 @@ def flatPolar_(phi2, phi1, lam21):
917
916
 
918
917
  @see: Functions L{flatPolar}, L{cosineAndoyerLambert_},
919
918
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
920
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
921
- L{haversine_}, L{thomas_} and L{vincentys_}.
919
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{haversine_},
920
+ L{thomas_} and L{vincentys_}.
922
921
  '''
923
922
  a = fabs(PI_2 - phi1) # co-latitude
924
923
  b = fabs(PI_2 - phi2) # co-latitude
@@ -940,7 +939,7 @@ def _hartzell(pov, los, earth, **kwds):
940
939
  if earth is None:
941
940
  earth = pov.datum
942
941
  else:
943
- earth = _spherical_datum(earth, name=hartzell.__name__)
942
+ earth = _spherical_datum(earth, name__=hartzell)
944
943
  pov = pov.toDatum(earth)
945
944
  h = pov.height
946
945
  if h < 0: # EPS0
@@ -949,26 +948,25 @@ def _hartzell(pov, los, earth, **kwds):
949
948
  return hartzell(pov, los=los, earth=earth, **kwds) if h > 0 else pov # EPS0
950
949
 
951
950
 
952
- def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
951
+ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
953
952
  '''Compute the intersection of the earth's surface and a Line-Of-Sight from
954
953
  a Point-Of-View in space.
955
954
 
956
955
  @arg pov: Point-Of-View outside the earth (C{LatLon}, C{Cartesian},
957
956
  L{Ecef9Tuple} or L{Vector3d}).
958
957
  @kwarg los: Line-Of-Sight, I{direction} to earth (L{Los}, L{Vector3d}),
959
- C{True} for the I{normal, plumb} onto the surface or
960
- C{False} or C{None} to point to the center of the earth.
958
+ C{True} for the I{normal, plumb} onto the surface or C{False}
959
+ or C{None} to point to the center of the earth.
961
960
  @kwarg earth: The earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
962
961
  L{a_f2Tuple} or a C{scalar} earth radius in C{meter}).
963
- @kwarg name: Optional name (C{str}).
964
- @kwarg LatLon_and_kwds: Optional C{B{LatLon}=None} class to return the
965
- intersection plus additional C{LatLon} keyword
966
- arguments, include B{C{datum}} if different
967
- from B{C{earth}}.
962
+ @kwarg name_LatLon_and_kwds: Optional, overriding C{B{name}="hartzell"}
963
+ (C{str}), class C{B{LatLon}=None} to return the intersection
964
+ plus additional C{LatLon} keyword arguments, include the
965
+ B{C{datum}} if different and to convert from B{C{earth}}.
968
966
 
969
- @return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or
970
- the given B{C{LatLon}} instance) with attribute C{heigth} set
971
- to the distance to the B{C{pov}}.
967
+ @return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or the
968
+ given B{C{LatLon}} instance) with attribute C{heigth} set to the
969
+ distance to the B{C{pov}}.
972
970
 
973
971
  @raise IntersectionError: Invalid B{C{pov}} or B{C{pov}} inside the earth or
974
972
  invalid B{C{los}} or B{C{los}} points outside or
@@ -979,23 +977,23 @@ def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
979
977
  @see: Class L{Los}, functions L{tyr3d} and L{hartzell4} and methods
980
978
  L{Ellipsoid.hartzell4} and any C{Cartesian.hartzell} and C{LatLon.hartzell}.
981
979
  '''
982
- n = hartzell.__name__
983
- D = earth if isinstance(earth, Datum) else _spherical_datum(earth, name=n)
980
+ n, LatLon_and_kwds = _name2__(name_LatLon_and_kwds, name__=hartzell)
984
981
  try:
982
+ D = _spherical_datum(earth, name__=hartzell)
985
983
  r, h, i = _MODS.triaxials._hartzell3(pov, los, D.ellipsoid._triaxial)
986
984
 
987
- r = _xnamed(r, name or n)
988
985
  C = _MODS.cartesianBase.CartesianBase
989
986
  if LatLon_and_kwds:
990
- c = C(r, datum=D, name=r.name)
987
+ c = C(r, datum=D)
991
988
  r = c.toLatLon(**_xkwds(LatLon_and_kwds, height=h))
992
989
  elif isinstance(r, C):
993
990
  r.height = h
994
991
  if i:
995
992
  r._iteration = i
996
993
  except Exception as x:
997
- raise IntersectionError(pov=pov, los=los, earth=earth, cause=x, **LatLon_and_kwds)
998
- return r
994
+ raise IntersectionError(pov=pov, los=los, earth=earth, cause=x,
995
+ **LatLon_and_kwds)
996
+ return _xnamed(r, n) if n else r
999
997
 
1000
998
 
1001
999
  def haversine(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
@@ -1042,8 +1040,8 @@ def haversine_(phi2, phi1, lam21):
1042
1040
 
1043
1041
  @see: Functions L{haversine}, L{cosineAndoyerLambert_},
1044
1042
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1045
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1046
- L{flatPolar_}, L{thomas_} and L{vincentys_}.
1043
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
1044
+ L{thomas_} and L{vincentys_}.
1047
1045
 
1048
1046
  @note: See note at function L{vincentys_}.
1049
1047
  '''
@@ -1108,8 +1106,8 @@ def heightOrthometric(h_ll, N):
1108
1106
 
1109
1107
 
1110
1108
  def horizon(height, radius=R_M, refraction=False):
1111
- '''Determine the distance to the horizon from a given altitude
1112
- above the (spherical) earth.
1109
+ '''Determine the distance to the horizon from a given altitude above the
1110
+ (spherical) earth.
1113
1111
 
1114
1112
  @arg height: Altitude (C{meter} or same units as B{C{radius}}).
1115
1113
  @kwarg radius: Optional mean earth radius (C{meter}).
@@ -1139,8 +1137,8 @@ class _idllmn6(object): # see also .geodesicw._wargs, .latlonBase._toCartesian3
1139
1137
  if wrap:
1140
1138
  _, lat2, lon2 = _Wrap.latlon3(lon1, lat2, lon2, wrap)
1141
1139
  kwds = _xkwds(kwds, wrap=wrap) # for _xError
1142
- m = small if small is _100km else Meter_(small=small)
1143
- n = (intersections2 if s else intersection2).__name__
1140
+ m = small if small is _100km else Meter_(small=small)
1141
+ n = _dunder_nameof(intersections2 if s else intersection2)
1144
1142
  if datum is None or euclidean(lat1, lon1, lat2, lon2) < m:
1145
1143
  d, m = None, _MODS.vector3d
1146
1144
  _i = m._intersects2 if s else m._intersect3d3
@@ -1398,13 +1396,13 @@ def isnormal_(phi, lam, eps=0):
1398
1396
  return (PI_2 - fabs(phi)) >= eps and (PI - fabs(lam)) >= eps
1399
1397
 
1400
1398
 
1401
- def latlon2n_xyz(lat, lon, name=NN):
1399
+ def latlon2n_xyz(lat, lon, **name):
1402
1400
  '''Convert lat-, longitude to C{n-vector} (I{normal} to the
1403
1401
  earth's surface) X, Y and Z components.
1404
1402
 
1405
1403
  @arg lat: Latitude (C{degrees}).
1406
1404
  @arg lon: Longitude (C{degrees}).
1407
- @kwarg name: Optional name (C{str}).
1405
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1408
1406
 
1409
1407
  @return: A L{Vector3Tuple}C{(x, y, z)}.
1410
1408
 
@@ -1429,12 +1427,12 @@ def _normal2(a, b, n_2, n, n2):
1429
1427
  return float0_(a, b)
1430
1428
 
1431
1429
 
1432
- def normal(lat, lon, name=NN):
1430
+ def normal(lat, lon, **name):
1433
1431
  '''Normalize a lat- I{and} longitude pair in C{degrees}.
1434
1432
 
1435
1433
  @arg lat: Latitude (C{degrees}).
1436
1434
  @arg lon: Longitude (C{degrees}).
1437
- @kwarg name: Optional name (C{str}).
1435
+ @kwarg name: Optional, overriding C{B{name}="normal"} (C{str}).
1438
1436
 
1439
1437
  @return: L{LatLon2Tuple}C{(lat, lon)} with C{abs(lat) <= 90}
1440
1438
  and C{abs(lon) <= 180}.
@@ -1442,15 +1440,15 @@ def normal(lat, lon, name=NN):
1442
1440
  @see: Functions L{normal_} and L{isnormal}.
1443
1441
  '''
1444
1442
  return LatLon2Tuple(*_normal2(lat, lon, _90_0, _180_0, _360_0),
1445
- name=name or normal.__name__)
1443
+ name=_name__(name, name__=normal))
1446
1444
 
1447
1445
 
1448
- def normal_(phi, lam, name=NN):
1446
+ def normal_(phi, lam, **name):
1449
1447
  '''Normalize a lat- I{and} longitude pair in C{radians}.
1450
1448
 
1451
1449
  @arg phi: Latitude (C{radians}).
1452
1450
  @arg lam: Longitude (C{radians}).
1453
- @kwarg name: Optional name (C{str}).
1451
+ @kwarg name: Optional, overriding C{B{name}="normal_"} (C{str}).
1454
1452
 
1455
1453
  @return: L{PhiLam2Tuple}C{(phi, lam)} with C{abs(phi) <= PI/2}
1456
1454
  and C{abs(lam) <= PI}.
@@ -1458,45 +1456,45 @@ def normal_(phi, lam, name=NN):
1458
1456
  @see: Functions L{normal} and L{isnormal_}.
1459
1457
  '''
1460
1458
  return PhiLam2Tuple(*_normal2(phi, lam, PI_2, PI, PI2),
1461
- name=name or normal_.__name__)
1459
+ name=_name__(name, name__=normal_))
1462
1460
 
1463
1461
 
1464
- def _2n_xyz(name, sa, ca, sb, cb):
1462
+ def _2n_xyz(name, sa, ca, sb, cb): # name always **name
1465
1463
  '''(INTERNAL) Helper for C{latlon2n_xyz} and C{philam2n_xyz}.
1466
1464
  '''
1467
1465
  # Kenneth Gade eqn 3, but using right-handed
1468
1466
  # vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N
1469
- return Vector3Tuple(ca * cb, ca * sb, sa, name=name)
1467
+ return Vector3Tuple(ca * cb, ca * sb, sa, **name)
1470
1468
 
1471
1469
 
1472
- def n_xyz2latlon(x, y, z, name=NN):
1470
+ def n_xyz2latlon(x, y, z, **name):
1473
1471
  '''Convert C{n-vector} components to lat- and longitude in C{degrees}.
1474
1472
 
1475
1473
  @arg x: X component (C{scalar}).
1476
1474
  @arg y: Y component (C{scalar}).
1477
1475
  @arg z: Z component (C{scalar}).
1478
- @kwarg name: Optional name (C{str}).
1476
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1479
1477
 
1480
1478
  @return: A L{LatLon2Tuple}C{(lat, lon)}.
1481
1479
 
1482
1480
  @see: Function L{n_xyz2philam}.
1483
1481
  '''
1484
- return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), name=name)
1482
+ return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), **name)
1485
1483
 
1486
1484
 
1487
- def n_xyz2philam(x, y, z, name=NN):
1485
+ def n_xyz2philam(x, y, z, **name):
1488
1486
  '''Convert C{n-vector} components to lat- and longitude in C{radians}.
1489
1487
 
1490
1488
  @arg x: X component (C{scalar}).
1491
1489
  @arg y: Y component (C{scalar}).
1492
1490
  @arg z: Z component (C{scalar}).
1493
- @kwarg name: Optional name (C{str}).
1491
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1494
1492
 
1495
1493
  @return: A L{PhiLam2Tuple}C{(phi, lam)}.
1496
1494
 
1497
1495
  @see: Function L{n_xyz2latlon}.
1498
1496
  '''
1499
- return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), name=name)
1497
+ return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), **name)
1500
1498
 
1501
1499
 
1502
1500
  def _opposes(d, m, n, n2):
@@ -1539,7 +1537,7 @@ def opposing_(radians1, radians2, margin=PI_2):
1539
1537
  return _opposes(radians2 - radians1, m, PI, PI2)
1540
1538
 
1541
1539
 
1542
- def philam2n_xyz(phi, lam, name=NN):
1540
+ def philam2n_xyz(phi, lam, **name):
1543
1541
  '''Convert lat-, longitude to C{n-vector} (I{normal} to the
1544
1542
  earth's surface) X, Y and Z components.
1545
1543
 
@@ -1557,14 +1555,29 @@ def philam2n_xyz(phi, lam, name=NN):
1557
1555
  return _2n_xyz(name, *sincos2_(phi, lam))
1558
1556
 
1559
1557
 
1560
- def _radical2(d, r1, r2): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
1558
+ def _Propy(func, nargs, kwds):
1559
+ '''(INTERNAL) Helper for the C{frechet.[-]Frechet**} and
1560
+ C{hausdorff.[-]Hausdorff*} classes.
1561
+ '''
1562
+ try:
1563
+ _xcallable(distance=func)
1564
+ # assert _args_kwds_count2(func)[0] == nargs + int(ismethod(func))
1565
+ _ = func(*_0_0s(nargs), **kwds)
1566
+ except Exception as x:
1567
+ t = unstr(func, **kwds)
1568
+ raise _TypeError(t, cause=x)
1569
+ return func
1570
+
1571
+
1572
+ def _radical2(d, r1, r2, **name): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
1561
1573
  # (INTERNAL) See C{radical2} below
1562
1574
  # assert d > EPS0
1563
- r = fsumf_(_1_0, (r1 / d)**2, -(r2 / d)**2) * _0_5
1564
- return Radical2Tuple(max(_0_0, min(_1_0, r)), r * d)
1575
+ r = fsumf_(_1_0, (r1 / d)**2, -(r2 / d)**2) * _0_5
1576
+ n = _name__(name, name__=radical2)
1577
+ return Radical2Tuple(max(_0_0, min(_1_0, r)), r * d, name=n)
1565
1578
 
1566
1579
 
1567
- def radical2(distance, radius1, radius2):
1580
+ def radical2(distance, radius1, radius2, **name):
1568
1581
  '''Compute the I{radical ratio} and I{radical line} of two
1569
1582
  U{intersecting circles<https://MathWorld.Wolfram.com/
1570
1583
  Circle-CircleIntersection.html>}.
@@ -1575,6 +1588,7 @@ def radical2(distance, radius1, radius2):
1575
1588
  @arg distance: Distance between the circle centers (C{scalar}).
1576
1589
  @arg radius1: Radius of the first circle (C{scalar}).
1577
1590
  @arg radius2: Radius of the second circle (C{scalar}).
1591
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1578
1592
 
1579
1593
  @return: A L{Radical2Tuple}C{(ratio, xline)} where C{0.0 <=
1580
1594
  ratio <= 1.0} and C{xline} is along the B{C{distance}}.
@@ -1594,8 +1608,8 @@ def radical2(distance, radius1, radius2):
1594
1608
  if d > (r1 + r2):
1595
1609
  raise IntersectionError(distance=d, radius1=r1, radius2=r2,
1596
1610
  txt=_too_(_distant_))
1597
- return _radical2(d, r1, r2) if d > EPS0 else \
1598
- Radical2Tuple(_0_5, _0_0)
1611
+ return _radical2(d, r1, r2, **name) if d > EPS0 else \
1612
+ Radical2Tuple(_0_5, _0_0, **name)
1599
1613
 
1600
1614
 
1601
1615
  class Radical2Tuple(_NamedTuple):
@@ -1607,7 +1621,7 @@ class Radical2Tuple(_NamedTuple):
1607
1621
 
1608
1622
 
1609
1623
  def _radistance(inst):
1610
- '''(INTERNAL) Helper for the L{frechet._FrecherMeterRadians}
1624
+ '''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
1611
1625
  and L{hausdorff._HausdorffMeterRedians} classes.
1612
1626
  '''
1613
1627
  wrap_, kwds_ = _xkwds_pop2(inst._kwds, wrap=False)
@@ -1695,8 +1709,8 @@ def thomas_(phi2, phi1, lam21, datum=_WGS84):
1695
1709
 
1696
1710
  @see: Functions L{thomas}, L{cosineAndoyerLambert_},
1697
1711
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1698
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1699
- L{flatPolar_}, L{haversine_} and L{vincentys_} and U{Geodesy-PHP
1712
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
1713
+ L{haversine_} and L{vincentys_} and U{Geodesy-PHP
1700
1714
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
1701
1715
  Distance/ThomasFormula.php>}.
1702
1716
  '''
@@ -1778,8 +1792,8 @@ def vincentys_(phi2, phi1, lam21):
1778
1792
 
1779
1793
  @see: Functions L{vincentys}, L{cosineAndoyerLambert_},
1780
1794
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1781
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1782
- L{flatPolar_}, L{haversine_} and L{thomas_}.
1795
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
1796
+ L{haversine_} and L{thomas_}.
1783
1797
 
1784
1798
  @note: Functions L{vincentys_}, L{haversine_} and L{cosineLaw_}
1785
1799
  produce equivalent results, but L{vincentys_} is suitable