pygeodesy 24.5.8__py2.py3-none-any.whl → 24.5.24__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 (83) hide show
  1. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.5.24.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +16 -12
  4. pygeodesy/__main__.py +9 -10
  5. pygeodesy/albers.py +42 -42
  6. pygeodesy/auxilats/__init__.py +1 -1
  7. pygeodesy/auxilats/__main__.py +7 -10
  8. pygeodesy/auxilats/auxAngle.py +32 -31
  9. pygeodesy/auxilats/auxLat.py +81 -51
  10. pygeodesy/azimuthal.py +123 -124
  11. pygeodesy/basics.py +165 -176
  12. pygeodesy/booleans.py +14 -15
  13. pygeodesy/cartesianBase.py +25 -23
  14. pygeodesy/clipy.py +3 -3
  15. pygeodesy/constants.py +8 -6
  16. pygeodesy/css.py +50 -42
  17. pygeodesy/datums.py +50 -48
  18. pygeodesy/dms.py +6 -6
  19. pygeodesy/ecef.py +27 -27
  20. pygeodesy/elevations.py +2 -2
  21. pygeodesy/ellipsoidalBase.py +28 -27
  22. pygeodesy/ellipsoidalBaseDI.py +8 -7
  23. pygeodesy/ellipsoidalNvector.py +11 -12
  24. pygeodesy/ellipsoids.py +41 -35
  25. pygeodesy/elliptic.py +12 -10
  26. pygeodesy/epsg.py +4 -3
  27. pygeodesy/errors.py +35 -13
  28. pygeodesy/etm.py +62 -53
  29. pygeodesy/fmath.py +48 -41
  30. pygeodesy/formy.py +93 -65
  31. pygeodesy/frechet.py +117 -102
  32. pygeodesy/fstats.py +52 -46
  33. pygeodesy/fsums.py +169 -145
  34. pygeodesy/gars.py +10 -9
  35. pygeodesy/geodesicw.py +32 -30
  36. pygeodesy/geodesicx/__init__.py +1 -1
  37. pygeodesy/geodesicx/__main__.py +4 -4
  38. pygeodesy/geodesicx/gx.py +40 -32
  39. pygeodesy/geodesicx/gxarea.py +15 -12
  40. pygeodesy/geodesicx/gxbases.py +3 -4
  41. pygeodesy/geodesicx/gxline.py +6 -8
  42. pygeodesy/geodsolve.py +28 -26
  43. pygeodesy/geohash.py +47 -44
  44. pygeodesy/geoids.py +37 -35
  45. pygeodesy/hausdorff.py +112 -99
  46. pygeodesy/heights.py +136 -129
  47. pygeodesy/internals.py +576 -0
  48. pygeodesy/interns.py +6 -207
  49. pygeodesy/iters.py +22 -19
  50. pygeodesy/karney.py +18 -15
  51. pygeodesy/ktm.py +31 -24
  52. pygeodesy/latlonBase.py +12 -11
  53. pygeodesy/lazily.py +140 -218
  54. pygeodesy/lcc.py +24 -25
  55. pygeodesy/ltp.py +83 -71
  56. pygeodesy/ltpTuples.py +7 -5
  57. pygeodesy/mgrs.py +5 -4
  58. pygeodesy/named.py +136 -49
  59. pygeodesy/namedTuples.py +33 -25
  60. pygeodesy/nvectorBase.py +10 -9
  61. pygeodesy/osgr.py +14 -12
  62. pygeodesy/points.py +13 -13
  63. pygeodesy/props.py +7 -7
  64. pygeodesy/rhumb/__init__.py +1 -1
  65. pygeodesy/rhumb/bases.py +3 -2
  66. pygeodesy/rhumb/solve.py +2 -2
  67. pygeodesy/solveBase.py +8 -7
  68. pygeodesy/sphericalTrigonometry.py +5 -5
  69. pygeodesy/streprs.py +8 -7
  70. pygeodesy/trf.py +8 -8
  71. pygeodesy/triaxials.py +67 -63
  72. pygeodesy/units.py +48 -50
  73. pygeodesy/unitsBase.py +24 -11
  74. pygeodesy/ups.py +7 -6
  75. pygeodesy/utily.py +4 -4
  76. pygeodesy/utm.py +53 -52
  77. pygeodesy/utmupsBase.py +11 -8
  78. pygeodesy/vector2d.py +6 -7
  79. pygeodesy/vector3d.py +16 -17
  80. pygeodesy/vector3dBase.py +5 -5
  81. PyGeodesy-24.5.8.dist-info/RECORD +0 -115
  82. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
  83. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/geodsolve.py CHANGED
