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/fsums.py CHANGED
@@ -25,11 +25,11 @@ from __future__ import division as _; del _ # PYCHOK semicolon
25
25
 
26
26
  from pygeodesy.basics import isbool, iscomplex, isint, isscalar, \
27
27
  _signOf, itemsorted, signOf, _xiterable, \
28
- _enquote
28
+ _xiterablen, _enquote
29
29
  from pygeodesy.constants import INT0, _isfinite, NEG0, _pos_self, \
30
30
  _0_0, _1_0, _N_1_0, Float, Int
31
31
  from pygeodesy.errors import _OverflowError, _TypeError, _UnexpectedError, \
32
- _ValueError, _xError, _xError2, _xkwds_get, \
32
+ _ValueError, _xError, _xError2, _xkwds_get1, \
33
33
  _xkwds_pop2
34
34
  # from pygeodesy.internals import _enquote # from .basics
35
35
  from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, \
@@ -40,14 +40,14 @@ from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
40
40
  from pygeodesy.named import _name__, _name2__, _Named, _NamedTuple, \
41
41
  _NotImplemented
42
42
  from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
43
- Property_RO, property_RO
43
+ Property, Property_RO, property_RO
44
44
  from pygeodesy.streprs import Fmt, fstr, unstr
45
45
  # from pygeodesy.units import Float, Int # from .constants
46
46
 
47
47
  from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
48
48
 
49
49
  __all__ = _ALL_LAZY.fsums
50
- __version__ = '24.05.24'
50
+ __version__ = '24.06.09'
51
51
 
52
52
  _add_op_ = _PLUS_ # in .auxilats.auxAngle
53
53
  _eq_op_ = _EQUAL_ * 2 # _DEQUAL_
@@ -1105,6 +1105,26 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1105
1105
  # raise self._Error(op, other, _AssertionError, txt__=signOf)
1106
1106
  return DivMod2Tuple(q, self) # q is C{int} in Python 3+, but C{float} in Python 2-
1107
1107
 
1108
+ def _fhorner(self, x, cs, op): # in .fmath
1109
+ '''(INTERNAL) Add an L{Fhorner} evaluation of polynomial
1110
+ M{sum(cs[i] * x**i for i=0..len(cs)-1)}.
1111
+ '''
1112
+ if _xiterablen(cs):
1113
+ H = Fsum(name__=self._fhorner)
1114
+ if _isFsumTuple(x):
1115
+ _mul = H._mul_Fsum
1116
+ else:
1117
+ _mul = H._mul_scalar
1118
+ x = _2float(x=x)
1119
+ if len(cs) > 1 and x:
1120
+ for c in reversed(cs):
1121
+ H._fset_ps(_mul(x, op))
1122
+ H._fadd(c, op, up=False)
1123
+ else: # x == 0
1124
+ H = cs[0]
1125
+ self._fadd(H, op)
1126
+ return self
1127
+
1108
1128
  def _finite(self, other, op=None):
1109
1129
  '''(INTERNAL) Return B{C{other}} if C{finite}.
1110
1130
  '''
@@ -1149,7 +1169,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1149
1169
  '''
1150
1170
  return Fsum2Tuple(*self._fint2, **name)
1151
1171
 
1152
- @Property_RO
1172
+ @Property
1153
1173
  def _fint2(self): # see ._fset
1154
1174
  '''(INTERNAL) Get 2-tuple (C{int}, I{integer} residual).
1155
1175
  '''
@@ -1159,6 +1179,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1159
1179
  r = self._ps_1sum(i) if r and n > 1 else float(s - i)
1160
1180
  return i, (r or INT0) # Fsum2Tuple?
1161
1181
 
1182
+ @_fint2.setter_ # PYCHOK setter_underscore!
1183
+ def _fint2(self, s):
1184
+ '''(INTERNAL) Replace the C{_fint2} value.
1185
+ '''
1186
+ i = int(s)
1187
+ return i, ((s - i) or INT0)
1188
+
1162
1189
  @deprecated_property_RO
1163
1190
  def float_int(self): # PYCHOK no cover
1164
1191
  '''DEPRECATED, use method C{Fsum.int_float}.'''
@@ -1243,7 +1270,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1243
1270
  f = self._pow(other, other, op, **raiser_RESIDUAL)
1244
1271
  return self._fset(f) # n=max(len(self), 1)
1245
1272
 
1246
- @Property_RO
1273
+ @Property
1247
1274
  def _fprs(self):
1248
1275
  '''(INTERNAL) Get and cache this instance' precision
