pygeodesy 24.7.24__py2.py3-none-any.whl → 24.8.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 (57) hide show
  1. {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/METADATA +20 -19
  2. {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/RECORD +57 -57
  3. {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/WHEEL +1 -1
  4. pygeodesy/__init__.py +26 -27
  5. pygeodesy/auxilats/auxAngle.py +2 -2
  6. pygeodesy/auxilats/auxDST.py +3 -3
  7. pygeodesy/azimuthal.py +4 -4
  8. pygeodesy/basics.py +3 -3
  9. pygeodesy/cartesianBase.py +6 -6
  10. pygeodesy/constants.py +11 -11
  11. pygeodesy/css.py +5 -5
  12. pygeodesy/ellipsoidalBase.py +18 -15
  13. pygeodesy/ellipsoidalExact.py +2 -2
  14. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  15. pygeodesy/ellipsoidalKarney.py +2 -2
  16. pygeodesy/ellipsoidalNvector.py +2 -2
  17. pygeodesy/ellipsoidalVincenty.py +7 -6
  18. pygeodesy/ellipsoids.py +3 -3
  19. pygeodesy/epsg.py +3 -3
  20. pygeodesy/fmath.py +2 -1
  21. pygeodesy/formy.py +2 -2
  22. pygeodesy/fsums.py +4 -4
  23. pygeodesy/gars.py +66 -58
  24. pygeodesy/geodesici.py +4 -10
  25. pygeodesy/geodesicx/gx.py +3 -3
  26. pygeodesy/geodesicx/gxarea.py +3 -3
  27. pygeodesy/geodsolve.py +3 -3
  28. pygeodesy/geohash.py +491 -267
  29. pygeodesy/geoids.py +298 -316
  30. pygeodesy/heights.py +176 -194
  31. pygeodesy/internals.py +39 -6
  32. pygeodesy/interns.py +2 -3
  33. pygeodesy/karney.py +2 -2
  34. pygeodesy/latlonBase.py +14 -8
  35. pygeodesy/lazily.py +22 -21
  36. pygeodesy/ltp.py +6 -7
  37. pygeodesy/ltpTuples.py +12 -6
  38. pygeodesy/named.py +5 -4
  39. pygeodesy/namedTuples.py +14 -1
  40. pygeodesy/osgr.py +7 -7
  41. pygeodesy/points.py +2 -2
  42. pygeodesy/resections.py +7 -7
  43. pygeodesy/rhumb/solve.py +3 -3
  44. pygeodesy/simplify.py +10 -10
  45. pygeodesy/sphericalBase.py +3 -3
  46. pygeodesy/sphericalTrigonometry.py +2 -2
  47. pygeodesy/streprs.py +3 -3
  48. pygeodesy/triaxials.py +210 -204
  49. pygeodesy/units.py +36 -19
  50. pygeodesy/unitsBase.py +4 -4
  51. pygeodesy/utmupsBase.py +3 -3
  52. pygeodesy/vector2d.py +158 -51
  53. pygeodesy/vector3d.py +13 -52
  54. pygeodesy/vector3dBase.py +81 -63
  55. pygeodesy/webmercator.py +3 -3
  56. pygeodesy/wgrs.py +109 -101
  57. {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/top_level.txt +0 -0
pygeodesy/gars.py CHANGED
@@ -3,33 +3,34 @@
3
3
 
4
4
  u'''I{Global Area Reference System} (GARS) en-/decoding.
5
5
 
6
- Classes L{Garef} and L{GARSError} and several functions to encode,
7
- decode and inspect I{Global Area Reference System} (GARS) references.
8
-
9
- Transcoded from C++ class U{GARS
10
- <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GARS.html>}
11
- by I{Charles Karney}. See also U{Global Area Reference System
12
- <https://WikiPedia.org/wiki/Global_Area_Reference_System>} and U{NGA (GARS)
13
- <https://Earth-Info.NGA.mil/GandG/coordsys/grids/gars.html>}.
6
+ Class L{Garef} and several functions to encode, decode and inspect
7
+ GARS references.
8
+
9
+ Transcoded from I{Charles Karney}'s C++ class U{GARS
10
+ <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GARS.html>}.
11
+
12
+ @see: U{Global Area Reference System
13
+ <https://WikiPedia.org/wiki/Global_Area_Reference_System>} and U{NGA
14
+ (GARS)<https://Earth-Info.NGA.mil/GandG/coordsys/grids/gars.html>}.
14
15
  '''
15
16
 
16
17
  # from pygeodesy.basics import isstr # from .named
17
18
  from pygeodesy.constants import _off90, _1_over, _0_5, \
18
19
  _1_0 # PYCHOK used!
19
- from pygeodesy.dms import parse3llh, Fmt # parseDMS2
20
20
  from pygeodesy.errors import _ValueError, _xkwds, _xStrError
21
- from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _COMMA_
22
- from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER
23
- from pygeodesy.named import _name__, isstr, Property_RO
21
+ from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _COMMA_, \
22
+ _INV_, _SPACE_
23
+ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
24
+ from pygeodesy.named import _name__, Fmt, isstr, Property_RO
24
25
  from pygeodesy.namedTuples import LatLon2Tuple, LatLonPrec3Tuple
25
26
  # from pygeodesy.props import Property_RO # from .named
26
- # from pygeodesy.streprs import Fmt # from .dms
27
+ # from pygeodesy.streprs import Fmt # from .named
27
28
  from pygeodesy.units import Int_, Lat, Lon, Precision_, Scalar_, Str
28
29
 
29
30
  from math import floor
30
31
 
31
32
  __all__ = _ALL_LAZY.gars
32
- __version__ = '24.06.15'
33
+ __version__ = '24.08.13'
33
34
 
34
35
  _Digits = _0to9_
35
36
  _LatLen = 2
@@ -86,9 +87,9 @@ def _2garstr2(garef):
86
87
  try:
87
88
  n, garstr = len(garef), garef.upper()
88
89
  if n < _MinLen or n > _MaxLen \
89
- or garstr[:3] == 'INV' \
90
+ or garstr.startswith(_INV_) \
90
91
  or not garstr.isalnum():
91
- raise ValueError
92
+ raise ValueError()
92
93
  return garstr, _2Precision(n - _MinLen)
93
94
 
94
95
  except (AttributeError, TypeError, ValueError) as x:
@@ -111,45 +112,45 @@ class Garef(Str):
111
112
  '''Garef class, a named C{str}.
112
113
  '''
113
114
  # no str.__init__ in Python 3
114
- def __new__(cls, cll, precision=1, **name):
115
- '''New L{Garef} from an other L{Garef} instance or garef
116
- C{str} or from a C{LatLon} instance or lat-/longitude C{str}.
117
-
118
- @arg cll: Cell or location (L{Garef} or C{str}, C{LatLon}
119
- or C{str}).
120
- @kwarg precision: Optional, the desired garef resolution
121
- and length (C{int} 0..2), see function
122
- L{gars.encode} for more details.
115
+ def __new__(cls, lat_gll, lon=None, precision=1, **name):
116
+ '''New L{Garef} from an other L{Garef} instance or garef C{str}
117
+ or from a lat- and longitude.
118
+
119
+ @arg lat_gll: Latitude (C{degrees90}), a garef (L{Garef},
120
+ C{str}) or a location (C{LatLon}, C{LatLon*Tuple}).
121
+ @kwarg lon: Logitude (C{degrees180)}, required if B{C{lat_gll}}
122
+ is C{degrees90}, ignored otherwise.
123
+ @kwarg precision: The desired garef resolution and length (C{int}
124
+ 0..2), see L{encode<pygeodesy.gars.encode>}.
123
125
  @kwarg name: Optional C{B{name}=NN} (C{str}).
124
126
 
125
127
  @return: New L{Garef}.
126
128
 
127
- @raise RangeError: Invalid B{C{cll}} lat- or longitude.
129
+ @raise GARSError: INValid B{C{lat_gll}}.
128
130
 
129
- @raise TypeError: Invalid B{C{cll}}.
131
+ @raise RangeError: Invalid B{C{lat_gll}} or B{C{lon}}.
130
132
 
131
- @raise GARSError: INValid or non-alphanumeric B{C{cll}}.
133
+ @raise TypeError: Invalid B{C{lat_gll}} or B{C{lon}}.
132
134
  '''
133
- ll = p = None
134
-
135
- if isinstance(cll, Garef):
136
- g, p = _2garstr2(str(cll))
137
-
138
- elif isstr(cll):
139
- if _COMMA_ in cll:
140
- ll = _2fll(*parse3llh(cll))
141
- g = encode(*ll, precision=precision) # PYCHOK false
142
- else:
143
- g = cll.upper()
144
-
145
- else: # assume LatLon
146
- try:
147
- ll = _2fll(cll.lat, cll.lon)
148
- g = encode(*ll, precision=precision) # PYCHOK false
149
- except AttributeError:
150
- raise _xStrError(Garef, cll=cll) # Error=GARSError
151
-
152
- self = Str.__new__(cls, g, name=_name__(name, _or_nameof=cll))
135
+ if lon is None:
136
+ if isinstance(lat_gll, Garef):
137
+ g, ll, p = str(lat_gll), lat_gll.latlon, lat_gll.precision
138
+ elif isstr(lat_gll):
139
+ ll = lat_gll.replace(_COMMA_, _SPACE_).split()
140
+ if len(ll) > 1:
141
+ g, ll, p = _encode3(ll[0], ll[1], precision)
142
+ else:
143
+ g, ll = lat_gll.upper(), None
144
+ _, p = _2garstr2(g) # validate
145
+ else: # assume LatLon
146
+ try:
147
+ g, ll, p = _encode3(lat_gll.lat, lat_gll.lon, precision)
148
+ except AttributeError:
149
+ raise _xStrError(Garef, gll=lat_gll, Error=GARSError)
150
+ else:
151
+ g, ll, p = _encode3(lat_gll, lon, precision)
152
+
153
+ self = Str.__new__(cls, g, name=_name__(name, _or_nameof=lat_gll))
153
154
  self._latlon = ll
154
155
  self._precision = p
155
156
  return self
@@ -200,8 +201,8 @@ def decode3(garef, center=True, **name):
200
201
  '''Decode a C{garef} to lat-, longitude and precision.
201
202
 
202
203
  @arg garef: To be decoded (L{Garef} or C{str}).
203
- @kwarg center: If C{True} the center, otherwise the south-west,
204
- lower-left corner (C{bool}).
204
+ @kwarg center: If C{True}, use the garef's center, otherwise
205
+ the south-west, lower-left corner (C{bool}).
205
206
 
206
207
  @return: A L{LatLonPrec3Tuple}C{(lat, lon, precision)}.
207
208
 
@@ -251,7 +252,7 @@ def decode3(garef, center=True, **name):
251
252
  precision, name=n)
252
253
 
253
254
 
254
- def encode(lat, lon, precision=1): # MCCABE 14
255
+ def encode(lat, lon, precision=1):
255
256
  '''Encode a lat-/longitude as a C{garef} of the given precision.
256
257
 
257
258
  @arg lat: Latitude (C{degrees}).
@@ -269,6 +270,13 @@ def encode(lat, lon, precision=1): # MCCABE 14
269
270
  resolution is B{30′} for B{C{precision}} 0, B{15′} for 1
270
271
  and B{5′} for 2, respectively.
271
272
  '''
273
+ g, _, _ = _encode3(lat, lon, precision)
274
+ return g
275
+
276
+
277
+ def _encode3(lat, lon, precision): # MCCABE 14
278
+ '''Return 3-tuple C{(garef, (lat, lon), p)}.
279
+ '''
272
280
  def _digit(x, y, m):
273
281
  return _Digits[m * (m - y - 1) + x + 1],
274
282
 
@@ -282,12 +290,12 @@ def encode(lat, lon, precision=1): # MCCABE 14
282
290
  p = _2Precision(precision)
283
291
 
284
292
  lat, lon = _2fll(lat, lon)
285
- lat = _off90(lat)
286
293
 
287
- ix, x = _2divmod2(lon, _LonOrig_M4)
288
- iy, y = _2divmod2(lat, _LatOrig_M4)
294
+ ix, x = _2divmod2( lon, _LonOrig_M4)
295
+ iy, y = _2divmod2(_off90(lat), _LatOrig_M4)
289
296
 
290
- g = _str(_Digits, ix + 1, _LonLen) + _str(_Letters, iy, _LatLen)
297
+ g = _str(_Digits, ix + 1, _LonLen) + \
298
+ _str(_Letters, iy, _LatLen)
291
299
  if p > 0:
292
300
  ix, x = divmod(x, _M3)
293
301
  iy, y = divmod(y, _M3)
@@ -295,7 +303,7 @@ def encode(lat, lon, precision=1): # MCCABE 14
295
303
  if p > 1:
296
304
  g += _digit(x, y, _M3)
297
305
 
298
- return NN.join(g)
306
+ return NN.join(g), (lat, lon), p
299
307
 
300
308
 
301
309
  def precision(res):
@@ -332,8 +340,8 @@ def resolution(prec):
332
340
  return _Resolutions[max(0, min(p, _MaxPrec))]
333
341
 
334
342
 
335
- __all__ += _ALL_OTHER(decode3, # functions
336
- encode, precision, resolution)
343
+ __all__ += _ALL_DOCS(decode3, # functions
344
+ encode, precision, resolution)
337
345
 
338
346
  # **) MIT License
339
347
  #
pygeodesy/geodesici.py CHANGED
@@ -49,14 +49,14 @@ from pygeodesy.props import deprecated_method, Property, \
49
49
  from pygeodesy.solveBase import _SolveCapsBase, pairs
50
50
  # from pygeodesy.streprs import pairs # from .solveBase
51
51
  # from pygeodesy.streprs import Fmt, unstr # from .ellipsoids
52
- from pygeodesy.units import Degrees, Float, Int, _isDegrees, \
53
- Lat, Lon, Meter, Meter_
52
+ from pygeodesy.units import Azimuth as Azi, Degrees, Float, Int, \
53
+ _isDegrees, Lat, Lon, Meter, Meter_
54
54
  from pygeodesy.utily import sincos2, atan2, fabs, radians
55
55
 
56
56
  # from math import atan2, ceil as _ceil, fabs, radians # .fsums, .utily
57
57
 
58
58
  __all__ = _ALL_LAZY.geodesici
59
- __version__ = '24.07.22'
59
+ __version__ = '24.07.25'
60
60
 
61
61
  _0t = 0, # int
62
62
  _1_1t = -1, +1
@@ -77,12 +77,6 @@ _sX0_ = 'sX0'
77
77
  _TRIPS = 128
78
78
 
79
79
 
80
- class Azi(Degrees):
81
- '''(INTERNAL) Azimuth C{Unit}.
82
- '''
83
- pass
84
-
85
-
86
80
  class XDict(ADict):
87
81
  '''4+Item result from L{Intersectool} and L{Intersector} methods
88
82
  C{All}, C{Closest}, C{Next} and C{Segment} with the intersection
@@ -597,7 +591,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
597
591
  def _GeodesicExact(self):
598
592
  '''Get the I{class} L{GeodesicExact}, I{once}.
599
593
  '''
600
- return _MODS.geodesicx.GeodesicExact # overwrite propertyROver
594
+ return _MODS.geodesicx.GeodesicExact # overwrite property_ROver
601
595
 
602
596
  def _In5T(self, glA, glB, S, X, k2=False, **_2X):
603
597
  A = GDict(glA).set_(lat2=X.latA, lon2=X.lonA, s12=S.sA)
pygeodesy/geodesicx/gx.py CHANGED
@@ -63,7 +63,7 @@ from pygeodesy.utily import atan2d as _atan2d_reverse, _unrollon, _Wrap, wrap360
63
63
  from math import atan2, copysign, cos, degrees, fabs, radians, sqrt
64
64
 
65
65
  __all__ = ()
66
- __version__ = '24.07.11'
66
+ __version__ = '24.08.13'
67
67
 
68
68
  _MAXIT1 = 20
69
69
  _MAXIT2 = 10 + _MAXIT1 + MANT_DIG # MANT_DIG == C++ digits
@@ -218,8 +218,8 @@ class GeodesicExact(_GeodesicBase):
218
218
  '''Set up a L{GeodesicAreaExact} to compute area and
219
219
  perimeter of a polygon.
220
220
 
221
- @kwarg polyline: If C{True} perimeter only, otherwise
222
- area and perimeter (C{bool}).
221
+ @kwarg polyline: If C{True}, compute the perimeter only, otherwise
222
+ the perimeter and area (C{bool}).
223
223
  @kwarg name: Optional C{B{name}=NN} (C{str}).
224
224
 
225
225
  @return: A L{GeodesicAreaExact} instance.
@@ -30,7 +30,7 @@ from pygeodesy.props import Property, Property_RO, property_RO
30
30
  from math import fmod as _fmod
31
31
 
32
32
  __all__ = ()
33
- __version__ = '24.05.19'
33
+ __version__ = '24.08.13'
34
34
 
35
35
 
36
36
  class GeodesicAreaExact(_NamedBase):
@@ -413,8 +413,8 @@ class PolygonArea(GeodesicAreaExact):
413
413
 
414
414
  @arg earth: A geodesic (L{GeodesicExact}, I{wrapped}
415
415
  C{Geodesic} or L{GeodesicSolve}).
416
- @kwarg polyline: If C{True} perimeter only, otherwise
417
- area and perimeter (C{bool}).
416
+ @kwarg polyline: If C{True}, compute the perimeter only, otherwise
417
+ perimeter and area (C{bool}).
418
418
  @kwarg name: Optional C{B{name}=NN} (C{str}).
419
419
 
420
420
  @raise GeodesicError: Invalid B{C{earth}}.
pygeodesy/geodsolve.py CHANGED
@@ -24,7 +24,7 @@ from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
24
24
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
25
25
 
26
26
  __all__ = _ALL_LAZY.geodsolve
27
- __version__ = '24.07.11'
27
+ __version__ = '24.08.13'
28
28
 
29
29
 
30
30
  class _GeodesicSolveBase(_SolveGDictBase):
@@ -101,8 +101,8 @@ class GeodesicSolve(_GeodesicSolveBase):
101
101
  '''Set up a L{GeodesicAreaExact} to compute area and perimeter
102
102
  of a polygon.
103
103
 
104
- @kwarg polyline: If C{True} perimeter only, otherwise area
105
- and perimeter (C{bool}).
104
+ @kwarg polyline: If C{True}, compute the perimeter only, otherwise
105
+ perimeter and area (C{bool}).
106
106
  @kwarg name: Optional C{B{name}=NN} (C{str}).
107
107
 
108
108
  @return: A L{GeodesicAreaExact} instance.