@@ -10,23 +10,23 @@ of the C{GeodSolve} executable.
10
10
  '''
11
11
 
12
12
  from pygeodesy.basics import _xinstanceof
13
- # from pygeodesy.errors import _xkwds # from .karney
14
13
  # from pygeodesy.geodesicx import GeodesicAreaExact # _MODS
15
14
  from pygeodesy.interns import NN, _a12_, _azi1_, _azi2_, \
16
15
  _lat1_, _lat2_, _lon1_, _lon2_, _m12_, \
17
16
  _M12_, _M21_, _s12_, _S12_, _UNDER_
18
17
  from pygeodesy.interns import _UNUSED_, _not_ # PYCHOK used!
19
18
  from pygeodesy.karney import _Azi, Caps, _Deg, GeodesicError, _GTuple, \
20
- _Pass, _Lat, _Lon, _M, _M2, _sincos2d, _xkwds
19
+ _Pass, _Lat, _Lon, _M, _M2, _sincos2d
21
20
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, \
22
- _PYGEODESY_GEODSOLVE_, _getenv, printf
21
+ _getenv, _PYGEODESY_GEODSOLVE_
22
+ from pygeodesy.named import _name1__
23
23
  from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
24
24
  from pygeodesy.props import Property, Property_RO
25
25
  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.04.07'
29
+ __version__ = '24.05.23'
30
30
 
31
31
 
32
32
  class GeodSolve12Tuple(_GTuple):
@@ -116,21 +116,20 @@ class GeodesicSolve(_GeodesicSolveBase):
116
116
  executable for I{every} method call.
117
117
  '''
118
118
 
119
- def Area(self, polyline=False, name=NN):
119
+ def Area(self, polyline=False, **name):
120
120
  '''Set up a L{GeodesicAreaExact} to compute area and
121
121
  perimeter of a polygon.
122
122
 
123
123
  @kwarg polyline: If C{True} perimeter only, otherwise
124
124
  area and perimeter (C{bool}).
125
- @kwarg name: Optional name (C{str}).
125
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
126
126
 
127
127
  @return: A L{GeodesicAreaExact} instance.
128
128
 
129
129
  @note: The B{C{debug}} setting is passed as C{verbose}
130
130
  to the returned L{GeodesicAreaExact} instance.
131
131
  '''
132
- gaX = _MODS.geodesicx.GeodesicAreaExact(self, polyline=polyline,
133
- name=name or self.name)
132
+ gaX = _MODS.geodesicx.GeodesicAreaExact(self, polyline=polyline, **name)
134
133
  if self.verbose or self.debug: # PYCHOK no cover
135
134
  gaX.verbose = True
136
135
  return gaX
@@ -159,9 +158,10 @@ class GeodesicSolve(_GeodesicSolveBase):
159
158
  @arg lat1: Latitude of the first point (C{degrees}).
160
159
  @arg lon1: Longitude of the first point (C{degrees}).
161
160
  @arg azi1: Azimuth at the first point (compass C{degrees}).
162
- @kwarg caps_name: Bit-or'ed combination of L{Caps} values specifying
163
- the capabilities the L{GeodesicLineSolve} instance should
164
- possess, C{caps=Caps.ALL} always.
161
+ @kwarg caps_name: Optional C{B{name}=NN} (C{str}) and keyword
162
+ argument C{B{caps}=Caps.ALL}, bit-or'ed combination
163
+ of L{Caps} values specifying the capabilities the
164
+ L{GeodesicLineSolve} instance should possess.
165
165
 
166
166
  @return: A L{GeodesicLineSolve} instance.
167
167
 
@@ -173,7 +173,7 @@ class GeodesicSolve(_GeodesicSolveBase):
173
173
  <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>}