1249
1276
  running sum (C{float} or C{int}), ignoring C{residual}.
@@ -1254,7 +1281,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1254
1281
  s, _ = self._fprs2
1255
1282
  return s # ._fprs2.fsum
1256
1283
 
1257
- @Property_RO
1284
+ @_fprs.setter_ # PYCHOK setter_underscore!
1285
+ def _fprs(self, s):
1286
+ '''(INTERNAL) Replace the C{_fprs} value.
1287
+ '''
1288
+ return s
1289
+
1290
+ @Property
1258
1291
  def _fprs2(self):
1259
1292
  '''(INTERNAL) Get and cache this instance' precision
1260
1293
  running sum and residual (L{Fsum2Tuple}).
@@ -1278,6 +1311,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1278
1311
  # assert self._ps is ps
1279
1312
  return Fsum2Tuple(s, r)
1280
1313
 
1314
+ @_fprs2.setter_ # PYCHOK setter_underscore!
1315
+ def _fprs2(self, s_r):
1316
+ '''(INTERNAL) Replace the C{_fprs2} value.
1317
+ '''
1318
+ return Fsum2Tuple(s_r)
1319
+
1281
1320
  def fset_(self, *xs):
1282
1321
  '''Replace this instance' value with all positional items.
1283
1322
 
@@ -1310,27 +1349,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1310
1349
  s = float(self._finite(other, **op)) if op else other
1311
1350
  self._ps[:] = s,
1312
1351
  self._n = n or 1
1313
- if up:
1314
- i = int(s) # see ._fint2
1315
- t = i, ((s - i) or INT0)
1316
- # Property_ROs _fint2, _fprs and _fprs2 can't be a Property:
1317
- # Property's _fset zaps the value just set by the @setter
1318
- self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
1352
+ if up: # Property _fint2, _fprs and _fprs2 all have
1353
+ # @.setter_underscore and NOT @.setter because the
1354
+ # latter's _fset zaps the value set by @.setter
1355
+ self._fint2 = s
1356
+ self._fprs = s
1357
+ self._fprs2 = s, INT0
1358
+ # assert self._fprs is s
1319
1359
  else: # PYCHOK no cover
1320
- op = _xkwds_get(op, op=_fset_op_)
1360
+ op = _xkwds_get1(op, op=_fset_op_)
1321
1361
  raise self._Error(op, other, _TypeError)
1322
1362
  return self
1323
1363
 
1324
- def _fset_ps(self, other, n=0): # in .fmath
1364
+ def _fset_ps(self, other): # in .fmath
1325
1365
  '''(INTERNAL) Set partials from a known C{scalar}, L{Fsum} or L{Fsum2Tuple}.
1326
1366
  '''
1327
- if _isFsumTuple(other):
1328
- self._ps[:] = other._ps
1329
- self._n = n or other._n
1330
- else: # assert isscalar(other)
1331
- self._ps[:] = other,
1332
- self._n = n or 1
1333
- return self
1367
+ return self._fset(other, up=False)
1334
1368
 
1335
1369
  def fsub(self, xs=()):
1336
1370
  '''Subtract an iterable's items from this instance.
@@ -1765,7 +1799,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1765
1799
  return self._pow_2_3(s, x, other, op, **raiser_RESIDUAL)
1766
1800
 
1767
1801
  def _ps_acc(self, ps, xs, up=True, **unused):
1768
- '''(INTERNAL) Accumulate C{xs} scalars into list C{ps}.
1802
+ '''(INTERNAL) Accumulate C{xs} known scalars into list C{ps}.
1769
1803
  '''
