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.
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
- PyGeodesy-24.5.24.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +16 -12
- pygeodesy/__main__.py +9 -10
- pygeodesy/albers.py +42 -42
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +7 -10
- pygeodesy/auxilats/auxAngle.py +32 -31
- pygeodesy/auxilats/auxLat.py +81 -51
- pygeodesy/azimuthal.py +123 -124
- pygeodesy/basics.py +165 -176
- pygeodesy/booleans.py +14 -15
- pygeodesy/cartesianBase.py +25 -23
- pygeodesy/clipy.py +3 -3
- pygeodesy/constants.py +8 -6
- pygeodesy/css.py +50 -42
- pygeodesy/datums.py +50 -48
- pygeodesy/dms.py +6 -6
- pygeodesy/ecef.py +27 -27
- pygeodesy/elevations.py +2 -2
- pygeodesy/ellipsoidalBase.py +28 -27
- pygeodesy/ellipsoidalBaseDI.py +8 -7
- pygeodesy/ellipsoidalNvector.py +11 -12
- pygeodesy/ellipsoids.py +41 -35
- pygeodesy/elliptic.py +12 -10
- pygeodesy/epsg.py +4 -3
- pygeodesy/errors.py +35 -13
- pygeodesy/etm.py +62 -53
- pygeodesy/fmath.py +48 -41
- pygeodesy/formy.py +93 -65
- pygeodesy/frechet.py +117 -102
- pygeodesy/fstats.py +52 -46
- pygeodesy/fsums.py +169 -145
- pygeodesy/gars.py +10 -9
- pygeodesy/geodesicw.py +32 -30
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +4 -4
- pygeodesy/geodesicx/gx.py +40 -32
- pygeodesy/geodesicx/gxarea.py +15 -12
- pygeodesy/geodesicx/gxbases.py +3 -4
- pygeodesy/geodesicx/gxline.py +6 -8
- pygeodesy/geodsolve.py +28 -26
- pygeodesy/geohash.py +47 -44
- pygeodesy/geoids.py +37 -35
- pygeodesy/hausdorff.py +112 -99
- pygeodesy/heights.py +136 -129
- pygeodesy/internals.py +576 -0
- pygeodesy/interns.py +6 -207
- pygeodesy/iters.py +22 -19
- pygeodesy/karney.py +18 -15
- pygeodesy/ktm.py +31 -24
- pygeodesy/latlonBase.py +12 -11
- pygeodesy/lazily.py +140 -218
- pygeodesy/lcc.py +24 -25
- pygeodesy/ltp.py +83 -71
- pygeodesy/ltpTuples.py +7 -5
- pygeodesy/mgrs.py +5 -4
- pygeodesy/named.py +136 -49
- pygeodesy/namedTuples.py +33 -25
- pygeodesy/nvectorBase.py +10 -9
- pygeodesy/osgr.py +14 -12
- pygeodesy/points.py +13 -13
- pygeodesy/props.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/bases.py +3 -2
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +8 -7
- pygeodesy/sphericalTrigonometry.py +5 -5
- pygeodesy/streprs.py +8 -7
- pygeodesy/trf.py +8 -8
- pygeodesy/triaxials.py +67 -63
- pygeodesy/units.py +48 -50
- pygeodesy/unitsBase.py +24 -11
- pygeodesy/ups.py +7 -6
- pygeodesy/utily.py +4 -4
- pygeodesy/utm.py +53 -52
- pygeodesy/utmupsBase.py +11 -8
- pygeodesy/vector2d.py +6 -7
- pygeodesy/vector3d.py +16 -17
- pygeodesy/vector3dBase.py +5 -5
- PyGeodesy-24.5.8.dist-info/RECORD +0 -115
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
- {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
|
|
19
|
+
_Pass, _Lat, _Lon, _M, _M2, _sincos2d
|
|
21
20
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
22
|
-
|
|
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.
|
|
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
|
|
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:
|
|
163
|
-
|
|
164
|
-
|
|
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, **
|
|
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:
|
|
213
|
-
|
|
214
|
-
|
|
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, **
|
|
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
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
@kwarg name: Optional name (C{str}).
|
|
254
|
-
|
|
255
|
-
@raise GeodesicError: Invalid path for the C{GeodSolve} executable
|
|
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
|
|
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
|
-
|
|
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__ = '
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
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
|
|
97
|
+
r = Bounds4Tuple(s, w, n, e, **name)
|
|
97
98
|
else:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return r
|
|
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
|
|
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
|
|
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
|
|
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})
|
|
194
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
536
|
-
|
|
536
|
+
a = _avg(w, e)
|
|
537
|
+
if (i & m):
|
|
538
|
+
w = a
|
|
537
539
|
else:
|
|
538
|
-
e =
|
|
540
|
+
e = a
|
|
539
541
|
else: # latitude
|
|
540
|
-
|
|
541
|
-
|
|
542
|
+
a = _avg(s, n)
|
|
543
|
+
if (i & m):
|
|
544
|
+
s = a
|
|
542
545
|
else:
|
|
543
|
-
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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_,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
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
|
-
#
|
|
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
|
|
241
|
-
If C{B{wrap} is True},
|
|
242
|
-
B{C{llis}} locations
|
|
243
|
-
return the I{orthometric} height
|
|
244
|
-
I{geoid} height at each location
|
|
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',
|
|
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,
|
|
757
|
-
kind=3,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
972
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
1727
|
+
from pygeodesy.internals import printf, _sys
|
|
1726
1728
|
|
|
1727
1729
|
_crop = ()
|
|
1728
1730
|
_GeoidEGM = GeoidKarney
|