174
174
  and Python U{Geodesic.Line<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
175
175
  '''
176
- return GeodesicLineSolve(self, lat1, lon1, azi1, **_xkwds(caps_name, name=self.name))
176
+ return GeodesicLineSolve(self, lat1, lon1, azi1, **_name1__(caps_name, _or_nameof=self))
177
177
 
178
178
  Line = DirectLine
179
179
 
@@ -209,9 +209,10 @@ class GeodesicSolve(_GeodesicSolveBase):
209
209
  @arg lon1: Longitude of the first point (C{degrees}).
210
210
  @arg lat2: Latitude of the second point (C{degrees}).
211
211
  @arg lon2: Longitude of the second point (C{degrees}).
212
- @kwarg caps_name: Bit-or'ed combination of L{Caps} values specifying
213
- the capabilities the L{GeodesicLineSolve} instance should
214
- possess, C{caps=Caps.ALL} always.
212
+ @kwarg caps_name: Optional C{B{name}=NN} (C{str}) and keyword
213
+ argument C{B{caps}=Caps.ALL}, bit-or'ed combination
214
+ of L{Caps} values specifying the capabilities the
215
+ L{GeodesicLineSolve} instance should possess.
215
216
 
216
217
  @return: A L{GeodesicLineSolve} instance.
217
218
 
@@ -222,7 +223,7 @@ class GeodesicSolve(_GeodesicSolveBase):
222
223
  Python U{Geodesic.InverseLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
223
224
  '''
224
225
  r = self.Inverse(lat1, lon1, lat2, lon2)
225
- return GeodesicLineSolve(self, lat1, lon1, r.azi1, **_xkwds(caps_name, name=self.name))
226
+ return GeodesicLineSolve(self, lat1, lon1, r.azi1, **_name1__(caps_name, _or_nameof=self))
226
227
 
227
228
 
228
229
  class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
@@ -237,7 +238,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
237
238
  executable for I{every} method call.
238
239
  '''
239
240
 
240
- def __init__(self, geodesic, lat1, lon1, azi1, caps=Caps.ALL, name=NN):
241
+ def __init__(self, geodesic, lat1, lon1, azi1, caps=Caps.ALL, **name):
241
242
  '''New L{GeodesicLineSolve} instance, allowing points to be found along
242
243
  a geodesic starting at C{(B{lat1}, B{lon1})} with azimuth B{C{azi1}}.
243
244
 
@@ -245,14 +246,14 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
245
246
  @arg lat1: Latitude of the first point (C{degrees}).
246
247
  @arg lon1: Longitude of the first point (C{degrees}).
247
248
  @arg azi1: Azimuth at the first points (compass C{degrees}).
248
- @kwarg caps: Bit-or'ed combination of L{Caps} values specifying
249
- the capabilities the L{GeodesicLineSolve} instance
250
- should possess, always C{Caps.ALL}. Use C{Caps.LINE_OFF}
251
- if updates to the B{C{geodesic}} should I{not} be
252
- reflected in this L{GeodesicLineSolve} instance.
253
- @kwarg name: Optional name (C{str}).
254
-
255
- @raise GeodesicError: Invalid path for the C{GeodSolve} executable or
249
+ @kwarg caps: Bit-or'ed combination of L{Caps} values specifying the
250
+ capabilities the L{GeodesicLineSolve} instance should possess,
251
+ C{B{caps}=Caps.ALL} always. Include C{Caps.LINE_OFF} if
252
+ updates to the B{C{geodesic}} should I{not} be reflected in
253
+ this L{GeodesicLineSolve} instance.
254
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
255
+
256
+ @raise GeodesicError: Invalid path for the C{GeodSolve} executable
256
257
  or isn't the C{GeodSolve} executable, see
257
258
  property C{geodesic.GeodSolve}.
258
259
 
@@ -260,7 +261,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
260
261
  '''
261
262
  _xinstanceof(GeodesicSolve, geodesic=geodesic)
262
263
  if (caps & Caps.LINE_OFF): # copy to avoid updates
263
- geodesic = geodesic.copy(deep=False, name=NN(_UNDER_, geodesic.name))
264
+ geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name)) # NOT _under!
264
265
  _SolveLineBase.__init__(self, geodesic, lat1, lon1, caps, name, azi1=azi1)
265
266
  try:
266
267
  self.GeodSolve = geodesic.GeodSolve # geodesic or copy of geodesic
@@ -337,6 +338,7 @@ __all__ += _ALL_DOCS(_GeodesicSolveBase)
337
338
 
338
339
  if __name__ == '__main__':
339
340
 
341
+ from pygeodesy import printf
340
342
  from sys import argv
341
343
 
342
344
  gS = GeodesicSolve(name='Test')
pygeodesy/geohash.py CHANGED
@@ -26,9 +26,9 @@ from pygeodesy.fmath import favg
26
26
  from pygeodesy.interns import NN, _COMMA_, _DOT_, _E_, _N_, _NE_, _NW_, \
27
27
  _S_, _SE_, _SW_, _W_
28
28
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _ALL_OTHER
29
- from pygeodesy.named import _NamedDict, _NamedTuple, nameof, _xnamed
30
- from pygeodesy.namedTuples import Bounds2Tuple, Bounds4Tuple, \
31
- LatLon2Tuple, PhiLam2Tuple
29
+ from pygeodesy.named import _name__, _NamedDict, _NamedTuple, nameof, _xnamed
30
+ from pygeodesy.namedTuples import Bounds2Tuple, Bounds4Tuple, LatLon2Tuple, \
31
+ PhiLam2Tuple
32
32
  from pygeodesy.props import deprecated_function, deprecated_method, \
33
33
  deprecated_property_RO, Property_RO, property_RO
34
34
  from pygeodesy.streprs import fstr
@@ -38,7 +38,7 @@ 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__ = '23.12.18'
41
+ __version__ = '24.05.23'
42
42
 
43
43
 
44
44
  class _GH(object):
@@ -71,34 +71,35 @@ class _GH(object):
71
71
  @Property_RO
72
72
  def Sizes(self): # lat-, lon and radial size (in meter)
73
73
  # ... where radial = sqrt(latSize * lonWidth / PI)
74
- return (_floatuple(20032e3, 20000e3, 11292815.096), # 0
75
- _floatuple( 5003e3, 5000e3, 2821794.075), # 1
76
- _floatuple( 650e3, 1225e3, 503442.397), # 2
77
- _floatuple( 156e3, 156e3, 88013.575), # 3
78
- _floatuple( 19500, 39100, 15578.683), # 4
79
- _floatuple( 4890, 4890, 2758.887), # 5
80
- _floatuple( 610, 1220, 486.710), # 6
81
- _floatuple( 153, 153, 86.321), # 7
82
- _floatuple( 19.1, 38.2, 15.239), # 8
83
- _floatuple( 4.77, 4.77, 2.691), # 9
84
- _floatuple( 0.596, 1.19, 0.475), # 10
85
- _floatuple( 0.149, 0.149, 0.084), # 11
86
- _floatuple( 0.0186, 0.0372, 0.015)) # 12 _MaxPrec
74
+ _t = _floatuple
75
+ return (_t(20032e3, 20000e3, 11292815.096), # 0
76
+ _t( 5003e3, 5000e3, 2821794.075), # 1
77
+ _t( 650e3, 1225e3, 503442.397), # 2
78
+ _t( 156e3, 156e3, 88013.575), # 3
79
+ _t( 19500, 39100, 15578.683), # 4
80
+ _t( 4890, 4890, 2758.887), # 5
81
+ _t( 610, 1220, 486.710), # 6
82
+ _t( 153, 153, 86.321), # 7
83
+ _t( 19.1, 38.2, 15.239), # 8
84
+ _t( 4.77, 4.77, 2.691), # 9
85
+ _t( 0.596, 1.19, 0.475), # 10
86
+ _t( 0.149, 0.149, 0.084), # 11
87
+ _t( 0.0186, 0.0372, 0.015)) # 12 _MaxPrec
87
88
 
88
89
  _GH = _GH() # PYCHOK singleton
89
90
  _MaxPrec = 12
90
91
 
91
92
 
92
- def _2bounds(LatLon, LatLon_kwds, s, w, n, e, name=NN):
93
+ def _2bounds(LatLon, LatLon_kwds, s, w, n, e, **name):
93
94
  '''(INTERNAL) Return SW and NE bounds.
94
95
  '''
95
96
  if LatLon is None:
96
- r = Bounds4Tuple(s, w, n, e, name=name)
97
+ r = Bounds4Tuple(s, w, n, e, **name)
97
98
  else:
98
- sw = _xnamed(LatLon(s, w, **LatLon_kwds), name)
99
- ne = _xnamed(LatLon(n, e, **LatLon_kwds), name)
100
- r = Bounds2Tuple(sw, ne, name=name)
101
- return r # _xnamed(r, name)
99
+ kwds = _xkwds(LatLon_kwds, **name)
100
+ r = Bounds2Tuple(LatLon(s, w, **kwds),
101
+ LatLon(n, e, **kwds), **name)
102
+ return r
102
103
 
103
104
 
104
105
  def _2center(bounds):
@@ -128,11 +129,11 @@ def _2geostr(geohash):
128
129
  '''
129
130
  try:
130
131
  if not (0 < len(geohash) <= _MaxPrec):
131
- raise ValueError
132
+ raise ValueError()
132
133
  geostr = geohash.lower()
133
134
  for c in geostr:
134
135
  if c not in _GH.DecodedBase32:
135
- raise ValueError
136
+ raise ValueError()
136
137
  return geostr
137
138
  except (AttributeError, TypeError, ValueError) as x:
138
139
  raise GeohashError(Geohash.__name__, geohash, cause=x)
@@ -142,7 +143,7 @@ class Geohash(Str):
142
143
  '''Geohash class, a named C{str}.
143
144
  '''
144
145
  # no str.__init__ in Python 3
145
- def __new__(cls, cll, precision=None, name=NN):
146
+ def __new__(cls, cll, precision=None, **name):
146
147
  '''New L{Geohash} from an other L{Geohash} instance or C{str}
147
148
  or from a C{LatLon} instance or C{str}.
148
149
 
@@ -150,7 +151,7 @@ class Geohash(Str):
150
151
  @kwarg precision: Optional, the desired geohash length (C{int}
151
152
  1..12), see function L{geohash.encode} for
152
153
  some examples.
153
- @kwarg name: Optional name (C{str}).
154
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
154
155
 
155
156
  @return: New L{Geohash}.
156
157
 
@@ -177,7 +178,7 @@ class Geohash(Str):
177
178
  except AttributeError:
178
179
  raise _xStrError(Geohash, cll=cll, Error=GeohashError)
179
180
 
180
- self = Str.__new__(cls, gh, name=name or nameof(cll))
181
+ self = Str.__new__(cls, gh, name=_name__(name, _or_nameof=cll))
181
182
  self._latlon = ll
182
183
  return self
183
184
 
@@ -186,12 +187,12 @@ class Geohash(Str):
186
187
  '''DEPRECATED, use property C{philam}.'''
187
188
  return self.philam
188
189
 
189
- def adjacent(self, direction, name=NN):
190
+ def adjacent(self, direction, **name):
190
191
  '''Determine the adjacent cell in the given compass direction.
191
192
 
192
193
  @arg direction: Compass direction ('N', 'S', 'E' or 'W').
193
- @kwarg name: Optional name (C{str}), otherwise the name
194
- of this cell plus C{.D}irection.
194
+ @kwarg name: Optional C{B{name}=NN} (C{str}) otherwise this
195
+ cell's name, either extended with C{.D}irection.
195
196
 
196
197
  @return: Geohash of adjacent cell (L{Geohash}).
197
198
 
@@ -215,7 +216,7 @@ class Geohash(Str):
215
216
  if p and (c in _GH.Borders[D][e]):
216
217
  p = Geohash(p).adjacent(D)
217
218
 
218
- n = name or self.name
219
+ n = self._name__(name)
219
220
  if n:
220
221
  n = _DOT_(n, D)
221
222
  # append letter for direction to parent
@@ -242,7 +243,7 @@ class Geohash(Str):
242
243
  '''
243
244
  r = self._bounds
244
245
  return r if LatLon is None else \
245
- _2bounds(LatLon, LatLon_kwds, *r, name=self.name)
246
+ _2bounds(LatLon, LatLon_kwds, *r, name=self.name)
246
247
 
247
248
  def _distanceTo(self, func_, other, **kwds):
248
249
  '''(INTERNAL) Helper for distances, see C{.formy._distanceTo*}.
@@ -532,21 +533,23 @@ def bounds(geohash, LatLon=None, **LatLon_kwds):
532
533
  i = _GH.DecodedBase32[c]
533
534
  for m in (16, 8, 4, 2, 1):
534
535
  if d: # longitude
535
- if i & m:
536
- w = _avg(w, e)
536
+ a = _avg(w, e)
537
+ if (i & m):
538
+ w = a
537
539
  else:
538
- e = _avg(w, e)
540
+ e = a
539
541
  else: # latitude
540
- if i & m:
541
- s = _avg(s, n)
542
+ a = _avg(s, n)
543
+ if (i & m):
544
+ s = a
542
545
  else:
543
- n = _avg(s, n)
546
+ n = a
544
547
  d = not d
545
548
  except KeyError:
546
549
  raise GeohashError(geohash=geohash)
547
550
 
548
551
  return _2bounds(LatLon, LatLon_kwds, s, w, n, e,
549
- name=nameof(geohash))
552
+ name=nameof(geohash)) # _or_nameof=geohash
550
553
 