1770
1804
  n = 0
1771
1805
  _2s = _2sum
@@ -2144,7 +2178,7 @@ try:
2144
2178
  # float.__getformat__('float')[:4] == 'IEEE'?)
2145
2179
  if _fsum((1, 1e101, 1, -1e101)) != 2: # PYCHOK no cover
2146
2180
  del _fsum # nope, remove _fsum ...
2147
- raise ImportError # ... use _fsum below
2181
+ raise ImportError() # ... use _fsum below
2148
2182
 
2149
2183
  Fsum._math_fsum = _sum = _fsum # PYCHOK exported
2150
2184
  except ImportError:
@@ -2192,7 +2226,7 @@ def fsum_(*xs, **floats):
2192
2226
 
2193
2227
  @see: Function L{fsum<fsums.fsum>} for further details.
2194
2228
  '''
2195
- return _fsum(xs if _xkwds_get(floats, floats=False) is True else
2229
+ return _fsum(xs if _xkwds_get1(floats, floats=False) is True else
2196
2230
  _2floats(xs, origin=1)) if xs else _0_0 # PYCHOK yield
2197
2231
 
2198
2232
 
@@ -2227,7 +2261,7 @@ def fsum1_(*xs, **floats):
2227
2261
 
2228
2262
  @see: Function L{fsum_<fsums.fsum_>} for further details.
2229
2263
  '''
