pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.9__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 (71) hide show
  1. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/METADATA +6 -5
  2. PyGeodesy-24.6.9.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +4 -4
  4. pygeodesy/auxilats/__init__.py +1 -1
  5. pygeodesy/auxilats/__main__.py +2 -2
  6. pygeodesy/auxilats/auxAngle.py +4 -4
  7. pygeodesy/basics.py +39 -5
  8. pygeodesy/booleans.py +54 -67
  9. pygeodesy/cartesianBase.py +138 -147
  10. pygeodesy/constants.py +3 -3
  11. pygeodesy/deprecated/functions.py +9 -3
  12. pygeodesy/ecef.py +67 -72
  13. pygeodesy/ellipsoidalBase.py +18 -56
  14. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  15. pygeodesy/ellipsoidalKarney.py +3 -3
  16. pygeodesy/ellipsoidalNvector.py +7 -7
  17. pygeodesy/ellipsoids.py +6 -5
  18. pygeodesy/errors.py +20 -10
  19. pygeodesy/etm.py +16 -21
  20. pygeodesy/fmath.py +9 -20
  21. pygeodesy/formy.py +60 -74
  22. pygeodesy/frechet.py +13 -14
  23. pygeodesy/fsums.py +60 -26
  24. pygeodesy/geodesicx/__init__.py +1 -1
  25. pygeodesy/geodesicx/__main__.py +2 -2
  26. pygeodesy/geodesicx/gx.py +3 -5
  27. pygeodesy/geodsolve.py +24 -26
  28. pygeodesy/geohash.py +27 -40
  29. pygeodesy/geoids.py +1 -1
  30. pygeodesy/hausdorff.py +17 -18
  31. pygeodesy/heights.py +17 -30
  32. pygeodesy/internals.py +15 -14
  33. pygeodesy/interns.py +3 -9
  34. pygeodesy/iters.py +2 -2
  35. pygeodesy/karney.py +8 -7
  36. pygeodesy/latlonBase.py +189 -176
  37. pygeodesy/lazily.py +92 -56
  38. pygeodesy/lcc.py +2 -2
  39. pygeodesy/ltp.py +93 -55
  40. pygeodesy/ltpTuples.py +304 -240
  41. pygeodesy/mgrs.py +51 -24
  42. pygeodesy/named.py +159 -136
  43. pygeodesy/namedTuples.py +43 -14
  44. pygeodesy/nvectorBase.py +20 -23
  45. pygeodesy/osgr.py +40 -48
  46. pygeodesy/points.py +11 -11
  47. pygeodesy/props.py +29 -16
  48. pygeodesy/rhumb/aux_.py +13 -15
  49. pygeodesy/rhumb/bases.py +12 -5
  50. pygeodesy/rhumb/ekx.py +24 -18
  51. pygeodesy/rhumb/solve.py +20 -70
  52. pygeodesy/simplify.py +16 -16
  53. pygeodesy/solveBase.py +35 -32
  54. pygeodesy/sphericalBase.py +33 -31
  55. pygeodesy/sphericalTrigonometry.py +17 -17
  56. pygeodesy/streprs.py +6 -4
  57. pygeodesy/trf.py +11 -9
  58. pygeodesy/triaxials.py +71 -50
  59. pygeodesy/units.py +40 -65
  60. pygeodesy/unitsBase.py +2 -2
  61. pygeodesy/ups.py +66 -70
  62. pygeodesy/utily.py +7 -6
  63. pygeodesy/utm.py +152 -156
  64. pygeodesy/utmups.py +38 -38
  65. pygeodesy/utmupsBase.py +102 -106
  66. pygeodesy/vector3d.py +34 -36
  67. pygeodesy/vector3dBase.py +12 -9
  68. pygeodesy/webmercator.py +43 -51
  69. PyGeodesy-24.5.24.dist-info/RECORD +0 -116
  70. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/WHEEL +0 -0
  71. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/top_level.txt +0 -0
pygeodesy/ellipsoids.py CHANGED
@@ -80,11 +80,12 @@ from pygeodesy.interns import NN, _a_, _Airy1830_, _AiryModified_, _b_, _Bessel1
80
80
  _prime_vertical_, _radius_, _Sphere_, _SPACE_, _vs_, _WGS72_, _WGS84_
81
81
  # from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
82
82
  from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _name2__, _NamedEnum, \
83
- _NamedEnumItem, _NamedTuple, _Pass, _ALL_LAZY, _MODS
83
+ _NamedEnumItem, _NamedTuple, _Pass, _ALL_LAZY, _MODS
84
84
  from pygeodesy.namedTuples import Distance2Tuple, Vector3Tuple, Vector4Tuple
85
85
  from pygeodesy.props import deprecated_Property_RO, Property_RO, property_doc_, \
86
86
  deprecated_property_RO, property_RO
87
87
  from pygeodesy.streprs import Fmt, fstr, instr, strs, unstr