551
554
 
552
555
  def _bounds3(geohash):
@@ -598,7 +601,7 @@ def decode2(geohash, LatLon=None, **LatLon_kwds):
598
601
  '''
599
602
  t = map2(float, decode(geohash))
600
603
  r = LatLon2Tuple(t) if LatLon is None else LatLon(*t, **LatLon_kwds) # *t
601
- return _xnamed(r, decode2.__name__)
604
+ return _xnamed(r, name__=decode2)
602
605
 
603
606
 
604
607
  def decode_error(geohash):
@@ -636,19 +639,19 @@ def distance_(geohash1, geohash2):
636
639
 
637
640
  @deprecated_function
638
641
  def distance1(geohash1, geohash2):
639
- '''DEPRECATED, used L{geohash.distance_}.'''
642
+ '''DEPRECATED, use L{geohash.distance_}.'''
640
643
  return distance_(geohash1, geohash2)
641
644
 
642
645
 
643
646
  @deprecated_function
644
647
  def distance2(geohash1, geohash2):
645
- '''DEPRECATED, used L{geohash.equirectangular_}.'''
648
+ '''DEPRECATED, use L{geohash.equirectangular_}.'''
646
649
  return equirectangular_(geohash1, geohash2)
647
650
 
648
651
 
649
652
  @deprecated_function
650
653
  def distance3(geohash1, geohash2):
651
- '''DEPRECATED, used L{geohash.haversine_}.'''
654
+ '''DEPRECATED, use L{geohash.haversine_}.'''
652
655
  return haversine_(geohash1, geohash2)
653
656
 
654
657
 
pygeodesy/geoids.py CHANGED
@@ -87,19 +87,19 @@ from pygeodesy.constants import EPS, _float as _F, _0_0, _1_0, _180_0, _360_0
87
87
  # from pygeodesy.datums import _ellipsoidal_datum # from .heights
88
88
  # from pygeodesy.dms import parseDMS2 # _MODS
89
89
  from pygeodesy.errors import _incompatible, LenError, RangeError, SciPyError, \
90
- _SciPyIssue
90
+ _SciPyIssue, _xkwds_pop2
91
91
  from pygeodesy.fmath import favg, Fdot, fdot, Fhorner, frange
92
92
  # from pygoedesy.formy import heightOrthometric # _MODS
93
93
  from pygeodesy.heights import _as_llis2, _ascalar, _height_called, HeightError, \
94
94
  _HeightsBase, _ellipsoidal_datum, _Wrap
95
+ # from pygeodesy.internals import _version2 # _MODS
95
96
  from pygeodesy.interns import MISSING, NN, _4_, _COLONSPACE_, _COMMASPACE_, \
96
- _cubic_, _E_, _height_, _in_, _kind_, _knots_, \
97
- _lat_, _linear_, _lon_, _mean_, _N_, _n_a_, \
98
- _not_, _numpy_, _on_, _outside_, _S_, _s_, \
99
- _scipy_, _SPACE_, _stdev_, _supported_, _tbd_, \
100
- _W_, _width_, _version2
97
+ _cubic_, _E_, _height_, _in_, _kind_, _lat_, \
98
+ _linear_, _lon_, _mean_, _N_, _n_a_, _numpy_, \
99
+ _on_, _outside_, _S_, _s_, _scipy_, _SPACE_, \
100
+ _stdev_, _tbd_, _W_, _width_
101
101
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
102
- from pygeodesy.named import _Named, _NamedTuple
102
+ from pygeodesy.named import _name__, _Named, _NamedTuple
103
103
  # from pygeodesy.namedTuples import LatLon3Tuple # _MODS
104
104
  from pygeodesy.props import deprecated_method, Property_RO, property_RO
105
105
  from pygeodesy.streprs import attrs, Fmt, fstr, pairs
@@ -118,21 +118,21 @@ 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.04.07'
121
+ __version__ = '24.05.23'
122
122
 
123
123
  _assert_ = 'assert'
124
124
  _bHASH_ = b'#'
125
125
  _endian_ = 'endian'
126
126
  _format_ = '%s %r'
127
127
  _header_ = 'header'
128
- # temporarily hold a single instance for each int value
129
- _intCs = {}
128
+ _intCs = {} # cache int value
130
129
  _interp2d_ks = {-2: _linear_,
131
130
  -3: _cubic_,
132
131
  -5: 'quintic'}
133
132
  _lli_ = 'lli'
134
133
  _non_increasing_ = 'non-increasing'
135
134
  _rb_ = 'rb'
135
+ _supported_ = 'supported'
136
136
 
137
137
 
138
138
  class _GeoidBase(_HeightsBase):
@@ -237,11 +237,11 @@ class _GeoidBase(_HeightsBase):
237
237
  '''Interpolate the geoid height for one or several locations.