2230
- return _fsum(_1primed(xs if _xkwds_get(floats, floats=False) is True else
2264
+ return _fsum(_1primed(xs if _xkwds_get1(floats, floats=False) is True else
2231
2265
  _2floats(xs, origin=1))) if xs else _0_0 # PYCHOK yield
2232
2266
 
2233
2267
 
@@ -23,7 +23,7 @@ from pygeodesy.karney import Caps, GeodesicError
23
23
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
24
24
 
25
25
  __all__ = _ALL_LAZY.geodesicx + _ALL_DOCS(Caps, GeodesicError)
26
- __version__ = '24.05.24'
26
+ __version__ = '24.05.31'
27
27
 
28
28
  # **) MIT License
29
29
  #
@@ -5,7 +5,7 @@ u'''Print L{geodesicx} version, etc. using C{python -m pygeodesy.geodesicx}.
5
5
  '''
6
6
 
7
7
  __all__ = ()
8
- __version__ = '24.05.13'
8
+ __version__ = '24.05.31'
9
9
 
10
10
 
11
11
  def _C4stats(nC4=None): # PYCHOK no cover
@@ -88,4 +88,4 @@ _main()
88
88
  # OTHER DEALINGS IN THE SOFTWARE.
89
89
 
90
90
  # % python3 -m pygeodesy.geodesicx
91
- # pygeodesy.geodesicx.version=21.05.30, .C4Order=None, .C4len=5425, .C4set=5107, .C4set100=94, .C4x=465 (Python 3.9.5, 64bit, geographiclib 1.52)
91
+ # pygeodesy.geodesicx.version=24.05.31, .C4len=5425, .C4order=30, .C4set=5107, .C4set_len=94.1%, .C4x=465 (Python 3.12.3, 64bit, arm64, geographiclib 2.0)
pygeodesy/geodesicx/gx.py CHANGED
@@ -62,7 +62,7 @@ from pygeodesy.utily import atan2d as _atan2d_reverse, _unrollon, _Wrap, wrap360
62
62
  from math import atan2, copysign, cos, degrees, fabs, radians, sqrt
63
63
 
64
64
  __all__ = ()
65
- __version__ = '24.05.20'
65
+ __version__ = '24.05.31'
66
66
 
67
67
  _MAXIT1 = 20
68
68
  _MAXIT2 = 10 + _MAXIT1 + MANT_DIG # MANT_DIG == C++ digits
@@ -150,9 +150,7 @@ class GeodesicExact(_GeodesicBase):
150
150
  @raise GeodesicError: Invalid B{C{C4order}}.
151
151
  '''
152
152
  if name_C4Order:
153
- C4Order, name = _xkwds_pop2(name_C4Order, C4Order=C4order)
154
- if C4Order: # for backward compatibility
155
- self.C4order = C4Order
153
+ C4order, name = _xkwds_pop2(name_C4Order, C4Order=C4order)
156
154
  if name:
157
155
  self.name = name
158
156
  else:
@@ -318,7 +316,7 @@ class GeodesicExact(_GeodesicBase):
318
316
  def _C4(nC4):
319
317
  i, n, cs = 0, self.n, _C4coeffs(nC4)
320
318
  _p = _polynomial
321
- for r in range(nC4 + 1, 1, -1):
319
+ for r in range(nC4 + 1, 1, -1): # _reverange
322
320
  for j in range(1, r):
323
321
  j = j + i # (j - i - 1) order of polynomial
324
322
  yield _p(n, cs, i, j) / cs[j]
pygeodesy/geodsolve.py CHANGED
@@ -26,7 +26,7 @@ from pygeodesy.solveBase import _SolveBase, _SolveLineBase
26
26
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
27
27
 
28
28
  __all__ = _ALL_LAZY.geodsolve
29
- __version__ = '24.05.23'
29
+ __version__ = '24.06.04'
30
30
 
31
31
 
32
32
  class GeodSolve12Tuple(_GTuple):
@@ -59,11 +59,11 @@ class _GeodesicSolveBase(_SolveBase):
59
59
  def _cmdBasic(self):
60
60
  '''(INTERNAL) Get the basic C{GeodSolve} cmd (C{tuple}).
61
61
  '''
62
- return (self.GeodSolve,) + self._b_option \
63
- + self._e_option \
64
- + self._E_option \
65
- + self._p_option \
66
- + self._u_option + ('-f',)
62
+ return (self.GeodSolve, '-f') + (self._b_option +
63
+ self._e_option +
64
+ self._E_option +
65
+ self._p_option +
66
+ self._u_option)
67
67
 
68
68
  @Property_RO
69
69
  def _E_option(self):
@@ -262,7 +262,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
262
262
  _xinstanceof(GeodesicSolve, geodesic=geodesic)
263
263
  if (caps & Caps.LINE_OFF): # copy to avoid updates
264
264
  geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name)) # NOT _under!
265
- _SolveLineBase.__init__(self, geodesic, lat1, lon1, caps, name, azi1=azi1)
265
+ _SolveLineBase.__init__(self, geodesic, lat1, lon1, caps, azi1=azi1, **name)
266
266
  try:
267
267
  self.GeodSolve = geodesic.GeodSolve # geodesic or copy of geodesic
268
268
  except GeodesicError:
@@ -362,49 +362,47 @@ if __name__ == '__main__':
362
362
  p = glS.ArcPosition(49.475527)
363
363
  printf('ArcPosition: %s %r', p == r, p)
364
364
 
365
- # % python3 -m pygeodesy.geodsolve
366
365
 
367
- # version: /opt/local/bin/GeodSolve: GeographicLib version 1.51
366
+ # % python3 -m pygeodesy.geodsolve
368
367
 
369
- # version: /opt/local/bin/GeodSolve: GeographicLib version 1.51
368
+ # version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
370
369
 
371
- # Direct: GDict(M12=0.650911, M21=0.651229, S12=39735075134877.09375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, s12=5500000.0)
370
+ # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
372
371
  # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
373
372
 
374
- # Inverse: GDict(M12=0.64473, M21=0.645046, S12=40041368848742.53125, a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, s12=5551759.400319)
373
+ # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
375
374
  # Inverse1: 49.94131021789904
376
375
  # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
377
376
 
378
- # Position: True GDict(M12=0.650911, M21=0.651229, S12=39735075134877.09375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, s12=5500000.0)
379
- # ArcPosition: False GDict(M12=0.650911, M21=0.651229, S12=39735074737272.734375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, s12=5499999.948497)
377
+ # Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
378
+ # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
380
379
 
381
380
 
382
381
  # % python3 -m pygeodesy.geodsolve --verbose
383
382
 
384
383
  # GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve --version (invoke)
385
- # GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve: GeographicLib version 1.51 (0)
386
- # version: /opt/local/bin/GeodSolve: GeographicLib version 1.51
387
- # GeodesicSolve 'Test' 2: /opt/local/bin/GeodSolve -E -p 10 -f \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
384
+ # GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve: GeographicLib version 2.2 (0)
385
+ # version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
386
+ # GeodesicSolve 'Test' 2: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
388
387
  # GeodesicSolve 'Test' 2: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
389
388
 
390
- # Direct: GDict(M12=0.650911, M21=0.651229, S12=39735075134877.09375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, s12=5500000.0)
391
- # GeodesicSolve 'Test' 3: /opt/local/bin/GeodSolve -E -p 10 -f \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
389
+ # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
390
+ # GeodesicSolve 'Test' 3: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
392
391
  # GeodesicSolve 'Test' 3: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
393
392
  # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
394
- # GeodesicSolve 'Test' 4: /opt/local/bin/GeodSolve -E -p 10 -f -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
393
+ # GeodesicSolve 'Test' 4: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
395
394
  # GeodesicSolve 'Test' 4: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
396
395
 
397
- # Inverse: GDict(M12=0.64473, M21=0.645046, S12=40041368848742.53125, a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, s12=5551759.400319)
398
- # GeodesicSolve 'Test' 5: /opt/local/bin/GeodSolve -E -p 10 -f -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
396
+ # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
397
+ # GeodesicSolve 'Test' 5: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
399
398
  # GeodesicSolve 'Test' 5: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
400
399
  # Inverse1: 49.94131021789904
401
- # GeodesicSolve 'Test' 6: /opt/local/bin/GeodSolve -E -p 10 -f -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
400
+ # GeodesicSolve 'Test' 6: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
402
401
  # GeodesicSolve 'Test' 6: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
403
402
  # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
404
403
 
405
- # Position: True GDict(M12=0.650911, M21=0.651229, S12=39735075134877.09375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, s12=5500000.0)
406
- # ArcPosition: False GDict(M12=0.650911, M21=0.651229, S12=39735074737272.734375, a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, s12=5499999.948497)
407
-
404
+ # Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
405
+ # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
408
406
 
409
407
  # **) MIT License
410
408
  #
pygeodesy/geohash.py CHANGED
@@ -30,7 +30,7 @@ from pygeodesy.named import _name__, _NamedDict, _NamedTuple, nameof, _xnamed
30
30
  from pygeodesy.namedTuples import Bounds2Tuple, Bounds4Tuple, LatLon2Tuple, \
31
31
  PhiLam2Tuple
32
32
  from pygeodesy.props import deprecated_function, deprecated_method, \
33
- deprecated_property_RO, Property_RO, property_RO
33
+ deprecated_property_RO, Property_RO
34
34
  from pygeodesy.streprs import fstr
35
35
  from pygeodesy.units import Degrees_, Int, Lat, Lon, Precision_, Str, \
36
36
  _xStrError
@@ -38,7 +38,9 @@ from pygeodesy.units import Degrees_, Int, Lat, Lon, Precision_, Str, \
38
38
  from math import fabs, ldexp, log10, radians
39
39
 
40
40
  __all__ = _ALL_LAZY.geohash
41
- __version__ = '24.05.23'
41
+ __version__ = '24.06.10'
42
+
43
+ _formy = _MODS.into(formy=__name__)
42
44
 
43
45
 
44
46
  class _GH(object):
@@ -297,29 +299,28 @@ class Geohash(Str):
297
299
  using function L{pygeodesy.equirectangular}.
298
300
 
299
301
  @arg other: The other geohash (L{Geohash}, C{LatLon} or C{str}).
300
- @kwarg radius: Mean earth radius, ellipsoid or datum
301
- (C{meter}, L{Ellipsoid}, L{Ellipsoid2},
302
- L{Datum} or L{a_f2Tuple}) or C{None}.
303
- @kwarg adjust_limit_wrap: Optional keyword arguments for
304
- function L{pygeodesy.equirectangular_},
305
- overriding defaults C{B{adjust}=False,
306
- B{limit}=None} and C{B{wrap}=False}.
302
+ @kwarg radius: Mean earth radius, ellipsoid or datum (C{meter},
303
+ L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or
304
+ L{a_f2Tuple}) or C{None}, see function
305
+ L{pygeodesy.equirectangular}.
306
+ @kwarg adjust_limit_wrap: Optional keyword arguments for function
307
+ L{pygeodesy.equirectangular4}, overriding defaults
308
+ C{B{adjust}=False, B{limit}=None} and C{B{wrap}=False}.
307
309
 
308
310
  @return: Distance (C{meter}, same units as B{C{radius}} or the
309
311
  ellipsoid or datum axes or C{radians I{squared}} if
310
312
  B{C{radius}} is C{None} or C{0}).
311
313
 
312
- @raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon}
313
- or C{str} or invalid B{C{radius}}.
314
+ @raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon} or
315
+ C{str} or invalid B{C{radius}}.
314
316
 
315
317
  @see: U{Local, flat earth approximation
316
318
  <https://www.EdWilliams.org/avform.htm#flat>}, functions
317
319
  '''
318
320
  lls = self.latlon + _2Geohash(other).latlon
319
321
  kwds = _xkwds(adjust_limit_wrap, adjust=False, limit=None, wrap=False)
320
- m = self._formy
321
- return m.equirectangular( *lls, radius=radius, **kwds) if radius else \
322
- m.equirectangular_(*lls, **kwds).distance2
322
+ return _formy.equirectangular( *lls, radius=radius, **kwds) if radius else \
323
+ _formy.equirectangular4(*lls, **kwds).distance2
323
324
 
324
325
  def euclideanTo(self, other, **radius_adjust_wrap):
325
326
  '''Approximate the distance between this and an other geohash using
@@ -335,14 +336,7 @@ class Geohash(Str):
335
336
  @raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon}
336
337
  or C{str} or invalid B{C{radius}}.
337
338
  '''
338
- return self._distanceTo(self._formy.euclidean, other, **radius_adjust_wrap)
339
-
340
- @property_RO
341
- def _formy(self):
342
- '''(INTERNAL) Get the C{.formy} module, I{once}.
343
- '''
344
- Geohash._formy = f = _MODS.formy # overwrite property_RO
345
- return f
339
+ return self._distanceTo(_formy.euclidean, other, **radius_adjust_wrap)
346
340
 
347
341
  def haversineTo(self, other, **radius_wrap):
348
342
  '''Compute the distance between this and an other geohash using
@@ -358,7 +352,7 @@ class Geohash(Str):
358
352
  @raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon}
359
353
  or C{str} or invalid B{C{radius}}.
360
354
  '''
361
- return self._distanceTo(self._formy.haversine, other, **radius_wrap)
355
+ return self._distanceTo(_formy.haversine, other, **radius_wrap)
362
356
 
363
357
  @Property_RO
364
358
  def latlon(self):
@@ -431,7 +425,7 @@ class Geohash(Str):
431
425
  @raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon}
432
426
  or C{str} or invalid B{C{radius}}.
433
427
  '''
434
- return self._distanceTo(self._formy.vincentys, other, **radius_wrap)
428
+ return self._distanceTo(_formy.vincentys, other, **radius_wrap)
435
429
 
436
430
  @Property_RO
437
431
  def N(self):
@@ -645,8 +639,8 @@ def distance1(geohash1, geohash2):
645
639
 
646
640
  @deprecated_function
647
641
  def distance2(geohash1, geohash2):
648
- '''DEPRECATED, use L{geohash.equirectangular_}.'''
649
- return equirectangular_(geohash1, geohash2)
642
+ '''DEPRECATED, use L{geohash.equirectangular4}.'''
643
+ return equirectangular4(geohash1, geohash2)
650
644
 
651
645
 
652
646
  @deprecated_function
@@ -718,7 +712,7 @@ def encode(lat, lon, precision=None):
718
712
  return NN.join(gh)
719
713
 
720
714
 
721
- def equirectangular_(geohash1, geohash2, radius=R_M):
715
+ def equirectangular4(geohash1, geohash2, radius=R_M):
722
716
  '''Approximate the distance between two geohashes using the
723
717
  L{pygeodesy.equirectangular} formula.
724
718
 
@@ -803,18 +797,11 @@ def precision(res1, res2=None):
803
797
  <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Geohash.html>}.