88
+ # from pygeodesy.triaxials import _hartzell3 # _MODS
88
89
  from pygeodesy.units import Bearing_, Distance, Float, Float_, Height, Lam_, Lat, Meter, \
89
90
  Meter2, Meter3, Phi, Phi_, Radius, Radius_, Scalar
90
91
  from pygeodesy.utily import atan1, atan1d, atan2b, degrees90, m2radians, radians2m, sincos2d
@@ -92,7 +93,7 @@ from pygeodesy.utily import atan1, atan1d, atan2b, degrees90, m2radians, radians
92
93
  from math import asinh, atan, atanh, cos, degrees, exp, fabs, radians, sin, sinh, sqrt, tan
93
94
 
94
95
  __all__ = _ALL_LAZY.ellipsoids
95
- __version__ = '24.05.21'
96
+ __version__ = '24.05.28'
96
97
 
97
98
  _f_0_0 = Float(f =_0_0) # zero flattening
98
99
  _f__0_0 = Float(f_=_0_0) # zero inverse flattening
@@ -1101,7 +1102,7 @@ class Ellipsoid(_NamedEnumItem):
1101
1102
  methods L{Ellipsoid.height4} and L{Triaxial.hartzell4}.
1102
1103
  '''
1103
1104
  try:
1104
- v, d = _MODS.triaxials._hartzell2(pov, los, self._triaxial)
1105
+ v, d, _ = _MODS.triaxials._hartzell3(pov, los, self._triaxial)
1105
1106
  except Exception as x:
1106
1107
  raise IntersectionError(pov=pov, los=los, cause=x)
1107
1108
  return Vector4Tuple(v.x, v.y, v.z, d, name__=self.hartzell4)
@@ -1643,9 +1644,9 @@ class Ellipsoid(_NamedEnumItem):
1643
1644
  r = self.e2s2(sin(a))
1644
1645
  if r > EPS02:
1645
1646
  n = self.a / sqrt(r)
1646
- m = n * self.e21 / r # PYCHOK attr
1647
+ m = n * self.e21 / r
1647
1648
  else:
1648
- m = n = _0_0 # PYCHOK attr
1649
+ m = n = _0_0
1649
1650
  else:
1650
1651
  m = n = self.a
1651
1652
  if scaled and a:
pygeodesy/errors.py CHANGED
@@ -26,7 +26,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _getenv, _PYTHON_X_D
26
26
  from copy import copy as _copy
27
27
 
28
28
  __all__ = _ALL_LAZY.errors # _ALL_DOCS('_InvalidError', '_IsnotError') _under
29
- __version__ = '24.05.19'
29
+ __version__ = '24.06.08'
30
30
 
31
31
  _argument_ = 'argument'
32
32
  _box_ = 'box'
@@ -43,7 +43,7 @@ try:
43
43
 
44
44
  if _PYTHON_X_DEV or _getenv('PYGEODESY_EXCEPTION_CHAINING', NN): # == _std_
45
45
  _exception_chaining = True # turned on, std
46
- raise AttributeError # allow exception chaining
46
+ raise AttributeError() # allow exception chaining
47
47
 
48
48
  _exception_chaining = False # turned off
49
49
 
@@ -252,7 +252,7 @@ class LenError(_ValueError): # in .ecef, .fmath, .heights, .iters, .named
252
252
  class LimitError(_ValueError):
253
253
  '''Error raised for lat- or longitudinal values or deltas exceeding
254
254
  the given B{C{limit}} in functions L{pygeodesy.equirectangular},
255
- L{pygeodesy.equirectangular_}, C{nearestOn*} and C{simplify*}
255
+ L{pygeodesy.equirectangular4}, C{nearestOn*} and C{simplify*}
256
256
  or methods with C{limit} or C{options} keyword arguments.
257
257
 
258
258
  @see: Subclass L{UnitError}.
@@ -748,8 +748,8 @@ def _xkwds_get(kwds, **name_default):
748
748
  C{default} if not present.
749
749
  '''
750
750
  if isinstance(kwds, dict) and len(name_default) == 1:
751
- for n, d in name_default.items():
752
- return kwds.get(n, d)
751
+ for n, v in name_default.items():
752
+ return kwds.get(n, v)
753
753
  raise _xAssertionError(_xkwds_get, kwds, **name_default)
754
754
 
755
755
 
@@ -759,8 +759,18 @@ def _xkwds_get_(kwds, **names_defaults):
759
759
  '''
760
760
  if not isinstance(kwds, dict):
761
761
  raise _xAssertionError(_xkwds_get_, kwds)