238
238
 
239
239
  @arg llis: One or more locations (C{LatLon}s), all positional.
240
- @kwarg wrap_H: Keyword arguments C{B{wrap}=False, B{H}=False}.
241
- If C{B{wrap} is True}, wrap or I{normalize} all
242
- B{C{llis}} locations (C{bool}). If C{B{H} is True},
243
- return the I{orthometric} height instead of the
244
- I{geoid} height at each location (C{bool}).
240
+ @kwarg wrap_H: Keyword arguments C{B{wrap}=False} (C{bool}) and
241
+ C{B{H}=False} (C{bool}). If C{B{wrap} is True},
242
+ wrap or I{normalize} all B{C{llis}} locations. If
243
+ C{B{H} is True}, return the I{orthometric} height
244
+ instead of the I{geoid} height at each location.
245
245
 
246
246
  @return: A single interpolated geoid (or orthometric) height
247
247
  (C{float}) or a list or tuple of interpolated geoid
@@ -679,7 +679,7 @@ class _GeoidBase(_HeightsBase):
679
679
  self.highest, self.lowest)) + \
680
680
  attrs( _mean_, _stdev_, prec=prec, Nones=False) + \
681
681
  attrs((_kind_, 'smooth')[:s], prec=prec, Nones=False) + \
682
- attrs( 'cropped', 'dtype', _endian_, 'hits', _knots_, 'nBytes',
682
+ attrs( 'cropped', 'dtype', _endian_, 'hits', 'knots', 'nBytes',
683
683
  'sizeB', _scipy_, _numpy_, prec=prec, Nones=False)
684
684
  return _COLONSPACE_(self, sep.join(t))
685
685
 
@@ -753,12 +753,11 @@ class GeoidG2012B(_GeoidBase):
753
753
  Use any of the binary C{le} (little endian) or C{be} (big endian)
754
754
  C{g2012b*.bin} grid files.
755
755
  '''
756
- def __init__(self, g2012b_bin, crop=None, datum=None, # NAD 83 Ellipsoid
757
- kind=3, name=NN, smooth=0):
756
+ def __init__(self, g2012b_bin, datum=None, # NAD 83 Ellipsoid
757
+ kind=3, smooth=0, **name_crop):
758
758
  '''New L{GeoidG2012B} interpolator.
759
759
 
760
760
  @arg g2012b_bin: A C{GEOID12B} grid file name (C{.bin}).
761
- @kwarg crop: Optional crop box, not supported (C{None}).
762
761
  @kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}