804
798
  '''
805
799
  r = Degrees_(res1=res1, low=_0_0, Error=GeohashError)
806
- if res2 is None:
807
- t = r, r
808
- for p in range(1, _MaxPrec):
809
- if resolution2(p, None) <= t:
810
- return p
811
-
812
- else:
813
- t = r, Degrees_(res2=res2, low=_0_0, Error=GeohashError)
814
- for p in range(1, _MaxPrec):
815
- if resolution2(p, p) <= t:
816
- return p
817
-
800
+ N = res2 is None
801
+ t = r, (r if N else Degrees_(res2=res2, low=_0_0, Error=GeohashError))
802
+ for p in range(1, _MaxPrec):
803
+ if resolution2(p, (None if N else p)) <= t:
804
+ return p
818
805
  return _MaxPrec
819
806
 
820
807
 
@@ -891,7 +878,7 @@ def vincentys_(geohash1, geohash2, **radius_wrap):
891
878
 
892
879
  __all__ += _ALL_OTHER(bounds, # functions
893
880
  decode, decode2, decode_error, distance_,
894
- encode, equirectangular_, euclidean_, haversine_,
881
+ encode, equirectangular4, euclidean_, haversine_,
895
882
  neighbors, precision, resolution2, sizes, vincentys_)
896
883
 
897
884
  # **) MIT License
pygeodesy/geoids.py CHANGED
@@ -118,7 +118,7 @@ except ImportError: # Python 3+
118
118
  from io import BytesIO as _BytesIO # PYCHOK expected
119
119
 
120
120
  __all__ = _ALL_LAZY.geoids
121
- __version__ = '24.05.23'
121
+ __version__ = '24.06.03'
122
122
 
123
123
  _assert_ = 'assert'
124
124
  _bHASH_ = b'#'
pygeodesy/hausdorff.py CHANGED
@@ -77,7 +77,7 @@ from pygeodesy.lazily import _ALL_LAZY, _FOR_DOCS
77
77
  from pygeodesy.named import _name2__, _Named, _NamedTuple, _Pass
78
78
  # from pygeodesy.namedTuples import PhiLam2Tuple # from .points
79
79
  from pygeodesy.points import _distanceTo, points2 as _points2, PhiLam2Tuple, radians
80
- from pygeodesy.props import Property_RO, property_doc_, property_RO
80
+ from pygeodesy.props import Property, Property_RO, property_doc_, property_RO
81
81
  from pygeodesy.units import Float, Number_, _xUnit, _xUnits
82
82
  from pygeodesy.unitsBase import _Str_degrees, _Str_degrees2, _Str_meter, _Str_NN, \
83
83
  _Str_radians, _Str_radians2
@@ -86,7 +86,7 @@ from pygeodesy.unitsBase import _Str_degrees, _Str_degrees2, _Str_meter, _Str_NN
86
86
  from random import Random
87
87
 
88
88
  __all__ = _ALL_LAZY.hausdorff
89
- __version__ = '24.05.24'
89
+ __version__ = '24.06.08'
90
90
 
91
91
 
92
92
  class HausdorffError(PointsError):
@@ -179,14 +179,14 @@ class Hausdorff(_Named):
179
179
  return self._func(point1.lat, point1.lon,
180
180
  point2.lat, point2.lon, **self._kwds)
181
181
 
182
- @property
182
+ @Property
183
183
  def _func(self):
184
184
  '''(INTERNAL) I{Must be overloaded}.'''
185
- return _formy._Propy(self, 0, _func=None)
185
+ self._notOverloaded(**self.kwds)
186
186
 
187
- @_func.setter # PYCHOK setter!
187
+ @_func.setter_ # PYCHOK setter_underscore!
188
188
  def _func(self, func):
189
- _formy._Propy(self, 4, _func=func)
189
+ return _formy._Propy(func, 4, self.kwds)
190
190
 
191
191
  def _hausdorff_(self, point2s, both, early, distance):
192
192
  _, ps2 = self._points2(point2s)
@@ -341,14 +341,14 @@ class _HausdorffMeterRadians(Hausdorff):
341
341
  '''