762
- for n, d in _MODS.basics.itemsorted(names_defaults):
763
- yield kwds.get(n, d)
762
+ for n, v in _MODS.basics.itemsorted(names_defaults):
763
+ yield kwds.get(n, v)
764
+
765
+
766
+ def _xkwds_get1(kwds, **name_default):
767
+ '''(INTERNAL) Get one C{kwds} value by C{name} or the
768
+ C{default} if not present.
769
+ '''
770
+ v, kwds = _xkwds_pop2(kwds, **name_default)
771
+ if kwds:
772
+ raise _UnexpectedError(**kwds)
773
+ return v
764
774
 
765
775
 
766
776
  def _xkwds_item2(kwds):
@@ -784,11 +794,11 @@ def _xkwds_pop2(kwds, **name_default):
784
794
  reduced C{kwds} copy, otherwise the C{default} and original C{kwds}.
785
795
  '''
786
796
  if isinstance(kwds, dict) and len(name_default) == 1:
787
- for n, d in name_default.items():
797
+ for n, v in name_default.items():
788
798
  if n in kwds:
789
799
  kwds = _copy(kwds)
790
- d = kwds.pop(n, d)
791
- return d, kwds
800
+ v = kwds.pop(n, v)
801
+ return v, kwds
792
802
  raise _xAssertionError(_xkwds_pop2, kwds, **name_default)
793
803
 
794
804
 
pygeodesy/etm.py CHANGED
@@ -92,7 +92,7 @@ from pygeodesy.utm import _cmlon, _LLEB, _parseUTM5, _toBand, _toXtm8, \
92
92
  from math import asinh, atan2, degrees, radians, sinh, sqrt
93
93
 
94
94
  __all__ = _ALL_LAZY.etm
95
- __version__ = '24.05.24'
95
+ __version__ = '24.05.31'
96
96
 
97
97
  _OVERFLOW = _1_EPS**2 # about 2e+31
98
98
  _TAYTOL = pow(EPS, 0.6)
@@ -101,12 +101,6 @@ _TOL_10 = EPS * _0_1
101
101
  _TRIPS = 21 # C++ 10
102
102
 
103
103
 
104
- def _overflow(x):
105
- '''(INTERNAL) Like C{copysign0(OVERFLOW, B{x})}.
106
- '''
107
- return _copyBit(_OVERFLOW, x)
108
-
109
-
110
104
  class ETMError(UTMError):
111
105
  '''Exact Transverse Mercator (ETM) parse, projection or other
112
106
  L{Etm} issue or L{ExactTransverseMercator} conversion failure.
@@ -160,17 +154,15 @@ class Etm(Utm):
160
154
  def parse(self, strETM, **name):
161
155
  '''Parse a string to a similar L{Etm} instance.
162
156
 
163
- @arg strETM: The ETM coordinate (C{str}), see function
164
- L{parseETM5}.
165
- @kwarg name: Optional C{B{name}=NN} (C{str}), overriding
166
- this name.
157
+ @arg strETM: The ETM coordinate (C{str}), see function L{parseETM5}.
158
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
167
159
 
168
160
  @return: The instance (L{Etm}).
169
161
 
170
162
  @raise ETMError: Invalid B{C{strETM}}.
171
163
 
172
- @see: Function L{pygeodesy.parseUPS5}, L{pygeodesy.parseUTM5}
173
- and L{pygeodesy.parseUTMUPS5}.
164
+ @see: Function L{pygeodesy.parseUPS5}, L{pygeodesy.parseUTM5} and
165
+ L{pygeodesy.parseUTMUPS5}.
174
166
  '''
175
167
  return parseETM5(strETM, datum=self.datum, Etm=self.classof,
176
168
  name=self._name__(name))
@@ -217,9 +209,7 @@ class Etm(Utm):
217
209
  lat, lon, g, k = xTM.reverse(e, n, lon0=lon0)
218
210
 
219
211
  ll = _LLEB(lat, lon, datum=d, name=self.name) # utm._LLEB
220
- ll._gamma = g
221
- ll._scale = k
222
- self._latlon5args(ll, _toBand, unfalse, xTM)
212
+ self._latlon5args(ll, g, k, _toBand, unfalse, xTM)
223
213
 
224
214
  def toUtm(self): # PYCHOK signature
225
215
  '''Copy this ETM to a UTM coordinate.
@@ -1032,6 +1022,12 @@ class ExactTransverseMercator(_NamedBase):
1032
1022
  return g_k # or (g, k, lat, lon)
1033
1023
 
1034
1024
 
1025
+ def _overflow(x):
1026
+ '''(INTERNAL) Like C{copysign0(OVERFLOW, B{x})}.
1027
+ '''
1028
+ return _copyBit(_OVERFLOW, x)
1029
+
1030
+
1035
1031
  def parseETM5(strUTM, datum=_WGS84, Etm=Etm, falsed=True, **name):
1036
1032
  '''Parse a string representing a UTM coordinate, consisting
1037
1033
  of C{"zone[band] hemisphere easting northing"}.
@@ -1058,8 +1054,7 @@ def parseETM5(strUTM, datum=_WGS84, Etm=Etm, falsed=True, **name):
1058
1054
 