763
762
  or L{a_f2Tuple}), default C{WGS84}.
764
763
  @kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for
@@ -767,17 +766,18 @@ class GeoidG2012B(_GeoidBase):
767
766
  -2 for U{interp2d linear<https://docs.SciPy.org/doc/scipy/
768
767
  reference/generated/scipy.interpolate.interp2d.html>}, -3
769
768
  for C{interp2d cubic} or -5 for C{interp2d quintic}.
770
- @kwarg name: Optional geoid name (C{str}).
771
769
  @kwarg smooth: Smoothing factor for U{RectBivariateSpline
772
770
  <https://docs.SciPy.org/doc/scipy/reference/generated/
773
771
  scipy.interpolate.RectBivariateSpline.html>}
774
772
  only (C{int}).
773
+ @kwarg name_crop: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED
774
+ keyword argument C{B{crop}}, use C{B{crop}=None} to ignore.
775
775
 
776
776
  @raise GeoidError: G2012B grid file B{C{g2012b_bin}} issue or invalid
777
777
  B{C{crop}}, B{C{kind}} or B{C{smooth}}.
778
778
 
779
- @raise ImportError: Package C{numpy} or C{scipy} not found or
780
- not installed.
779
+ @raise ImportError: Package C{numpy} or C{scipy} not found or not
780
+ installed.
781
781
 