342
342
  return self._hausdorff_(point2s, True, early, _formy._radistance(self))
343
343
 
344
- @property
344
+ @Property
345
345
  def _func_(self):
346
346
  '''(INTERNAL) I{Must be overloaded}.'''
347
- return _formy._Propy(self, 0, _func_=None)
347
+ self._notOverloaded(**self.kwds)
348
348
 
349
- @_func_.setter # PYCHOK setter!
349
+ @_func_.setter_ # PYCHOK setter_underscore!
350
350
  def _func_(self, func):
351
- _formy._Propy(self, 3,_func_=func)
351
+ return _formy._Propy(func, 3, self.kwds)
352
352
 
353
353
 
354
354
  class HausdorffCosineAndoyerLambert(_HausdorffMeterRadians):
@@ -462,7 +462,7 @@ class HausdorffDistanceTo(Hausdorff):
462
462
 
463
463
  class HausdorffEquirectangular(Hausdorff):
464
464
  '''Compute the C{Hausdorff} distance based on the C{equirectangular} distance
465
- in C{radians squared} like function L{pygeodesy.equirectangular_}.
465
+ in C{radians squared} like function L{pygeodesy.equirectangular}.
466
466
  '''
467
467
  _units = _Str_degrees2
468
468
 
@@ -471,7 +471,7 @@ class HausdorffEquirectangular(Hausdorff):
471
471
 