1059
1055
 
1060
1056
  def toEtm8(latlon, lon=None, datum=None, Etm=Etm, falsed=True,
1061
- strict=True, zone=None,
1062
- **name_cmoff):
1057
+ strict=True, zone=None, **name_cmoff):
1063
1058
  '''Convert a geodetic lat-/longitude to an ETM coordinate.
1064
1059
 
1065
1060
  @arg latlon: Latitude (C{degrees}) or an (ellipsoidal)
@@ -1075,9 +1070,9 @@ def toEtm8(latlon, lon=None, datum=None, Etm=Etm, falsed=True,
1075
1070
  @kwarg strict: Restrict B{C{lat}} to UTM ranges (C{bool}).
1076
1071
  @kwarg zone: Optional UTM zone to enforce (C{int} or C{str}).
1077
1072
  @kwarg name_cmoff: Optional B{C{Etm}} C{B{name}=NN} (C{str})
1078
- and DEPRECATED C{B{cmoff}=True} to offset longitude
1079
- from the zone's central meridian (C{bool}), instead
1080
- use C{B{falsed}=True}.
1073
+ and DEPRECATED keyword argument C{B{cmoff}=True}
1074
+ to offset the longitude from the zone's central
1075
+ meridian (C{bool}), use B{C{falsed}} instead.
1081
1076
 
1082
1077
  @return: The ETM coordinate as an B{C{Etm}} instance or a
1083
1078
  L{UtmUps8Tuple}C{(zone, hemipole, easting, northing,
pygeodesy/fmath.py CHANGED
@@ -12,7 +12,7 @@ from pygeodesy.constants import EPS0, EPS02, EPS1, NAN, PI, PI_2, PI_4, \
12
12
  _0_0, _0_125, _1_6th, _0_25, _1_3rd, _0_5, _1_0, \
13
13
  _N_1_0, _1_5, _copysign_0_0, _isfinite, remainder
14
14
  from pygeodesy.errors import _IsnotError, LenError, _TypeError, _ValueError, \
15
- _xError, _xkwds_get, _xkwds_pop2
15
+ _xError, _xkwds_get1, _xkwds_pop2
16
16
  from pygeodesy.fsums import _2float, Fsum, fsum, fsum1_, _isFsumTuple, _1primed, \
17
17
  Fmt, unstr
18
18
  from pygeodesy.interns import MISSING, _negative_, _not_scalar_
@@ -24,7 +24,7 @@ from math import fabs, sqrt # pow
24
24
  import operator as _operator # in .datums, .trf, .utm
25
25
 
26
26
  __all__ = _ALL_LAZY.fmath
27
- __version__ = '24.05.24'
27
+ __version__ = '24.05.29'
28
28
 
29
29
  # sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
30
30
  _0_4142 = 0.41421356237309504880 # ... sqrt(2) - 1
@@ -85,19 +85,7 @@ class Fhorner(Fsum):
85
85
  '''
86
86
  Fsum.__init__(self, **name_RESIDUAL)
87
87
  if cs:
88
- if _isFsumTuple(x):
89
- _mul = self._mul_Fsum
90
- else:
91
- _mul = self._mul_scalar
92
- x = _2float(x=x)
93
- op = Fhorner.__name__
94
- if len(cs) > 1 and x:
95
- for c in reversed(cs):
96
- self._fset_ps(_mul(x, op))
97
- self._fadd(c, op, up=False)
98
- self._update()
99
- else: # x == 0
100
- self._fadd(cs[0], op)
88
+ self._fhorner(x, cs, Fhorner.__name__)
101
89
  else:
102
90
  self._fset_ps(_0_0)
103
91
 
@@ -343,8 +331,9 @@ def facos1(x):
343
331
  if a < EPS0:
344
332
  r = PI_2
345
333
  elif a < EPS1:
346
- H = Fhorner(-a, 1.5707288, 0.2121144, 0.0742610, 0.0187293)
347
- r = float(H * sqrt(_1_0 - a))
334
+ H = Fhorner(-a, 1.5707288, 0.2121144, 0.0742610, 0.0187293)
335
+ H *= Fsqrt(_1_0, -a)
336
+ r = float(H)
348
337
  if x < 0:
349
338
  r = PI - r
350
339
  else:
@@ -376,7 +365,7 @@ def fatan(x):
376
365
 
377
366
 
378
367
  def fatan1(x):
379
- '''Fast approximation of C{atan(B{x})} for C{0 <= B{x} <= 1}, I{unchecked}.
368
+ '''Fast approximation of C{atan(B{x})} for C{0 <= B{x} < 1}, I{unchecked}.
380
369
 