782
782
  @raise LenError: Grid file B{C{g2012b_bin}} axis mismatch.
783
783
 
@@ -791,10 +791,11 @@ class GeoidG2012B(_GeoidBase):
791
791
  @note: C{scipy.interpolate.interp2d} has been C{DEPRECATED}, specify
792
792
  C{B{kind}=1..5} for C{scipy.interpolate.RectBivariateSpline}.
793
793
  '''
794
+ crop, name = _xkwds_pop2(name_crop, crop=None)
794
795
  if crop is not None:
795
- raise GeoidError(crop=crop, txt=_not_(_supported_))
796
+ raise GeoidError(crop=crop, txt_not_=_supported_)
796
797
 
797
- g = self._open(g2012b_bin, datum, kind, name, smooth)
798
+ g = self._open(g2012b_bin, datum, kind, _name__(**name), smooth)
798
799
  _ = self.numpy # import numpy for ._load and
799
800
 
800
801
  try:
@@ -953,7 +954,7 @@ class GeoidKarney(_GeoidBase):
953
954
  _yx_hits = 0 # cache hits
954
955
 
955
956
  def __init__(self, egm_pgm, crop=None, datum=None, # WGS84
956
- kind=3, name=NN, smooth=None):
957
+ kind=3, **name_smooth):
957
958
  '''New L{GeoidKarney} interpolator.
958
959
 
959
960
  @arg egm_pgm: An U{EGM geoid dataset<https://GeographicLib.SourceForge.io/
@@ -968,8 +969,8 @@ class GeoidKarney(_GeoidBase):
968
969
  or L{a_f2Tuple}), default C{WGS84}.
969
970
  @kwarg kind: Interpolation order (C{int}), 2 for C{bilinear} or 3
970
971
  for C{cubic}.
971
- @kwarg name: Optional geoid name (C{str}).
972
- @kwarg smooth: Smoothing factor, unsupported (C{None}).
972
+ @kwarg name_smooth: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED
973
+ keyword argument C{B{smooth}}, use C{B{smooth}=None} to ignore.
973
974
 
974
975
  @raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid
975
976
  B{C{crop}}, B{C{kind}} or B{C{smooth}}.
@@ -982,15 +983,16 @@ class GeoidKarney(_GeoidBase):
982
983
  by calling the C{close} method or by using this instance
983
984
  in a C{with B{GeoidKarney}(...) as ...} context.
984
985
  '''
986
+ smooth, name = _xkwds_pop2(name_smooth, smooth=None)
985
987
  if smooth is not None:
986
- raise GeoidError(smooth=smooth, txt=_not_(_supported_))
988
+ raise GeoidError(smooth=smooth, txt_not_=_supported_)
987
989
 
988
990
  if kind in (2,):
989
991
  self._evH = self._ev2H
990
992
  elif kind not in (3,):
991
993
  raise GeoidError(kind=kind)
992
994
 
993
- self._egm = g = self._open(egm_pgm, datum, kind, name, smooth)
995
+ self._egm = g = self._open(egm_pgm, datum, kind, _name__(**name), None)
994
996
  self._pgm = p = _PGM(g, pgm=egm_pgm, itemsize=self.u2B, sizeB=self.sizeB)
995
997
 
996
998
  self._Rendian = self._4endian.replace(_4_, str(p.nlon))
@@ -1302,7 +1304,7 @@ class GeoidPGM(_GeoidBase):
1302
1304
  _endian = '>u2'
1303
1305
 
1304
1306
  def __init__(self, egm_pgm, crop=None, datum=None, # WGS84
1305
- kind=3, name=NN, smooth=0):
1307
+ kind=3, smooth=0, **name):
1306
1308
  '''New L{GeoidPGM} interpolator.
1307
1309
 
1308
1310
  @arg egm_pgm: An U{EGM geoid dataset<https://GeographicLib.SourceForge.io/
@@ -1319,11 +1321,11 @@ class GeoidPGM(_GeoidBase):
1319
1321
  -2 for U{interp2d linear<https://docs.SciPy.org/doc/scipy/
1320
1322
  reference/generated/scipy.interpolate.interp2d.html>}, -3
1321
1323
  for C{interp2d cubic} or -5 for C{interp2d quintic}.
1322
- @kwarg name: Optional geoid name (C{str}).
1323
1324
  @kwarg smooth: Smoothing factor for U{RectBivariateSpline
1324
1325
  <https://docs.SciPy.org/doc/scipy/reference/generated/
1325
1326
  scipy.interpolate.RectBivariateSpline.html>}
1326
1327
  only (C{int}).
1328
+ @kwarg name: Optional geoid C{B{name}=NN} (C{str}).
1327
1329
 
1328
1330
  @raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}},
1329
1331
  B{C{kind}} or B{C{smooth}}.
@@ -1337,7 +1339,7 @@ class GeoidPGM(_GeoidBase):
1337
1339
  @raise SciPyWarning: A C{RectBivariateSpline} or C{inter2d}
1338
1340
  warning as exception.
1339
1341
 
1340
- @raise TypeError: Invalid B{C{datum}}.
1342
+ @raise TypeError: Invalid B{C{datum}} or unexpected argument.
1341
1343
 
1342
1344
  @note: C{scipy.interpolate.interp2d} has been C{DEPRECATED}, specify
1343
1345
  C{B{kind}=1..5} for C{scipy.interpolate.RectBivariateSpline}.
@@ -1358,11 +1360,11 @@ class GeoidPGM(_GeoidBase):
1358
1360
  np = self.numpy
1359
1361
  self._u2B = np.dtype(self.endian).itemsize
1360
1362
 
1361
- g = self._open(egm_pgm, datum, kind, name, smooth)
1363
+ g = self._open(egm_pgm, datum, kind, _name__(**name), smooth)
1362
1364
  self._pgm = p = _PGM(g, pgm=egm_pgm, itemsize=self.u2B, sizeB=self.sizeB)
1363
1365
  if crop:
1364
1366
  g = p._cropped(g, abs(kind) + 1, *self._swne(crop))
1365
- if _version2(np.__version__) < (1, 9):
1367
+ if _MODS.internals._version2(np.__version__) < (1, 9):
1366
1368
  g = open(g.name, _rb_) # reopen tempfile for numpy 1.8.0-
1367
1369
  self._cropped = True
1368
1370
  try:
@@ -1722,7 +1724,7 @@ __all__ += _ALL_DOCS(_GeoidBase)
1722
1724
 
1723
1725
  if __name__ == '__main__':
1724
1726
 
1725
- from pygeodesy.lazily import printf, _sys
1727
+ from pygeodesy.internals import printf, _sys
1726
1728
 
1727
1729
  _crop = ()
1728
1730
  _GeoidEGM = GeoidKarney