472
472
  @kwarg seed_name__adjust_limit_wrap: Optional C{B{seed}=None} and
473
473
  C{B{name}=NN} and keyword arguments for function
474
- L{pygeodesy.equirectangular_} I{with default}
474
+ L{pygeodesy.equirectangular} I{with default}
475
475
  C{B{limit}=0} for I{backward compatibility}.
476
476
 
477
477
  @see: L{Hausdorff.__init__} for details about B{C{point1s}},
@@ -819,14 +819,13 @@ class Hausdorff6Tuple(_NamedTuple):
819
819
  _Names_ = ('hd', _i_, _j_, 'mn', 'md', _units_)
820
820
  _Units_ = (_Pass, Number_, Number_, Number_, _Pass, _Pass)
821
821
 
822
- def toUnits(self, **Error): # PYCHOK expected
822
+ def toUnits(self, **Error_name): # PYCHOK expected
823
823
  '''Overloaded C{_NamedTuple.toUnits} for C{hd} and C{md} units.
824
824
  '''
825
- U = _xUnit(self.units, Float) # PYCHOK expected
826
- M = _Pass if self.md is None else U # PYCHOK expected
827
- self._Units_ = (U,) + Hausdorff6Tuple._Units_[1:4] \
828
- + (M,) + Hausdorff6Tuple._Units_[5:]
829
- return _NamedTuple.toUnits(self, **Error)
825
+ u = list(Hausdorff6Tuple._Units_)
826
+ u[0] = U = _xUnit(self.units, Float) # PYCHOK expected
827
+ u[4] = _Pass if self.md is None else U # PYCHOK expected
828
+ return _NamedTuple.toUnits(self.reUnit(*u), **Error_name) # PYCHOK self
830
829
 
831
830
 
832
831
  def randomrangenerator(seed):