381
370
  @see: U{ShaderFastLibs.h<https://GitHub.com/michaldrobot/ShaderFastLibs/
382
371
  blob/master/ShaderFastMathLib.h>} and U{Efficient approximations
@@ -385,7 +374,7 @@ def fatan1(x):
385
374
  IEEE Signal Processing Magazine, 111, May 2006.
386
375
  '''
387
376
  # Eq (9): PI_4 * x - x * (abs(x) - 1) * (0.2447 + 0.0663 * abs(x)), for -1 < x < 1
388
- # PI_4 * x - (x**2 - x) * (0.2447 + 0.0663 * x), for 0 < x - 1
377
+ # PI_4 * x - (x**2 - x) * (0.2447 + 0.0663 * x), for 0 < x < 1
389
378
  # x * (1.0300981633974482 + x * (-0.1784 - x * 0.0663))
390
379
  H = Fhorner(x, _0_0, 1.0300981634, -0.1784, -0.0663)
391
380
  return float(H)
@@ -597,7 +586,7 @@ def fpolynomial(x, *cs, **over):
597
586
  @see: Class L{Fpolynomial} for further details.
598
587
  '''
599
588
  P = Fpolynomial(x, *cs)
600
- d = _xkwds_get(over, over=0) if over else 0
589
+ d = _xkwds_get1(over, over=0) if over else 0
601
590
  return P.fover(d) if d else float(P)
602
591
 
603
592
 
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,18 +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
21
  from pygeodesy.fsums import fsumf_, Fmt, unstr
22
22
  # from pygeodesy.internals import _dunder_nameof # from .named
23
- from pygeodesy.interns import _delta_, _distant_, _inside_, _not_, _SPACE_, _too_
23
+ from pygeodesy.interns import _delta_, _distant_, _inside_, _SPACE_, _too_
24
24
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
25
25
  from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed, \
26
26
  _dunder_nameof
27
27
  from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
28
28
  Intersection3Tuple, PhiLam2Tuple, Vector3Tuple
29
29
  # from pygeodesy.streprs import Fmt, unstr # from .fsums
30
- # from pygeodesy.triaxials import _hartzell2 # _MODS
30
+ # from pygeodesy.triaxials import _hartzell3 # _MODS
31
31
  from pygeodesy.units import _isHeight, _isRadius, Bearing, Degrees_, Distance, \
32
32
  Distance_, Height, Lam_, Lat, Lon, Meter_, Phi_, \
33
33
  Radians, Radians_, Radius, Radius_, Scalar, _100km
@@ -42,7 +42,7 @@ from contextlib import contextmanager
42
42
  from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
43
43
 
44
44
  __all__ = _ALL_LAZY.formy
45
- __version__ = '24.05.24'
45
+ __version__ = '24.05.28'
46
46
 
47
47
  _RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
48
48
  _ratio_ = 'ratio'
@@ -232,8 +232,8 @@ def cosineAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
232
232
  @raise TypeError: Invalid B{C{datum}}.
233
233
 
234
234
  @see: Functions L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert_},
235
- L{cosineLaw_}, L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
236
- 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
237
237
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/Distance/
238
238
  AndoyerLambert.php>}.
239
239
  '''
@@ -298,8 +298,8 @@ def cosineForsytheAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
298
298
  @raise TypeError: Invalid B{C{datum}}.
299
299
 
300
300
  @see: Functions L{cosineForsytheAndoyerLambert}, L{cosineAndoyerLambert_},
301
- L{cosineLaw_}, L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
302
- 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
303
303
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
304
304
  Distance/ForsytheCorrection.php>}.
305
305
  '''
@@ -366,9 +366,9 @@ def cosineLaw_(phi2, phi1, lam21):
366
366
  @return: Angular distance (C{radians}).
367
367
 
368
368
  @see: Functions L{cosineLaw}, L{cosineAndoyerLambert_},
369
- L{cosineForsytheAndoyerLambert_}, L{equirectangular_},
370
- L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
371
- 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_}.
372
372
 
373
373
  @note: See note at function L{vincentys_}.
374
374
  '''
@@ -430,35 +430,31 @@ def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
430
430
  @arg lon1: Start longitude (C{degrees}).
431
431
  @arg lat2: End latitude (C{degrees}).
432
432
  @arg lon2: End longitude (C{degrees}).
433
- @kwarg radius: Mean earth radius (C{meter}), datum (L{Datum})
434
- or ellipsoid (L{Ellipsoid}, L{Ellipsoid2} or
435
- L{a_f2Tuple}).
436
- @kwarg adjust_limit_wrap: Optional keyword arguments for
437
- 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}.
438
436
 
439
- @return: Distance (C{meter}, same units as B{C{radius}} or
440
- the ellipsoid or datum axes).
437
+ @return: Distance (C{meter}, same units as B{C{radius}} or the ellipsoid or datum axes).
441
438
 
442
439
  @raise TypeError: Invalid B{C{radius}}.
443
440
 
444
- @see: Function L{equirectangular_} for more details, the
445
- available B{C{options}}, errors, restrictions and other,
446
- 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.
447
443
  '''
