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.
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/METADATA +20 -19
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/RECORD +57 -57
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +26 -27
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxDST.py +3 -3
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/basics.py +3 -3
- pygeodesy/cartesianBase.py +6 -6
- pygeodesy/constants.py +11 -11
- pygeodesy/css.py +5 -5
- pygeodesy/ellipsoidalBase.py +18 -15
- pygeodesy/ellipsoidalExact.py +2 -2
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +2 -2
- pygeodesy/ellipsoidalNvector.py +2 -2
- pygeodesy/ellipsoidalVincenty.py +7 -6
- pygeodesy/ellipsoids.py +3 -3
- pygeodesy/epsg.py +3 -3
- pygeodesy/fmath.py +2 -1
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +4 -4
- pygeodesy/gars.py +66 -58
- pygeodesy/geodesici.py +4 -10
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +3 -3
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +491 -267
- pygeodesy/geoids.py +298 -316
- pygeodesy/heights.py +176 -194
- pygeodesy/internals.py +39 -6
- pygeodesy/interns.py +2 -3
- pygeodesy/karney.py +2 -2
- pygeodesy/latlonBase.py +14 -8
- pygeodesy/lazily.py +22 -21
- pygeodesy/ltp.py +6 -7
- pygeodesy/ltpTuples.py +12 -6
- pygeodesy/named.py +5 -4
- pygeodesy/namedTuples.py +14 -1
- pygeodesy/osgr.py +7 -7
- pygeodesy/points.py +2 -2
- pygeodesy/resections.py +7 -7
- pygeodesy/rhumb/solve.py +3 -3
- pygeodesy/simplify.py +10 -10
- pygeodesy/sphericalBase.py +3 -3
- pygeodesy/sphericalTrigonometry.py +2 -2
- pygeodesy/streprs.py +3 -3
- pygeodesy/triaxials.py +210 -204
- pygeodesy/units.py +36 -19
- pygeodesy/unitsBase.py +4 -4
- pygeodesy/utmupsBase.py +3 -3
- pygeodesy/vector2d.py +158 -51
- pygeodesy/vector3d.py +13 -52
- pygeodesy/vector3dBase.py +81 -63
- pygeodesy/webmercator.py +3 -3
- pygeodesy/wgrs.py +109 -101
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/top_level.txt +0 -0
pygeodesy/geoids.py
CHANGED
|
@@ -63,44 +63,45 @@ courtesy of SBFRF.
|
|
|
63
63
|
<https://PyPI.org/project/numpy>} and U{scipy<https://PyPI.org/project/scipy>}
|
|
64
64
|
to be installed.
|
|
65
65
|
|
|
66
|
-
@note: Errors from C{scipy} are raised as L{SciPyError}s. Warnings issued by
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
@note: Errors from C{scipy} are raised as L{SciPyError}s. Warnings issued by C{scipy} can
|
|
67
|
+
be thrown as L{SciPyWarning} exceptions, provided Python C{warnings} are filtered
|
|
68
|
+
accordingly, see L{SciPyWarning}.
|
|
69
69
|
|
|
70
70
|
@see: I{Karney}'s U{GeographicLib<https://GeographicLib.SourceForge.io/C++/doc/index.html>},
|
|
71
71
|
U{Geoid height<https://GeographicLib.SourceForge.io/C++/doc/geoid.html>} and U{Installing
|
|
72
72
|
the Geoid datasets<https://GeographicLib.SourceForge.io/C++/doc/geoid.html#geoidinst>},
|
|
73
73
|
U{SciPy<https://docs.SciPy.org/doc/scipy/reference/interpolate.html>} interpolation
|
|
74
|
-
U{RectBivariateSpline<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
and
|
|
80
|
-
|
|
74
|
+
U{RectBivariateSpline<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.
|
|
75
|
+
RectBivariateSpline.html>}, U{bisplrep/-ev<https://docs.scipy.org/doc/scipy/reference/generated/
|
|
76
|
+
scipy.interpolate.bisplrep.html>} and U{interp2d<https://docs.SciPy.org/doc/scipy/reference/
|
|
77
|
+
generated/scipy.interpolate.interp2d.html>}, functions L{elevations.elevation2} and
|
|
78
|
+
L{elevations.geoidHeight2}, U{I{Ellispoid vs Orthometric Elevations}<https://www.YouTube.com/
|
|
79
|
+
watch?v=dX6a6kCk3Po>} and U{6.22.1 Avoiding Pitfalls Related to Ellipsoid Height and Height
|
|
80
|
+
Above Mean Sea Level<https://Wiki.ROS.org/mavros>}.
|
|
81
81
|
'''
|
|
82
82
|
# make sure int/int division yields float quotient, see .basics
|
|
83
83
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
84
84
|
|
|
85
85
|
from pygeodesy.basics import len2, map1, isodd, ub2str as _ub2str
|
|
86
|
-
from pygeodesy.constants import EPS, _float as _F,
|
|
86
|
+
from pygeodesy.constants import EPS, _float as _F, _1_0, _N_90_0, _180_0, \
|
|
87
|
+
_N_180_0, _360_0
|
|
87
88
|
# from pygeodesy.datums import _ellipsoidal_datum # from .heights
|
|
88
89
|
# from pygeodesy.dms import parseDMS2 # _MODS
|
|
89
|
-
from pygeodesy.errors import _incompatible, LenError, RangeError,
|
|
90
|
-
|
|
90
|
+
from pygeodesy.errors import _incompatible, LenError, RangeError, _SciPyIssue, \
|
|
91
|
+
_xkwds_pop2
|
|
91
92
|
from pygeodesy.fmath import favg, Fdot, fdot, Fhorner, frange
|
|
92
93
|
# from pygoedesy.formy import heightOrthometric # _MODS
|
|
93
|
-
from pygeodesy.heights import _as_llis2, _ascalar,
|
|
94
|
-
|
|
94
|
+
from pygeodesy.heights import _as_llis2, _ascalar, _HeightBase, HeightError, \
|
|
95
|
+
_ellipsoidal_datum, _Wrap
|
|
95
96
|
# from pygeodesy.internals import _version2 # _MODS
|
|
96
|
-
from pygeodesy.interns import
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
from pygeodesy.interns import NN, _COLONSPACE_, _COMMASPACE_, _E_, _height_, \
|
|
98
|
+
_in_, _kind_, _lat_, _lon_, _mean_, _N_, _n_a_, \
|
|
99
|
+
_numpy_, _on_, _outside_, _S_, _s_, _scipy_, \
|
|
100
|
+
_SPACE_, _stdev_, _tbd_, _W_, _width_, _4_
|
|
100
101
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
|
|
101
102
|
from pygeodesy.named import _name__, _Named, _NamedTuple
|
|
102
103
|
# from pygeodesy.namedTuples import LatLon3Tuple # _MODS
|
|
103
|
-
from pygeodesy.props import
|
|
104
|
+
from pygeodesy.props import Property_RO, property_RO, property_ROver
|
|
104
105
|
from pygeodesy.streprs import attrs, Fmt, fstr, pairs
|
|
105
106
|
from pygeodesy.units import Height, Int_, Lat, Lon
|
|
106
107
|
# from pygeodesy.utily import _Wrap # from .heights
|
|
@@ -117,80 +118,65 @@ except ImportError: # Python 3+
|
|
|
117
118
|
from io import BytesIO as _BytesIO # PYCHOK expected
|
|
118
119
|
|
|
119
120
|
__all__ = _ALL_LAZY.geoids
|
|
120
|
-
__version__ = '24.
|
|
121
|
-
|
|
122
|
-
_assert_
|
|
123
|
-
_bHASH_
|
|
124
|
-
_endian_
|
|
125
|
-
_format_
|
|
126
|
-
_header_
|
|
127
|
-
_intCs
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
121
|
+
__version__ = '24.08.24'
|
|
122
|
+
|
|
123
|
+
_assert_ = 'assert'
|
|
124
|
+
_bHASH_ = b'#'
|
|
125
|
+
_endian_ = 'endian'
|
|
126
|
+
_format_ = '%s %r'
|
|
127
|
+
_header_ = 'header'
|
|
128
|
+
_intCs = {} # cache int value
|
|
129
|
+
_lli_ = 'lli'
|
|
130
|
+
_non_increasing_ = 'non-increasing'
|
|
131
|
+
_rb_ = 'rb'
|
|
132
|
+
_supported_ = 'supported'
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class GeoidError(HeightError):
|
|
136
|
+
'''Geoid interpolator C{Geoid...} or interpolation issue.
|
|
137
|
+
'''
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class _GeoidBase(_HeightBase):
|
|
138
142
|
'''(INTERNAL) Base class for C{Geoid...}s.
|
|
139
143
|
'''
|
|
144
|
+
_center = None # (lat, lon, height)
|
|
140
145
|
_cropped = None
|
|
141
|
-
# _datum = _WGS84 # from
|
|
146
|
+
# _datum = _WGS84 # from _HeightBase
|
|
142
147
|
_egm = None # open C{egm*.pgm} geoid file
|
|
143
148
|
_endian = _tbd_
|
|
149
|
+
_Error = GeoidError # in ._HeightBase._as_lls, ...
|
|
144
150
|
_geoid = _n_a_
|
|
145
151
|
_hs_y_x = None # numpy 2darray, row-major order
|
|
146
|
-
_interp2d = None # interp2d interpolation
|
|
147
152
|
_kind = 3 # order for interp2d, RectBivariateSpline
|
|
148
153
|
# _kmin = 2 # min number of knots
|
|
149
154
|
_knots = 0 # nlat * nlon
|
|
150
155
|
_mean = None # fixed in GeoidKarney
|
|
151
|
-
# _name = NN # _Named
|
|
152
156
|
_nBytes = 0 # numpy size in bytes, float64
|
|
153
157
|
_pgm = None # PGM attributes, C{_PGM} or C{None}
|
|
154
158
|
_sizeB = 0 # geoid file size in bytes
|
|
155
159
|
_smooth = 0 # used only for RectBivariateSpline
|
|
156
160
|
_stdev = None # fixed in GeoidKarney
|
|
157
161
|
_u2B = 0 # np.itemsize or undefined
|
|
162
|
+
_yx_hits = None # cache hits, ala Karney
|
|
158
163
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
_center = None # (lat, lon, height)
|
|
169
|
-
_yx_hits = None # cache hits, ala Karney
|
|
164
|
+
# _lat_d = _0_0 # increment, +tive
|
|
165
|
+
# _lat_lo = _0_0 # lower lat, south
|
|
166
|
+
# _lat_hi = _0_0 # upper lat, noth
|
|
167
|
+
# _lon_d = _0_0 # increment, +tive
|
|
168
|
+
# _lon_lo = _0_0 # left lon, west
|
|
169
|
+
# _lon_hi = _0_0 # right lon, east
|
|
170
|
+
# _lon_of = _0_0 # forward lon offset
|
|
171
|
+
# _lon_og = _0_0 # reverse lon offset
|
|
170
172
|
|
|
171
173
|
def __init__(self, hs, p):
|
|
172
|
-
'''(INTERNAL) Set up the grid axes, the C{SciPy} interpolator
|
|
173
|
-
|
|
174
|
+
'''(INTERNAL) Set up the grid axes, the C{SciPy} interpolator and
|
|
175
|
+
several internal geoid attributes.
|
|
174
176
|
|
|
175
177
|
@arg hs: Grid knots with known height (C{numpy 2darray}).
|
|
176
|
-
@arg p: The C{slat, wlon, nlat, nlon, dlat, dlon} and
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
@raise GeoidError: Incompatible grid B{C{hs}} shape or
|
|
180
|
-
invalid B{C{kind}}.
|
|
181
|
-
|
|
182
|
-
@raise LenError: Mismatch grid B{C{hs}} axis.
|
|
183
|
-
|
|
184
|
-
@raise SciPyError: A C{scipy.interpolate.inter2d} or
|
|
185
|
-
C{-.RectBivariateSpline} issue.
|
|
186
|
-
|
|
187
|
-
@raise SciPyWarning: A C{scipy.interpolate.inter2d} or
|
|
188
|
-
C{-.RectBivariateSpline} warning as
|
|
189
|
-
exception.
|
|
190
|
-
|
|
191
|
-
@note: C{scipy.interpolate.interp2d} has been C{DEPRECATED},
|
|
192
|
-
specify keyword argument C{B{kind}=1..5} to use
|
|
193
|
-
C{scipy.interpolate.RectBivariateSpline}.
|
|
178
|
+
@arg p: The C{slat, wlon, nlat, nlon, dlat, dlon} and other
|
|
179
|
+
geoid parameters (C{INTERNAL}).
|
|
194
180
|
'''
|
|
195
181
|
spi = self.scipy_interpolate
|
|
196
182
|
# for 2d scipy.interpolate.interp2d(xs, ys, hs, ...) and
|
|
@@ -209,28 +195,25 @@ class _GeoidBase(_HeightsBase):
|
|
|
209
195
|
# with rows (90..-90) reversed and columns (0..360) wrapped
|
|
210
196
|
# to Easten longitude, 0 <= east < 180 and 180 <= west < 360
|
|
211
197
|
k = self.kind
|
|
212
|
-
if k in
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
self._interp2d = self._interp2d(xs, ys, hs, k)
|
|
217
|
-
elif 1 <= k <= 5:
|
|
198
|
+
if k in self._k2interp2d: # see _HeightBase
|
|
199
|
+
self._interp2d(xs, ys, hs, kind=k)
|
|
200
|
+
else: # XXX order ys and xs, see HeightLSQBiSpline
|
|
201
|
+
k = self._kxky(k)
|
|
218
202
|
self._ev = spi.RectBivariateSpline(ys, xs, hs, bbox=bb, ky=k, kx=k,
|
|
219
203
|
s=self._smooth).ev
|
|
220
|
-
else:
|
|
221
|
-
raise GeoidError(kind=k)
|
|
222
|
-
|
|
223
204
|
self._hs_y_x = hs # numpy 2darray, row-major
|
|
224
205
|
self._nBytes = hs.nbytes # numpy size in bytes
|
|
225
206
|
self._knots = p.knots # grid knots
|
|
226
|
-
self._lon_of =
|
|
227
|
-
self._lon_og = float(p.glon) # reverse offset
|
|
228
|
-
# shrink the box by 1 unit on every side
|
|
229
|
-
#
|
|
230
|
-
self._lat_lo
|
|
231
|
-
self._lat_hi
|
|
232
|
-
self._lon_lo
|
|
233
|
-
self._lon_hi
|
|
207
|
+
self._lon_of = float(p.flon) # forward offset
|
|
208
|
+
self._lon_og = g = float(p.glon) # reverse offset
|
|
209
|
+
# shrink the bounding box by 1 unit on every side:
|
|
210
|
+
# +self._lat_d, -self._lat_d, +self._lon_d, -self._lon_d
|
|
211
|
+
self._lat_lo, \
|
|
212
|
+
self._lat_hi, \
|
|
213
|
+
self._lon_lo, \
|
|
214
|
+
self._lon_hi = map(float, bb)
|
|
215
|
+
self._lon_lo -= g
|
|
216
|
+
self._lon_hi -= g
|
|
234
217
|
|
|
235
218
|
def __call__(self, *llis, **wrap_H):
|
|
236
219
|
'''Interpolate the geoid height for one or several locations.
|
|
@@ -246,23 +229,19 @@ class _GeoidBase(_HeightsBase):
|
|
|
246
229
|
(C{float}) or a list or tuple of interpolated geoid
|
|
247
230
|
(or orthometric) heights (C{float}s).
|
|
248
231
|
|
|
249
|
-
@raise GeoidError: Insufficient number of B{C{llis}}, an
|
|
250
|
-
|
|
251
|
-
geoid file is closed.
|
|
232
|
+
@raise GeoidError: Insufficient number of B{C{llis}}, an invalid
|
|
233
|
+
B{C{lli}} or the C{egm*.pgm} geoid file is closed.
|
|
252
234
|
|
|
253
|
-
@raise RangeError: An B{C{lli}} is outside this geoid's lat-
|
|
254
|
-
|
|
235
|
+
@raise RangeError: An B{C{lli}} is outside this geoid's lat- or
|
|
236
|
+
longitude range.
|
|
255
237
|
|
|
256
|
-
@raise SciPyError: A C{scipy
|
|
257
|
-
C{-.RectBivariateSpline} issue.
|
|
238
|
+
@raise SciPyError: A C{scipy} issue.
|
|
258
239
|
|
|
259
|
-
@raise SciPyWarning: A C{scipy
|
|
260
|
-
C{-.RectBivariateSpline} warning as
|
|
261
|
-
exception.
|
|
240
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
262
241
|
|
|
263
|
-
@note: To obtain I{orthometric} heights, each B{C{llis}}
|
|
264
|
-
|
|
265
|
-
|
|
242
|
+
@note: To obtain I{orthometric} heights, each B{C{llis}} location
|
|
243
|
+
must have an ellipsoid C{height} or C{h} attribute, otherwise
|
|
244
|
+
C{height=0} is used.
|
|
266
245
|
|
|
267
246
|
@see: Function L{pygeodesy.heightOrthometric}.
|
|
268
247
|
'''
|
|
@@ -285,9 +264,9 @@ class _GeoidBase(_HeightsBase):
|
|
|
285
264
|
def __str__(self):
|
|
286
265
|
return Fmt.PAREN(self.classname, repr(self.name))
|
|
287
266
|
|
|
288
|
-
def _called(self, llis,
|
|
267
|
+
def _called(self, llis, iscipy, wrap=False, H=False):
|
|
289
268
|
# handle __call__
|
|
290
|
-
_H =
|
|
269
|
+
_H = self._heightOrthometric if H else None
|
|
291
270
|
_as, llis = _as_llis2(llis, Error=GeoidError)
|
|
292
271
|
hs, _w = [], _Wrap._latlonop(wrap)
|
|
293
272
|
_a, _h = hs.append, self._hGeoid
|
|
@@ -297,15 +276,14 @@ class _GeoidBase(_HeightsBase):
|
|
|
297
276
|
# orthometric or geoid height
|
|
298
277
|
_a(_H(lli, N) if _H else N)
|
|
299
278
|
return _as(hs)
|
|
300
|
-
|
|
301
279
|
except (GeoidError, RangeError) as x:
|
|
302
280
|
# XXX avoid str(LatLon()) degree symbols
|
|
303
281
|
t = _lli_ if _as is _ascalar else Fmt.INDEX(llis=i)
|
|
304
282
|
lli = fstr((lli.lat, lli.lon), strepr=repr)
|
|
305
283
|
raise type(x)(t, lli, wrap=wrap, H=H, cause=x)
|
|
306
284
|
except Exception as x:
|
|
307
|
-
if
|
|
308
|
-
raise _SciPyIssue(x)
|
|
285
|
+
if iscipy and self.scipy:
|
|
286
|
+
raise _SciPyIssue(x, self._ev_name)
|
|
309
287
|
else:
|
|
310
288
|
raise
|
|
311
289
|
|
|
@@ -361,11 +339,9 @@ class _GeoidBase(_HeightsBase):
|
|
|
361
339
|
'''
|
|
362
340
|
return self._endian
|
|
363
341
|
|
|
364
|
-
def _ev(self, y, x): # PYCHOK
|
|
365
|
-
#
|
|
366
|
-
#
|
|
367
|
-
# note (y, x) must be flipped!
|
|
368
|
-
return self._interp2d(x, y)
|
|
342
|
+
def _ev(self, y, x): # PYCHOK overwritten with .RectBivariateSpline.ev
|
|
343
|
+
# see methods _HeightBase._ev and -._interp2d
|
|
344
|
+
return self._ev2d(x, y) # (y, x) flipped!
|
|
369
345
|
|
|
370
346
|
def _gaxis2(self, lo, d, n, name):
|
|
371
347
|
# build grid axis, hi = lo + (n - 1) * d
|
|
@@ -407,14 +383,16 @@ class _GeoidBase(_HeightsBase):
|
|
|
407
383
|
@raise RangeError: A B{C{lat}} or B{C{lon}} is outside this
|
|
408
384
|
geoid's lat- or longitude range.
|
|
409
385
|
|
|
410
|
-
@raise SciPyError: A C{scipy
|
|
411
|
-
C{-.RectBivariateSpline} issue.
|
|
386
|
+
@raise SciPyError: A C{scipy} issue.
|
|
412
387
|
|
|
413
|
-
@raise SciPyWarning: A C{scipy
|
|
414
|
-
C{-.RectBivariateSpline} warning as
|
|
415
|
-
exception.
|
|
388
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
416
389
|
'''
|
|
417
|
-
|
|
390
|
+
lls = self._as_lls(lats, lons)
|
|
391
|
+
return self(lls, **wrap) # __call__(ll) or __call__(lls)
|
|
392
|
+
|
|
393
|
+
@property_ROver
|
|
394
|
+
def _heightOrthometric(self):
|
|
395
|
+
return _MODS.formy.heightOrthometric # overwrite property_ROver
|
|
418
396
|
|
|
419
397
|
def _hGeoid(self, lat, lon):
|
|
420
398
|
out = self.outside(lat, lon)
|
|
@@ -425,9 +403,9 @@ class _GeoidBase(_HeightsBase):
|
|
|
425
403
|
|
|
426
404
|
@Property_RO
|
|
427
405
|
def _highest(self):
|
|
428
|
-
'''(INTERNAL) Cache for
|
|
406
|
+
'''(INTERNAL) Cache for C{.highest}.
|
|
429
407
|
'''
|
|
430
|
-
return self._llh3minmax(True)
|
|
408
|
+
return self._LL3T(self._llh3minmax(True), name__=self.highest)
|
|
431
409
|
|
|
432
410
|
def highest(self, LatLon=None, **unused):
|
|
433
411
|
'''Return the location and largest height of this geoid.
|
|
@@ -447,15 +425,6 @@ class _GeoidBase(_HeightsBase):
|
|
|
447
425
|
'''
|
|
448
426
|
return self._yx_hits
|
|
449
427
|
|
|
450
|
-
@deprecated_method
|
|
451
|
-
def _interp2d(self, xs, ys, hs=(), k=0): # overwritten in .__init__ above
|
|
452
|
-
'''DEPRECATED on 23.01.06, use keyword argument C{B{kind}=1..5}.'''
|
|
453
|
-
# assert k in _interp2d_ks # and len(hs) == len(xs) == len(ys)
|
|
454
|
-
try:
|
|
455
|
-
return self.scipy_interpolate.interp2d(xs, ys, hs, kind=_interp2d_ks[k])
|
|
456
|
-
except AttributeError as x:
|
|
457
|
-
raise SciPyError(interp2d=MISSING, kind=k, cause=x)
|
|
458
|
-
|
|
459
428
|
@Property_RO
|
|
460
429
|
def kind(self):
|
|
461
430
|
'''Get the interpolator kind and order (C{int}).
|
|
@@ -484,7 +453,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
484
453
|
def _llh3LL(self, llh, LatLon):
|
|
485
454
|
return llh if LatLon is None else self._xnamed(LatLon(*llh))
|
|
486
455
|
|
|
487
|
-
def _llh3minmax(self, highest
|
|
456
|
+
def _llh3minmax(self, highest, *unused):
|
|
488
457
|
hs, np = self._hs_y_x, self.numpy
|
|
489
458
|
# <https://docs.SciPy.org/doc/numpy/reference/generated/
|
|
490
459
|
# numpy.argmin.html#numpy.argmin>
|
|
@@ -499,7 +468,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
499
468
|
|
|
500
469
|
@Property_RO
|
|
501
470
|
def _lowerleft(self):
|
|
502
|
-
'''(INTERNAL) Cache for
|
|
471
|
+
'''(INTERNAL) Cache for C{.lowerleft}.
|
|
503
472
|
'''
|
|
504
473
|
return self._llh3(self._lat_lo, self._lon_lo)
|
|
505
474
|
|
|
@@ -517,7 +486,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
517
486
|
|
|
518
487
|
@Property_RO
|
|
519
488
|
def _loweright(self):
|
|
520
|
-
'''(INTERNAL) Cache for
|
|
489
|
+
'''(INTERNAL) Cache for C{.loweright}.
|
|
521
490
|
'''
|
|
522
491
|
return self._llh3(self._lat_lo, self._lon_hi)
|
|
523
492
|
|
|
@@ -531,16 +500,15 @@ class _GeoidBase(_HeightsBase):
|
|
|
531
500
|
otherwise a B{C{LatLon}} instance with the lat-, longitude and
|
|
532
501
|
geoid height of the lower-right, SE grid corner.
|
|
533
502
|
'''
|
|
534
|
-
|
|
535
503
|
return self._llh3LL(self._loweright, LatLon)
|
|
536
504
|
|
|
537
505
|
lowerright = loweright # synonymous
|
|
538
506
|
|
|
539
507
|
@Property_RO
|
|
540
508
|
def _lowest(self):
|
|
541
|
-
'''(INTERNAL) Cache for
|
|
509
|
+
'''(INTERNAL) Cache for C{.lowest}.
|
|
542
510
|
'''
|
|
543
|
-
return self._llh3minmax(False)
|
|
511
|
+
return self._LL3T(self._llh3minmax(False), name__=self.lowest)
|
|
544
512
|
|
|
545
513
|
def lowest(self, LatLon=None, **unused):
|
|
546
514
|
'''Return the location and lowest height of this geoid.
|
|
@@ -566,7 +534,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
566
534
|
def name(self):
|
|
567
535
|
'''Get the name of this geoid (C{str}).
|
|
568
536
|
'''
|
|
569
|
-
return
|
|
537
|
+
return _HeightBase.name.fget(self) or self._geoid # recursion
|
|
570
538
|
|
|
571
539
|
@Property_RO
|
|
572
540
|
def nBytes(self):
|
|
@@ -587,7 +555,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
587
555
|
self._datum = _ellipsoidal_datum(datum, name=name)
|
|
588
556
|
self._kind = int(kind)
|
|
589
557
|
if name:
|
|
590
|
-
|
|
558
|
+
_HeightBase.name.fset(self, name) # rename
|
|
591
559
|
if smooth:
|
|
592
560
|
self._smooth = Int_(smooth=smooth, Error=GeoidError, low=0)
|
|
593
561
|
|
|
@@ -647,8 +615,8 @@ class _GeoidBase(_HeightsBase):
|
|
|
647
615
|
swne = crop
|
|
648
616
|
if len(swne) == 4:
|
|
649
617
|
s, w, n, e = map(float, swne)
|
|
650
|
-
if
|
|
651
|
-
|
|
618
|
+
if _N_90_0 <= s <= (n - _1_0) <= 89.0 and \
|
|
619
|
+
_N_180_0 <= w <= (e - _1_0) <= 179.0:
|
|
652
620
|
return s, w, n, e
|
|
653
621
|
except (IndexError, TypeError, ValueError):
|
|
654
622
|
pass
|
|
@@ -684,7 +652,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
684
652
|
|
|
685
653
|
@Property_RO
|
|
686
654
|
def _upperleft(self):
|
|
687
|
-
'''(INTERNAL) Cache for
|
|
655
|
+
'''(INTERNAL) Cache for C{.upperleft}.
|
|
688
656
|
'''
|
|
689
657
|
return self._llh3(self._lat_hi, self._lon_lo)
|
|
690
658
|
|
|
@@ -702,7 +670,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
702
670
|
|
|
703
671
|
@Property_RO
|
|
704
672
|
def _upperright(self):
|
|
705
|
-
'''(INTERNAL) Cache for
|
|
673
|
+
'''(INTERNAL) Cache for C{.upperright}.
|
|
706
674
|
'''
|
|
707
675
|
return self._llh3(self._lat_hi, self._lon_hi)
|
|
708
676
|
|
|
@@ -719,12 +687,6 @@ class _GeoidBase(_HeightsBase):
|
|
|
719
687
|
return self._llh3LL(self._upperright, LatLon)
|
|
720
688
|
|
|
721
689
|
|
|
722
|
-
class GeoidError(HeightError):
|
|
723
|
-
'''Geoid interpolator C{Geoid...} or interpolation issue.
|
|
724
|
-
'''
|
|
725
|
-
pass
|
|
726
|
-
|
|
727
|
-
|
|
728
690
|
class GeoidG2012B(_GeoidBase):
|
|
729
691
|
'''Geoid height interpolator for U{GEOID12B Model
|
|
730
692
|
<https://www.NGS.NOAA.gov/GEOID/GEOID12B/>} grids U{CONUS
|
|
@@ -736,10 +698,11 @@ class GeoidG2012B(_GeoidBase):
|
|
|
736
698
|
U{Puerto Rico and U.S. Virgin Islands
|
|
737
699
|
<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_PRVI.shtml>} and
|
|
738
700
|
U{American Samoa<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_AS.shtml>}
|
|
739
|
-
based on C{SciPy} U{RectBivariateSpline<https://docs.SciPy.org/doc/
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
701
|
+
based on C{SciPy} U{RectBivariateSpline<https://docs.SciPy.org/doc/scipy/
|
|
702
|
+
reference/generated/scipy.interpolate.RectBivariateSpline.html>}, U{interp2d
|
|
703
|
+
<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate
|
|
704
|
+
.interp2d.html>} or U{bisplrep/-ev<https://docs.scipy.org/doc/scipy/reference/
|
|
705
|
+
generated/scipy.interpolate.bisplrep.html>} interpolation.
|
|
743
706
|
|
|
744
707
|
Use any of the binary C{le} (little endian) or C{be} (big endian)
|
|
745
708
|
C{g2012b*.bin} grid files.
|
|
@@ -749,38 +712,34 @@ class GeoidG2012B(_GeoidBase):
|
|
|
749
712
|
'''New L{GeoidG2012B} interpolator.
|
|
750
713
|
|
|
751
714
|
@arg g2012b_bin: A C{GEOID12B} grid file name (C{.bin}).
|
|
752
|
-
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}
|
|
753
|
-
|
|
754
|
-
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
reference/generated/scipy.
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
@raise ImportError: Package C{numpy} or C{scipy} not found or not
|
|
771
|
-
installed.
|
|
715
|
+
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or
|
|
716
|
+
L{a_f2Tuple}), default C{WGS84}.
|
|
717
|
+
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for U{RectBivariateSpline
|
|
718
|
+
<https://docs.SciPy.org/doc/scipy/ reference/generated/scipy.interpolate.
|
|
719
|
+
RectBivariateSpline.html>} or -1, -3 or -5 for U{bisplrep/-ev<https://
|
|
720
|
+
docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html>}
|
|
721
|
+
or U{interp2d<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.
|
|
722
|
+
interpolate.interp2d.html>} C{linear}, C{cubic} respectively C{quintic},
|
|
723
|
+
see note for more details.
|
|
724
|
+
@kwarg smooth: Smoothing factor for C{B{kind}=1..5} only (C{int}).
|
|
725
|
+
@kwarg name_crop: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED keyword argument
|
|
726
|
+
C{B{crop}=None}.
|
|
727
|
+
|
|
728
|
+
@raise GeoidError: Invalid B{C{crop}}, B{C{kind}} or B{C{smooth}} or a G2012B grid file
|
|
729
|
+
B{C{g2012b_bin}} issue.
|
|
730
|
+
|
|
731
|
+
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
|
|
772
732
|
|
|
773
733
|
@raise LenError: Grid file B{C{g2012b_bin}} axis mismatch.
|
|
774
734
|
|
|
775
|
-
@raise SciPyError: A C{
|
|
735
|
+
@raise SciPyError: A C{scipy} issue.
|
|
776
736
|
|
|
777
|
-
@raise SciPyWarning: A C{
|
|
778
|
-
warning as exception.
|
|
737
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
779
738
|
|
|
780
739
|
@raise TypeError: Invalid B{C{datum}}.
|
|
781
740
|
|
|
782
|
-
@note: C{
|
|
783
|
-
|
|
741
|
+
@note: Specify C{B{kind}=-1, -3 or -5} to use C{scipy.interpolate.interp2d}
|
|
742
|
+
before or C{scipy.interpolate.bisplrep/-ev} since C{Scipy} version 1.14.
|
|
784
743
|
'''
|
|
785
744
|
crop, name = _xkwds_pop2(name_crop, crop=None)
|
|
786
745
|
if crop is not None:
|
|
@@ -923,6 +882,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
923
882
|
_T( 0, 2),
|
|
924
883
|
_T( 1, 2))
|
|
925
884
|
|
|
885
|
+
# _cropped = None
|
|
926
886
|
_endian = '>H' # struct.unpack 1 ushort (big endian, unsigned short)
|
|
927
887
|
_4endian = '>4H' # struct.unpack 4 ushorts
|
|
928
888
|
_Rendian = NN # struct.unpack a row of ushorts
|
|
@@ -940,9 +900,9 @@ class GeoidKarney(_GeoidBase):
|
|
|
940
900
|
_u2B = _calcsize(_endian) # pixelsize_ in bytes
|
|
941
901
|
_4u2B = _calcsize(_4endian) # 4 pixelsize_s in bytes
|
|
942
902
|
_Ru2B = 0 # row of pixelsize_s in bytes
|
|
943
|
-
_yxH = () # cache (y, x) indices
|
|
944
|
-
_yxHt = () # cached 4- or 10-tuple for _ev2H resp. _ev3H
|
|
945
903
|
_yx_hits = 0 # cache hits
|
|
904
|
+
_yx_i = () # cached (y, x) indices
|
|
905
|
+
_yx_t = () # cached 4- or 10-tuple for _ev2k resp. _ev3k
|
|
946
906
|
|
|
947
907
|
def __init__(self, egm_pgm, crop=None, datum=None, # WGS84
|
|
948
908
|
kind=3, **name_smooth):
|
|
@@ -952,34 +912,31 @@ class GeoidKarney(_GeoidBase):
|
|
|
952
912
|
C++/doc/geoid.html#geoidinst>} file name (C{egm*.pgm}), see
|
|
953
913
|
note below.
|
|
954
914
|
@kwarg crop: Optional box to limit geoid locations, a 4-tuple (C{south,
|
|
955
|
-
west, north, east}), 2-tuple (C{(south, west), (north,
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
@kwarg kind: Interpolation order (C{int}), 2 for C{bilinear} or 3
|
|
962
|
-
for C{cubic}.
|
|
915
|
+
west, north, east}), 2-tuple (C{(south, west), (north, east)})
|
|
916
|
+
with 2 C{degrees90} lat- and C{degrees180} longitudes or as
|
|
917
|
+
2-tuple (C{LatLonSW, LatLonNE}) of C{LatLon} instances.
|
|
918
|
+
@kwarg datum: Optional grid datum (C{Datum}, L{Ellipsoid}, L{Ellipsoid2} or
|
|
919
|
+
L{a_f2Tuple}), default C{WGS84}.
|
|
920
|
+
@kwarg kind: Interpolation order (C{int}), 2 for C{bilinear} or 3 for C{cubic}.
|
|
963
921
|
@kwarg name_smooth: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED
|
|
964
922
|
keyword argument C{B{smooth}}, use C{B{smooth}=None} to ignore.
|
|
965
923
|
|
|
966
|
-
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid
|
|
967
|
-
B{C{
|
|
924
|
+
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}},
|
|
925
|
+
B{C{kind}} or B{C{smooth}}.
|
|
968
926
|
|
|
969
927
|
@raise TypeError: Invalid B{C{datum}}.
|
|
970
928
|
|
|
971
929
|
@see: Class L{GeoidPGM} and function L{egmGeoidHeights}.
|
|
972
930
|
|
|
973
|
-
@note: Geoid file B{C{egm_pgm}} remains open and must be closed
|
|
974
|
-
|
|
975
|
-
in a C{with B{GeoidKarney}(...) as ...} context.
|
|
931
|
+
@note: Geoid file B{C{egm_pgm}} remains open and I{must be closed} by calling
|
|
932
|
+
method C{close} or by using C{with B{GeoidKarney}(...) as ...:} context.
|
|
976
933
|
'''
|
|
977
934
|
smooth, name = _xkwds_pop2(name_smooth, smooth=None)
|
|
978
935
|
if smooth is not None:
|
|
979
936
|
raise GeoidError(smooth=smooth, txt_not_=_supported_)
|
|
980
937
|
|
|
981
938
|
if kind in (2,):
|
|
982
|
-
self.
|
|
939
|
+
self._ev2d = self._ev2k # see ._ev_name
|
|
983
940
|
elif kind not in (3,):
|
|
984
941
|
raise GeoidError(kind=kind)
|
|
985
942
|
|
|
@@ -995,7 +952,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
995
952
|
# set earth (lat, lon) limits (s, w, n, e)
|
|
996
953
|
self._lat_lo, self._lon_lo, \
|
|
997
954
|
self._lat_hi, self._lon_hi = self._swne(crop if crop else p.crop4)
|
|
998
|
-
self._cropped =
|
|
955
|
+
self._cropped = bool(crop)
|
|
999
956
|
|
|
1000
957
|
def __call__(self, *llis, **wrap_H):
|
|
1001
958
|
'''Interpolate the geoid height for one or several locations.
|
|
@@ -1011,16 +968,15 @@ class GeoidKarney(_GeoidBase):
|
|
|
1011
968
|
(C{float}) or a list or tuple of interpolated geoid
|
|
1012
969
|
(or orthometric) heights (C{float}s).
|
|
1013
970
|
|
|
1014
|
-
@raise GeoidError: Insufficient number of B{C{llis}}, an
|
|
1015
|
-
|
|
1016
|
-
geoid file is closed.
|
|
971
|
+
@raise GeoidError: Insufficient number of B{C{llis}}, an invalid
|
|
972
|
+
B{C{lli}} or the C{egm*.pgm} geoid file is closed.
|
|
1017
973
|
|
|
1018
|
-
@raise RangeError: An B{C{lli}} is outside this geoid's lat-
|
|
1019
|
-
|
|
974
|
+
@raise RangeError: An B{C{lli}} is outside this geoid's lat- or
|
|
975
|
+
longitude range.
|
|
1020
976
|
|
|
1021
|
-
@note: To obtain I{orthometric} heights, each B{C{llis}}
|
|
1022
|
-
|
|
1023
|
-
|
|
977
|
+
@note: To obtain I{orthometric} heights, each B{C{llis}} location
|
|
978
|
+
must have an ellipsoid C{height} or C{h} attribute, otherwise
|
|
979
|
+
C{height=0} is used.
|
|
1024
980
|
|
|
1025
981
|
@see: Function L{pygeodesy.heightOrthometric}.
|
|
1026
982
|
'''
|
|
@@ -1068,38 +1024,38 @@ class GeoidKarney(_GeoidBase):
|
|
|
1068
1024
|
y, x = int(floor(fy)), int(floor(fx))
|
|
1069
1025
|
fy -= y
|
|
1070
1026
|
fx -= x
|
|
1071
|
-
H = self.
|
|
1027
|
+
H = self._ev2d(fy, fx, y, x) # PYCHOK ._ev2k or ._ev3k
|
|
1072
1028
|
H *= self._pgm.Scale # H.fmul(self._pgm.Scale)
|
|
1073
1029
|
H += self._pgm.Offset # H.fadd(self._pgm.Offset)
|
|
1074
|
-
return H.fsum()
|
|
1030
|
+
return H.fsum() # float(H)
|
|
1075
1031
|
|
|
1076
|
-
def
|
|
1032
|
+
def _ev2k(self, fy, fx, *yx):
|
|
1077
1033
|
# compute the bilinear 4-tuple and interpolate raw H
|
|
1078
|
-
if self.
|
|
1079
|
-
t = self._yxHt
|
|
1034
|
+
if self._yx_i == yx:
|
|
1080
1035
|
self._yx_hits += 1
|
|
1081
1036
|
else:
|
|
1082
|
-
y, x = self.
|
|
1083
|
-
self.
|
|
1037
|
+
y, x = self._yx_i = yx
|
|
1038
|
+
self._yx_t = self._raws(y, x, GeoidKarney._BT)
|
|
1039
|
+
t = self._yx_t
|
|
1084
1040
|
v = _1_0, -fx, fx
|
|
1085
1041
|
H = Fdot(v, t[0], t[0], t[1]).fmul(_1_0 - fy) # c = a * (1 - fy)
|
|
1086
1042
|
H += Fdot(v, t[2], t[2], t[3]).fmul(fy) # c += b * fy
|
|
1087
1043
|
return H
|
|
1088
1044
|
|
|
1089
|
-
def
|
|
1045
|
+
def _ev3k(self, fy, fx, *yx):
|
|
1090
1046
|
# compute the cubic 10-tuple and interpolate raw H
|
|
1091
|
-
if self.
|
|
1092
|
-
t = self._yxHt
|
|
1047
|
+
if self._yx_i == yx:
|
|
1093
1048
|
self._yx_hits += 1
|
|
1094
1049
|
else:
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
self.
|
|
1050
|
+
c0, c3, v = self._c0c3v(*yx)
|
|
1051
|
+
# assert len(c3) == self._nterms
|
|
1052
|
+
self._yx_t = tuple(fdot(v, *r3) / c0 for r3 in c3)
|
|
1053
|
+
self._yx_i = yx
|
|
1099
1054
|
# GeographicLib/Geoid.cpp Geoid::height(lat, lon) ...
|
|
1100
1055
|
# real h = t[0] + fx * (t[1] + fx * (t[3] + fx * t[6])) +
|
|
1101
1056
|
# fy * (t[2] + fx * (t[4] + fx * t[7]) +
|
|
1102
1057
|
# fy * (t[5] + fx * t[8] + fy * t[9]));
|
|
1058
|
+
t = self._yx_t
|
|
1103
1059
|
v = _1_0, fx, fy
|
|
1104
1060
|
H = Fdot(v, t[5], t[8], t[9])
|
|
1105
1061
|
H *= fy
|
|
@@ -1108,7 +1064,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
1108
1064
|
H += Fhorner(fx, t[0], t[1], t[3], t[6])
|
|
1109
1065
|
return H
|
|
1110
1066
|
|
|
1111
|
-
|
|
1067
|
+
_ev2d = _ev3k # overriden for kind=2, see ._ev_name
|
|
1112
1068
|
|
|
1113
1069
|
def _g2ll2(self, lat, lon):
|
|
1114
1070
|
# convert grid (lat, lon) to earth (lat, lon), uncropped
|
|
@@ -1145,13 +1101,14 @@ class GeoidKarney(_GeoidBase):
|
|
|
1145
1101
|
@raise RangeError: A B{C{lat}} or B{C{lon}} is outside this
|
|
1146
1102
|
geoid's lat- or longitude range.
|
|
1147
1103
|
'''
|
|
1148
|
-
|
|
1104
|
+
lls = self._as_lls(lats, lons)
|
|
1105
|
+
return self(lls, **wrap) # __call__(ll) or __call__(lls)
|
|
1149
1106
|
|
|
1150
1107
|
@Property_RO
|
|
1151
1108
|
def _highest_ltd(self):
|
|
1152
|
-
'''(INTERNAL) Cache for
|
|
1109
|
+
'''(INTERNAL) Cache for C{.highest}.
|
|
1153
1110
|
'''
|
|
1154
|
-
return self._llh3minmax(True, -12, -4)
|
|
1111
|
+
return self._LL3T(self._llh3minmax(True, -12, -4), name__=self.highest)
|
|
1155
1112
|
|
|
1156
1113
|
def highest(self, LatLon=None, full=False): # PYCHOK full
|
|
1157
1114
|
'''Return the location and largest height of this geoid.
|
|
@@ -1181,30 +1138,34 @@ class GeoidKarney(_GeoidBase):
|
|
|
1181
1138
|
lon += _360_0
|
|
1182
1139
|
return lat, lon
|
|
1183
1140
|
|
|
1184
|
-
def _llh3minmax(self, highest
|
|
1141
|
+
def _llh3minmax(self, highest, *lat2):
|
|
1185
1142
|
# find highest or lowest, takes 10+ secs for egm2008-1.pgm geoid
|
|
1186
1143
|
# (Python 2.7.16, macOS 10.13.6 High Sierra, iMac 3 GHz Core i3)
|
|
1187
|
-
y = x = 0
|
|
1188
|
-
h = self._raw(y, x)
|
|
1189
1144
|
if highest:
|
|
1190
|
-
|
|
1145
|
+
def _mt(r, h):
|
|
1191
1146
|
m = max(r)
|
|
1192
|
-
|
|
1193
|
-
|
|
1147
|
+
return m, (m > h)
|
|
1148
|
+
|
|
1194
1149
|
else: # lowest
|
|
1195
|
-
|
|
1150
|
+
def _mt(r, h): # PYCHOK redef
|
|
1196
1151
|
m = min(r)
|
|
1197
|
-
|
|
1198
|
-
|
|
1152
|
+
return m, (m < h)
|
|
1153
|
+
|
|
1154
|
+
y = x = 0
|
|
1155
|
+
h = self._raw(y, x)
|
|
1156
|
+
for j, r in self._raw2(*lat2):
|
|
1157
|
+
m, t = _mt(r, h)
|
|
1158
|
+
if t:
|
|
1159
|
+
h, y, x = m, j, r.index(m)
|
|
1199
1160
|
h *= self._pgm.Scale
|
|
1200
1161
|
h += self._pgm.Offset
|
|
1201
1162
|
return self._g2ll2(*self._gyx2g2(y, x)) + (h,)
|
|
1202
1163
|
|
|
1203
1164
|
@Property_RO
|
|
1204
1165
|
def _lowest_ltd(self):
|
|
1205
|
-
'''(INTERNAL) Cache for
|
|
1166
|
+
'''(INTERNAL) Cache for C{.lowest}.
|
|
1206
1167
|
'''
|
|
1207
|
-
return self._llh3minmax(False, 0, 8)
|
|
1168
|
+
return self._LL3T(self._llh3minmax(False, 0, 8), name__=self.lowest)
|
|
1208
1169
|
|
|
1209
1170
|
def lowest(self, LatLon=None, full=False): # PYCHOK full
|
|
1210
1171
|
'''Return the location and lowest height of this geoid.
|
|
@@ -1269,25 +1230,21 @@ class GeoidKarney(_GeoidBase):
|
|
|
1269
1230
|
|
|
1270
1231
|
class GeoidPGM(_GeoidBase):
|
|
1271
1232
|
'''Geoid height interpolator for I{Karney}'s U{GeographicLib Earth
|
|
1272
|
-
Gravitational Model (EGM)<https://GeographicLib.SourceForge.io/C++/doc/
|
|
1273
|
-
geoid
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
generated/scipy.interpolate.
|
|
1277
|
-
U{interp2d<https://docs.SciPy.org/doc/scipy/reference/generated/
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
Use any of the U{egm84-, egm96- or egm2008-*.pgm
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
is
|
|
1284
|
-
doc/
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
2-byte C{int} to 8-byte C{dtype float64}. Therefore, internal memory
|
|
1288
|
-
usage is 4x the U{egm*.pgm<https://GeographicLib.SourceForge.io/C++/doc/
|
|
1289
|
-
geoid.html#geoidinst>} file size and may exceed the available memory,
|
|
1290
|
-
especially with 32-bit Python, see properties C{.nBytes} and C{.sizeB}.
|
|
1233
|
+
Gravitational Model (EGM)<https://GeographicLib.SourceForge.io/C++/doc/geoid.html>}
|
|
1234
|
+
geoid U{egm*.pgm<https://GeographicLib.SourceForge.io/C++/doc/geoid.html#geoidinst>}
|
|
1235
|
+
datasets but based on C{SciPy} U{RectBivariateSpline<https://docs.SciPy.org/doc/scipy/
|
|
1236
|
+
reference/generated/scipy.interpolate.RectBivariateSpline.html>}, U{bisplrep/-ev
|
|
1237
|
+
<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html>}
|
|
1238
|
+
or U{interp2d<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.
|
|
1239
|
+
interp2d.html>} interpolation.
|
|
1240
|
+
|
|
1241
|
+
Use any of the U{egm84-, egm96- or egm2008-*.pgm <https://GeographicLib.SourceForge.io/
|
|
1242
|
+
C++/doc/geoid.html#geoidinst>} datasets. However, unless cropped, an entire C{egm*.pgm}
|
|
1243
|
+
dataset is loaded into the C{SciPy} interpolator and converted from 2-byte C{int} to
|
|
1244
|
+
8-byte C{dtype float64}. Therefore, internal memory usage is 4x the U{egm*.pgm
|
|
1245
|
+
<https://GeographicLib.SourceForge.io/C++/doc/geoid.html#geoidinst>} file size and may
|
|
1246
|
+
exceed the available memory, especially with 32-bit Python, see properties C{.nBytes}
|
|
1247
|
+
and C{.sizeB}.
|
|
1291
1248
|
'''
|
|
1292
1249
|
_cropped = False
|
|
1293
1250
|
_endian = '>u2'
|
|
@@ -1300,48 +1257,44 @@ class GeoidPGM(_GeoidBase):
|
|
|
1300
1257
|
C++/doc/geoid.html#geoidinst>} file name (C{egm*.pgm}).
|
|
1301
1258
|
@kwarg crop: Optional box to crop B{C{egm_pgm}}, a 4-tuple (C{south, west,
|
|
1302
1259
|
north, east}) or 2-tuple (C{(south, west), (north, east)}),
|
|
1303
|
-
in C{degrees90} lat- and C{degrees180} longitudes or a
|
|
1304
|
-
|
|
1305
|
-
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}
|
|
1306
|
-
|
|
1307
|
-
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
reference/generated/scipy.
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
scipy.interpolate.RectBivariateSpline.html>}
|
|
1316
|
-
only (C{int}).
|
|
1260
|
+
in C{degrees90} lat- and C{degrees180} longitudes or a 2-tuple
|
|
1261
|
+
(C{LatLonSW, LatLonNE}) of C{LatLon} instances.
|
|
1262
|
+
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or
|
|
1263
|
+
L{a_f2Tuple}), default C{WGS84}.
|
|
1264
|
+
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for U{RectBivariateSpline
|
|
1265
|
+
<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.
|
|
1266
|
+
RectBivariateSpline.html>} or -1, -3 or -5 for U{bisplrep/-ev<https://
|
|
1267
|
+
docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html>}
|
|
1268
|
+
or U{interp2d<https://docs.SciPy.org/doc/scipy/reference/generated/scipy.
|
|
1269
|
+
interpolate.interp2d.html>} C{linear}, C{cubic} respectively C{quintic},
|
|
1270
|
+
see note for more details.
|
|
1271
|
+
@kwarg smooth: Smoothing factor for C{B{kind}=1..5} only (C{int}).
|
|
1317
1272
|
@kwarg name: Optional geoid C{B{name}=NN} (C{str}).
|
|
1318
1273
|
|
|
1319
|
-
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}},
|
|
1320
|
-
|
|
1274
|
+
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}}, B{C{kind}}
|
|
1275
|
+
or B{C{smooth}}.
|
|
1321
1276
|
|
|
1322
1277
|
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
|
|
1323
1278
|
|
|
1324
1279
|
@raise LenError: EGM dataset B{C{egm_pgm}} axis mismatch.
|
|
1325
1280
|
|
|
1326
|
-
@raise SciPyError: A C{
|
|
1281
|
+
@raise SciPyError: A C{scipy} issue.
|
|
1327
1282
|
|
|
1328
|
-
@raise SciPyWarning: A C{
|
|
1329
|
-
warning as exception.
|
|
1283
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
1330
1284
|
|
|
1331
1285
|
@raise TypeError: Invalid B{C{datum}} or unexpected argument.
|
|
1332
1286
|
|
|
1333
|
-
@note: C{
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
@note: The U{GeographicLib egm*.pgm<https://GeographicLib.SourceForge.io/
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
www.NGS.NOAA.gov/GEOID/GEOID12B/maps/GEOID12B_CONUS_grids.png>}
|
|
1287
|
+
@note: Specify C{B{kind}=-1, -3 or -5} to use C{scipy.interpolate.interp2d}
|
|
1288
|
+
before or C{scipy.interpolate.bisplrep/-ev} since C{Scipy} version 1.14.
|
|
1289
|
+
|
|
1290
|
+
@note: The U{GeographicLib egm*.pgm<https://GeographicLib.SourceForge.io/C++/doc/
|
|
1291
|
+
geoid.html#geoidinst>} file sizes are based on a 2-byte C{int} height
|
|
1292
|
+
converted to 8-byte C{dtype float64} for C{scipy} interpolators. Therefore,
|
|
1293
|
+
internal memory usage is 4 times the C{egm*.pgm} file size and may exceed
|
|
1294
|
+
the available memory, especially with 32-bit Python. To reduce memory
|
|
1295
|
+
usage, set keyword argument B{C{crop}} to the region of interest. For
|
|
1296
|
+
example C{B{crop}=(20, -125, 50, -65)} covers the U{conterminous US
|
|
1297
|
+
<https://www.NGS.NOAA.gov/GEOID/GEOID12B/maps/GEOID12B_CONUS_grids.png>}
|
|
1345
1298
|
(CONUS), less than 3% of the entire C{egm2008-1.pgm} dataset.
|
|
1346
1299
|
|
|
1347
1300
|
@see: Class L{GeoidKarney} and function L{egmGeoidHeights}.
|
|
@@ -1711,9 +1664,10 @@ def egmGeoidHeights(GeoidHeights_dat):
|
|
|
1711
1664
|
|
|
1712
1665
|
__all__ += _ALL_DOCS(_GeoidBase)
|
|
1713
1666
|
|
|
1714
|
-
if __name__ == '__main__':
|
|
1667
|
+
if __name__ == '__main__': # MCCABE 14
|
|
1715
1668
|
|
|
1716
|
-
from pygeodesy.internals import printf, _sys
|
|
1669
|
+
from pygeodesy.internals import printf, _secs2str, _sys, _versions
|
|
1670
|
+
from time import time
|
|
1717
1671
|
|
|
1718
1672
|
_crop = ()
|
|
1719
1673
|
_GeoidEGM = GeoidKarney
|
|
@@ -1737,7 +1691,10 @@ if __name__ == '__main__':
|
|
|
1737
1691
|
|
|
1738
1692
|
elif geoid[-4:].lower() in ('.pgm',):
|
|
1739
1693
|
g = _GeoidEGM(geoid, crop=_crop, kind=_kind)
|
|
1740
|
-
|
|
1694
|
+
t = time()
|
|
1695
|
+
_ = g.highest()
|
|
1696
|
+
t = _secs2str(time() - t)
|
|
1697
|
+
printf('%s: %s (%s)', g.toStr(), t, _versions(), nl=1, nt=1)
|
|
1741
1698
|
printf(repr(g.pgm), nt=1)
|
|
1742
1699
|
# <https://GeographicLib.SourceForge.io/cgi-bin/GeoidEval>:
|
|
1743
1700
|
# The height of the EGM96 geoid at Timbuktu
|
|
@@ -1767,27 +1724,6 @@ if __name__ == '__main__':
|
|
|
1767
1724
|
_I = int # PYCHOK unused _I
|
|
1768
1725
|
del _intCs # trash ints cache
|
|
1769
1726
|
|
|
1770
|
-
# **) MIT License
|
|
1771
|
-
#
|
|
1772
|
-
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1773
|
-
#
|
|
1774
|
-
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1775
|
-
# copy of this software and associated documentation files (the "Software"),
|
|
1776
|
-
# to deal in the Software without restriction, including without limitation
|
|
1777
|
-
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
1778
|
-
# and/or sell copies of the Software, and to permit persons to whom the
|
|
1779
|
-
# Software is furnished to do so, subject to the following conditions:
|
|
1780
|
-
#
|
|
1781
|
-
# The above copyright notice and this permission notice shall be included
|
|
1782
|
-
# in all copies or substantial portions of the Software.
|
|
1783
|
-
#
|
|
1784
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
1785
|
-
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1786
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
1787
|
-
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
1788
|
-
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
1789
|
-
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
1790
|
-
# OTHER DEALINGS IN THE SOFTWARE.
|
|
1791
1727
|
|
|
1792
1728
|
# <https://GeographicLib.SourceForge.io/cgi-bin/GeoidEval>
|
|
1793
1729
|
# _lowerleft = -90, -179, -30.1500 # egm2008-1.pgm
|
|
@@ -1803,23 +1739,23 @@ del _intCs # trash ints cache
|
|
|
1803
1739
|
# _upperright = 90, 180, 13.0980 # egm84-15.pgm
|
|
1804
1740
|
|
|
1805
1741
|
|
|
1806
|
-
# % python3 -m pygeodesy.geoids
|
|
1742
|
+
# % python3.12 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1807
1743
|
#
|
|
1808
|
-
# GeoidKarney('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, 147.367, 85.839), lowest(4.7, 78.767, -106.911)
|
|
1744
|
+
# GeoidKarney('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, 147.367, 85.839), lowest(4.7, 78.767, -106.911): 204.334 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1809
1745
|
#
|
|
1810
1746
|
# _PGM('../testGeoids/egm2008-1.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-31 06:54:00', Description='WGS84 EGM2008, 1-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.025, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.001, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008', Vertical_Datum='WGS84'
|
|
1811
1747
|
#
|
|
1812
1748
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1813
1749
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1814
1750
|
#
|
|
1815
|
-
# GeoidKarney('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, 148.75, 81.33), lowest(4.75, 79.25, -107.34)
|
|
1751
|
+
# GeoidKarney('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, 148.75, 81.33), lowest(4.75, 79.25, -107.34): 1.007 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1816
1752
|
#
|
|
1817
1753
|
# _PGM('../testGeoids/egm84-15.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:02', Description='WGS84 EGM84, 15-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.413, MaxCubicError=0.02, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.018, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html', Vertical_Datum='WGS84'
|
|
1818
1754
|
#
|
|
1819
1755
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1820
1756
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1821
1757
|
#
|
|
1822
|
-
# GeoidKarney('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, 0.0, 17.163), highest(-8.167, 147.25, 85.422), lowest(4.667, 78.833, -107.043)
|
|
1758
|
+
# GeoidKarney('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, 0.0, 17.163), highest(-8.167, 147.25, 85.422), lowest(4.667, 78.833, -107.043): 8.509 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1823
1759
|
#
|
|
1824
1760
|
# _PGM('../testGeoids/egm96-5.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:03', Description='WGS84 EGM96, 5-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.14, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.005, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html', Vertical_Datum='WGS84'
|
|
1825
1761
|
#
|
|
@@ -1827,23 +1763,23 @@ del _intCs # trash ints cache
|
|
|
1827
1763
|
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1828
1764
|
|
|
1829
1765
|
|
|
1830
|
-
# % python3 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1766
|
+
# % python3.8 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1831
1767
|
#
|
|
1832
|
-
# GeoidKarney('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, 147.367, 85.839), lowest(4.7, 78.767, -106.911)
|
|
1768
|
+
# GeoidKarney('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, 147.367, 85.839), lowest(4.7, 78.767, -106.911): 353.050 ms (pygeodesy 24.8.24 Python 3.8.10 64bit arm64_x86_64 macOS 10.16)
|
|
1833
1769
|
#
|
|
1834
1770
|
# _PGM('../testGeoids/egm2008-1.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-31 06:54:00', Description='WGS84 EGM2008, 1-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.025, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.001, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008', Vertical_Datum='WGS84'
|
|
1835
1771
|
#
|
|
1836
1772
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1837
1773
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1838
1774
|
#
|
|
1839
|
-
# GeoidKarney('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, 148.75, 81.33), lowest(4.75, 79.25, -107.34)
|
|
1775
|
+
# GeoidKarney('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, 148.75, 81.33), lowest(4.75, 79.25, -107.34): 1.727 ms (pygeodesy 24.8.24 Python 3.8.10 64bit arm64_x86_64 macOS 10.16)
|
|
1840
1776
|
#
|
|
1841
1777
|
# _PGM('../testGeoids/egm84-15.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:02', Description='WGS84 EGM84, 15-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.413, MaxCubicError=0.02, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.018, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html', Vertical_Datum='WGS84'
|
|
1842
1778
|
#
|
|
1843
1779
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1844
1780
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1845
1781
|
#
|
|
1846
|
-
# GeoidKarney('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, 0.0, 17.163), highest(-8.167, 147.25, 85.422), lowest(4.667, 78.833, -107.043)
|
|
1782
|
+
# GeoidKarney('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, 0.0, 17.163), highest(-8.167, 147.25, 85.422), lowest(4.667, 78.833, -107.043): 14.807 ms (pygeodesy 24.8.24 Python 3.8.10 64bit arm64_x86_64 macOS 10.16)
|
|
1847
1783
|
#
|
|
1848
1784
|
# _PGM('../testGeoids/egm96-5.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:03', Description='WGS84 EGM96, 5-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.14, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.005, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html', Vertical_Datum='WGS84'
|
|
1849
1785
|
#
|
|
@@ -1851,25 +1787,71 @@ del _intCs # trash ints cache
|
|
|
1851
1787
|
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1852
1788
|
|
|
1853
1789
|
|
|
1854
|
-
# % python2 -m pygeodesy.geoids -
|
|
1790
|
+
# % python2 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1855
1791
|
#
|
|
1856
|
-
#
|
|
1792
|
+
# GeoidKarney('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, 147.367, 85.839), lowest(4.7, 78.767, -106.911): 283.362 ms (pygeodesy 24.8.24 Python 2.7.18 64bit arm64_x86_64 macOS 10.16)
|
|
1793
|
+
#
|
|
1794
|
+
# _PGM('../testGeoids/egm2008-1.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-31 06:54:00', Description='WGS84 EGM2008, 1-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.025, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.001, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008', Vertical_Datum='WGS84'
|
|
1795
|
+
#
|
|
1796
|
+
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1797
|
+
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1798
|
+
#
|
|
1799
|
+
# GeoidKarney('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, 148.75, 81.33), lowest(4.75, 79.25, -107.34): 1.378 ms (pygeodesy 24.8.24 Python 2.7.18 64bit arm64_x86_64 macOS 10.16)
|
|
1800
|
+
#
|
|
1801
|
+
# _PGM('../testGeoids/egm84-15.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:02', Description='WGS84 EGM84, 15-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.413, MaxCubicError=0.02, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.018, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html', Vertical_Datum='WGS84'
|
|
1802
|
+
#
|
|
1803
|
+
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1804
|
+
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1805
|
+
#
|
|
1806
|
+
# GeoidKarney('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, 0.0, 17.163), highest(-8.167, 147.25, 85.422), lowest(4.667, 78.833, -107.043): 11.612 ms (pygeodesy 24.8.24 Python 2.7.18 64bit arm64_x86_64 macOS 10.16)
|
|
1807
|
+
#
|
|
1808
|
+
# _PGM('../testGeoids/egm96-5.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:03', Description='WGS84 EGM96, 5-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.14, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.005, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html', Vertical_Datum='WGS84'
|
|
1809
|
+
#
|
|
1810
|
+
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.775833, -3.009444): 28.7068 vs 28.7067
|
|
1811
|
+
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
# % python3.12 -m pygeodesy.geoids -PGM ../testGeoids/egm*.pgm
|
|
1815
|
+
#
|
|
1816
|
+
# GeoidPGM('egm2008-1.pgm'): lowerleft(-90.0, -180.0, -30.15), upperright(90.0, 180.0, 14.898), center(0.0, 0.0, 17.226), highest(-8.4, -32.633, 85.839), lowest(4.683, -101.25, -106.911): 543.148 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1857
1817
|
#
|
|
1858
1818
|
# _PGM('../testGeoids/egm2008-1.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-31 06:54:00', Description='WGS84 EGM2008, 1-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.025, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.001, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008', Vertical_Datum='WGS84'
|
|
1859
1819
|
#
|
|
1860
1820
|
# Timbuktu GeoidPGM('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1861
1821
|
# Timbuktu GeoidPGM('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1862
1822
|
#
|
|
1863
|
-
# GeoidPGM('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, -31.25, 81.33), lowest(4.75, -100.75, -107.34)
|
|
1823
|
+
# GeoidPGM('egm84-15.pgm'): lowerleft(-90.0, -180.0, -29.712), upperright(90.0, 180.0, 13.098), center(0.0, 0.0, 18.33), highest(-4.5, -31.25, 81.33), lowest(4.75, -100.75, -107.34): 1.762 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1864
1824
|
#
|
|
1865
1825
|
# _PGM('../testGeoids/egm84-15.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:02', Description='WGS84 EGM84, 15-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.413, MaxCubicError=0.02, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.018, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html', Vertical_Datum='WGS84'
|
|
1866
1826
|
#
|
|
1867
1827
|
# Timbuktu GeoidPGM('egm84-15.pgm').height(16.775833, -3.009444): 31.2979 vs 31.2979
|
|
1868
1828
|
# Timbuktu GeoidPGM('egm84-15.pgm').height(16.776, -3.009): 31.2975 vs 31.2979
|
|
1869
1829
|
#
|
|
1870
|
-
# GeoidPGM('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, -0.0, 17.179), highest(-8.167, -32.75, 85.422), lowest(4.667, -101.167, -107.043)
|
|
1830
|
+
# GeoidPGM('egm96-5.pgm'): lowerleft(-90.0, -180.0, -29.535), upperright(90.0, 180.0, 13.605), center(0.0, -0.0, 17.179), highest(-8.167, -32.75, 85.422), lowest(4.667, -101.167, -107.043): 12.594 ms (pygeodesy 24.8.24 Python 3.12.5 64bit arm64 macOS 14.6.1)
|
|
1871
1831
|
#
|
|
1872
1832
|
# _PGM('../testGeoids/egm96-5.pgm'): AREA_OR_POINT='Point', DateTime='2009-08-29 18:45:03', Description='WGS84 EGM96, 5-minute grid', Geoid='file in PGM format for the GeographicLib::Geoid class', MaxBilinearError=0.14, MaxCubicError=0.003, Offset=-108.0, Origin=LatLon2Tuple(lat=90.0, lon=0.0), Pixel=65535, RMSBilinearError=0.005, RMSCubicError=0.001, Scale=0.003, URL='http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html', Vertical_Datum='WGS84'
|
|
1873
1833
|
#
|
|
1874
1834
|
# Timbuktu GeoidPGM('egm96-5.pgm').height(16.775833, -3.009444): 28.7065 vs 28.7067
|
|
1875
1835
|
# Timbuktu GeoidPGM('egm96-5.pgm').height(16.776, -3.009): 28.7064 vs 28.7067
|
|
1836
|
+
|
|
1837
|
+
# **) MIT License
|
|
1838
|
+
#
|
|
1839
|
+
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1840
|
+
#
|
|
1841
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1842
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
1843
|
+
# to deal in the Software without restriction, including without limitation
|
|
1844
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
1845
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
1846
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
1847
|
+
#
|
|
1848
|
+
# The above copyright notice and this permission notice shall be included
|
|
1849
|
+
# in all copies or substantial portions of the Software.
|
|
1850
|
+
#
|
|
1851
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
1852
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1853
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
1854
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
1855
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
1856
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
1857
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|