448
- d = sqrt(equirectangular_(Lat(lat1=lat1), Lon(lon1=lon1),
444
+ d = sqrt(equirectangular4(Lat(lat1=lat1), Lon(lon1=lon1),
449
445
  Lat(lat2=lat2), Lon(lon2=lon2),
450
446
  **adjust_limit_wrap).distance2) # PYCHOK 4 vs 2-3
451
447
  return degrees2m(d, radius=_mean_radius(radius, lat1, lat2))
452
448
 
453
449
 
454
450
  def _equirectangular(lat1, lon1, lat2, lon2, **adjust_limit_wrap):
455
- '''(INTERNAL) Helper for the L{frechet._FrecherMeterRadians}
451
+ '''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
456
452
  and L{hausdorff._HausdorffMeterRedians} classes.
457
453
  '''
458
- return equirectangular_(lat1, lon1, lat2, lon2, **adjust_limit_wrap).distance2 * _RADIANS2
454
+ return equirectangular4(lat1, lon1, lat2, lon2, **adjust_limit_wrap).distance2 * _RADIANS2
459
455
 
460
456
 
461
- 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):
462
458
  '''Compute the distance between two points using the U{Equirectangular Approximation
463
459
  / Projection<https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}.
464
460
 
@@ -469,15 +465,15 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
469
465
  @arg lon1: Start longitude (C{degrees}).
470
466
  @arg lat2: End latitude (C{degrees}).
471
467
  @arg lon2: End longitude (C{degrees}).
472
- @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta
473
- by the cosine of the mean latitude (C{bool}).
474
- @kwarg limit: Optional limit for lat- and longitudinal deltas
475
- (C{degrees}) or C{None} or C{0} for unlimited.
476
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}}
477
- 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}).
478
474
 
479
- @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon,
480
- unroll_lon2)} in C{degrees squared}.
475
+ @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon, unroll_lon2)}
476
+ in C{degrees squared}.
481
477
 
482
478
  @raise LimitError: If the lat- and/or longitudinal delta exceeds the
483
479
  B{C{-limit..limit}} range and L{pygeodesy.limiterrors}
@@ -498,7 +494,7 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
498
494
  d = max(fabs(d_lat), fabs(d_lon))
499
495
  if d > limit:
500
496
  t = _SPACE_(_delta_, Fmt.PAREN_g(d), Fmt.exceeds_limit(limit))
501
- s = unstr(equirectangular_, lat1, lon1, lat2, lon2,
497
+ s = unstr(equirectangular4, lat1, lon1, lat2, lon2,
502
498
  limit=limit, wrap=wrap)
503
499
  raise LimitError(s, txt=t)
504
500
 
@@ -551,9 +547,9 @@ def euclidean_(phi2, phi1, lam21, adjust=True):
551
547
  @return: Angular distance (C{radians}).
552
548
 
553
549
  @see: Functions L{euclid}, L{euclidean}, L{cosineAndoyerLambert_},
554
- L{cosineForsytheAndoyerLambert_}, L{cosineLaw_}, L{equirectangular_},
555
- L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_}, L{thomas_}
556
- and L{vincentys_}.
550
+ L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
551
+ L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
552
+ L{thomas_} and L{vincentys_}.
557
553
  '''
558
554
  if adjust:
559
555
  lam21 *= _scale_rad(phi2, phi1)
@@ -866,8 +862,8 @@ def flatLocal_(phi2, phi1, lam21, datum=_WGS84, scaled=True):
866
862
 
867
863
  @see: Functions L{flatLocal} or L{hubeny}, L{cosineAndoyerLambert_},
868
864
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_}, L{flatPolar_},
869
- L{equirectangular_}, L{euclidean_}, L{haversine_}, L{thomas_}
870
- 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
871
867
  <https://www.EdWilliams.org/avform.htm#flat>}.
872
868
  '''
873
869
  E = _ellipsoidal(datum, flatLocal_)
@@ -920,8 +916,8 @@ def flatPolar_(phi2, phi1, lam21):
920
916
 
921
917
  @see: Functions L{flatPolar}, L{cosineAndoyerLambert_},
922
918
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
923
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
924
- L{haversine_}, L{thomas_} and L{vincentys_}.
919
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{haversine_},
920
+ L{thomas_} and L{vincentys_}.
925
921
  '''
926
922
  a = fabs(PI_2 - phi1) # co-latitude
927
923
  b = fabs(PI_2 - phi2) # co-latitude
@@ -964,9 +960,9 @@ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
964
960
  @kwarg earth: The earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
965
961
  L{a_f2Tuple} or a C{scalar} earth radius in C{meter}).
966
962
  @kwarg name_LatLon_and_kwds: Optional, overriding C{B{name}="hartzell"}
967
- (C{str}), C{B{LatLon}=None} class to return the intersection
963
+ (C{str}), class C{B{LatLon}=None} to return the intersection
968
964
  plus additional C{LatLon} keyword arguments, include the
969
- B{C{datum}} if different from B{C{earth}}.
965
+ B{C{datum}} if different and to convert from B{C{earth}}.
970
966
 
971
967
  @return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or the
972
968
  given B{C{LatLon}} instance) with attribute C{heigth} set to the
@@ -981,15 +977,14 @@ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
981
977
  @see: Class L{Los}, functions L{tyr3d} and L{hartzell4} and methods
982
978
  L{Ellipsoid.hartzell4} and any C{Cartesian.hartzell} and C{LatLon.hartzell}.
983
979
  '''
984
- D = _spherical_datum(earth, name__=hartzell)
985
980
  n, LatLon_and_kwds = _name2__(name_LatLon_and_kwds, name__=hartzell)
986
981
  try:
982
+ D = _spherical_datum(earth, name__=hartzell)
987
983
  r, h, i = _MODS.triaxials._hartzell3(pov, los, D.ellipsoid._triaxial)
988
- r = _xnamed(r, n)
989
984
 
990
985
  C = _MODS.cartesianBase.CartesianBase
991
986
  if LatLon_and_kwds:
992
- c = C(r, datum=D, name=r.name)
987
+ c = C(r, datum=D)
993
988
  r = c.toLatLon(**_xkwds(LatLon_and_kwds, height=h))
994
989
  elif isinstance(r, C):
995
990
  r.height = h
@@ -998,7 +993,7 @@ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
998
993
  except Exception as x:
999
994
  raise IntersectionError(pov=pov, los=los, earth=earth, cause=x,
1000
995
  **LatLon_and_kwds)
1001
- return r
996
+ return _xnamed(r, n) if n else r
1002
997
 
1003
998
 
1004
999
  def haversine(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
@@ -1045,8 +1040,8 @@ def haversine_(phi2, phi1, lam21):
1045
1040
 
1046
1041
  @see: Functions L{haversine}, L{cosineAndoyerLambert_},
1047
1042
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1048
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1049
- L{flatPolar_}, L{thomas_} and L{vincentys_}.
1043
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
1044
+ L{thomas_} and L{vincentys_}.
1050
1045
 
1051
1046
  @note: See note at function L{vincentys_}.
1052
1047
  '''
@@ -1111,8 +1106,8 @@ def heightOrthometric(h_ll, N):
1111
1106
 
1112
1107
 
1113
1108
  def horizon(height, radius=R_M, refraction=False):
1114
- '''Determine the distance to the horizon from a given altitude
1115
- above the (spherical) earth.
1109
+ '''Determine the distance to the horizon from a given altitude above the
1110
+ (spherical) earth.
1116
1111
 
1117
1112
  @arg height: Altitude (C{meter} or same units as B{C{radius}}).
1118
1113
  @kwarg radius: Optional mean earth radius (C{meter}).
@@ -1560,27 +1555,18 @@ def philam2n_xyz(phi, lam, **name):
1560
1555
  return _2n_xyz(name, *sincos2_(phi, lam))
1561
1556
 
1562
1557
 
1563
- def _Propy(inst, nargs, **_prop_func):
1558
+ def _Propy(func, nargs, kwds):
1564
1559
  '''(INTERNAL) Helper for the C{frechet.[-]Frechet**} and
1565
1560
  C{hausdorff.[-]Hausdorff*} classes.
1566
1561
  '''
1567
- _prop, func = _prop_func.popitem() # _xkwds_item2(_func_func)
1568
- if func is None: # getter
1569
- try:
1570
- return inst.__dict__[_prop]
1571
- except KeyError:
1572
- inst._notOverloaded(**inst.kwds)
1573
- else: # setter
1574
- try:
1575
- if not callable(func):
1576
- raise TypeError(_not_(callable.__name__))
1577
- args = (0,) * nargs
1578
- _ = func(*args, **inst.kwds)
1579
- except Exception as x:
1580
- t = unstr(func, **inst.kwds)
1581
- raise _TypeError(t, cause=x)
1582
- inst.__dict__[_prop] = func
1583
- # return func
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
1584
1570
 
1585
1571
 
1586
1572
  def _radical2(d, r1, r2, **name): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
@@ -1723,8 +1709,8 @@ def thomas_(phi2, phi1, lam21, datum=_WGS84):
1723
1709
 
1724
1710
  @see: Functions L{thomas}, L{cosineAndoyerLambert_},
1725
1711
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1726
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1727
- 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
1728
1714
  <https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
1729
1715
  Distance/ThomasFormula.php>}.
1730
1716
  '''
@@ -1806,8 +1792,8 @@ def vincentys_(phi2, phi1, lam21):
1806
1792
 
1807
1793
  @see: Functions L{vincentys}, L{cosineAndoyerLambert_},
1808
1794
  L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
1809
- L{equirectangular_}, L{euclidean_}, L{flatLocal_}/L{hubeny_},
1810
- L{flatPolar_}, L{haversine_} and L{thomas_}.
1795
+ L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
1796
+ L{haversine_} and L{thomas_}.
1811
1797
 
1812
1798
  @note: Functions L{vincentys_}, L{haversine_} and L{cosineLaw_}
1813
1799
  produce equivalent results, but L{vincentys_} is suitable
pygeodesy/frechet.py CHANGED
@@ -94,7 +94,7 @@ from pygeodesy.named import _name2__, _Named, _NamedTuple, _Pass
94
94
  # from pygeodesy.namedTuples import PhiLam2Tuple # from .points
95
95
  from pygeodesy.points import _distanceTo, _fractional, isscalar, \
96
96
  PhiLam2Tuple, points2 as _points2, radians
97
- from pygeodesy.props import property_doc_, property_RO
97
+ from pygeodesy.props import Property, property_doc_, property_RO
98
98
  from pygeodesy.units import FIx, Float, Number_, _xUnit, _xUnits
99
99
  from pygeodesy.unitsBase import _Str_degrees, _Str_meter, _Str_NN, \
100
100
  _Str_radians, _Str_radians2
@@ -103,7 +103,7 @@ from collections import defaultdict as _defaultdict
103
103
  # from math import radians # from .points
104
104
 
105
105
  __all__ = _ALL_LAZY.frechet
106
- __version__ = '24.05.24'
106
+ __version__ = '24.06.10'
107
107
 
108
108
 
109
109
  def _fraction(fraction, n):
@@ -252,14 +252,14 @@ class Frechet(_Named):
252
252
  # '''(INTERNAL) I{Must be overloaded}.'''
253
253
  # self._notOverloaded(*args, **kwds)
254
254
 
255
- @property
255
+ @Property
256
256
  def _func(self):
257
257
  '''(INTERNAL) I{Must be overloaded}.'''
258
- return _formy._Propy(self, 0, _func=None)
258
+ self._notOverloaded(**self.kwds)
259
259
 
260
- @_func.setter # PYCHOK setter!
260
+ @_func.setter_ # PYCHOK setter_underscore!
261
261
  def _func(self, func):
262
- _formy._Propy(self, 4, _func=func)
262
+ return _formy._Propy(func, 4, self.kwds)
263
263
 
264
264
  @property_RO
265
265
  def kwds(self):
@@ -382,14 +382,14 @@ class _FrechetMeterRadians(Frechet):
382
382
  '''
383
383
  return self._discrete(point2s, fraction, _formy._radistance(self))
384
384
 
385
- @property
385
+ @Property
386
386
  def _func_(self):
387
387
  '''(INTERNAL) I{Must be overloaded}.'''
388
- return _formy._Propy(self, 0, _func_=None)
388
+ self._notOverloaded(**self.kwds)
389
389
 
390
- @_func_.setter # PYCHOK setter!
390
+ @_func_.setter_ # PYCHOK setter_underscore!
391
391
  def _func_(self, func):
392
- _formy._Propy(self, 3, _func_=func)
392
+ return _formy._Propy(func, 3, self.kwds)
393
393
 
394
394
 
395
395
  class FrechetCosineAndoyerLambert(_FrechetMeterRadians):
@@ -507,7 +507,7 @@ class FrechetEquirectangular(Frechet):
507
507
 
508
508
  @kwarg fraction_name__adjust_limit_wrap: Optional C{B{fraction}=None}
509
509
  and C{B{name}=NN} and keyword arguments for
510
- function L{pygeodesy.equirectangular_} I{with
510
+ function L{pygeodesy.equirectangular} I{with
511
511
  default} C{B{limit}=0} for I{backward compatibility}.
512
512
 
513
513
  @see: L{Frechet.__init__} for details about B{C{point1s}}, B{C{fraction}},
@@ -842,12 +842,11 @@ class Frechet6Tuple(_NamedTuple):
842
842
  _Names_ = ('fd', 'fi1', 'fi2', 'r', _n_, _units_)
843
843
  _Units_ = (_Pass, FIx, FIx, Number_, Number_, _Pass)
844
844
 
845
- def toUnits(self, **Error): # PYCHOK expected
845
+ def toUnits(self, **Error_name): # PYCHOK expected
846
846
  '''Overloaded C{_NamedTuple.toUnits} for C{fd} units.
847
847
  '''
848
848
  U = _xUnit(self.units, Float) # PYCHOK expected
849
- self._Units_ = (U,) + Frechet6Tuple._Units_[1:]
850
- return _NamedTuple.toUnits(self, **Error)
849
+ return _NamedTuple.toUnits(self.reUnit(U), **Error_name) # PYCHOK self
851
850
 
852
851
  # def __gt__(self, other):
853
852
  # _xinstanceof(Frechet6Tuple, other=other)