pygeodesy 24.8.4__py2.py3-none-any.whl → 24.9.9__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/METADATA +17 -16
- PyGeodesy-24.9.9.dist-info/RECORD +118 -0
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +23 -23
- pygeodesy/__main__.py +46 -47
- pygeodesy/auxilats/_CX_4.py +104 -181
- pygeodesy/auxilats/_CX_6.py +152 -277
- pygeodesy/auxilats/_CX_8.py +211 -438
- pygeodesy/auxilats/_CX_Rs.py +222 -0
- pygeodesy/auxilats/__init__.py +2 -2
- pygeodesy/auxilats/__main__.py +30 -38
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +28 -36
- pygeodesy/auxilats/auxily.py +30 -50
- pygeodesy/basics.py +18 -7
- pygeodesy/booleans.py +10 -11
- pygeodesy/cartesianBase.py +5 -5
- pygeodesy/constants.py +35 -34
- 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/elliptic.py +154 -88
- pygeodesy/epsg.py +3 -3
- pygeodesy/etm.py +71 -59
- pygeodesy/fmath.py +99 -90
- pygeodesy/fsums.py +201 -14
- pygeodesy/gars.py +9 -8
- pygeodesy/geodesici.py +6 -5
- pygeodesy/geodesicx/_C4_24.py +1 -3
- pygeodesy/geodesicx/_C4_27.py +1 -3
- pygeodesy/geodesicx/_C4_30.py +1 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +44 -46
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +5 -5
- pygeodesy/geodesicx/gxbases.py +32 -18
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +18 -11
- pygeodesy/geoids.py +293 -315
- pygeodesy/heights.py +150 -158
- pygeodesy/internals.py +70 -9
- pygeodesy/interns.py +4 -4
- pygeodesy/karney.py +83 -60
- pygeodesy/ktm.py +4 -4
- pygeodesy/latlonBase.py +13 -7
- pygeodesy/lazily.py +13 -8
- pygeodesy/ltp.py +5 -6
- pygeodesy/ltpTuples.py +7 -1
- pygeodesy/mgrs.py +47 -42
- pygeodesy/named.py +8 -4
- pygeodesy/namedTuples.py +14 -1
- pygeodesy/osgr.py +7 -7
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +7 -6
- pygeodesy/resections.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +42 -60
- 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 +207 -201
- pygeodesy/units.py +3 -3
- 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 +20 -22
- PyGeodesy-24.8.4.dist-info/RECORD +0 -117
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.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,7 +264,7 @@ 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
269
|
_H = self._heightOrthometric if H else None
|
|
291
270
|
_as, llis = _as_llis2(llis, Error=GeoidError)
|
|
@@ -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,12 @@ 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)
|
|
418
392
|
|
|
419
393
|
@property_ROver
|
|
420
394
|
def _heightOrthometric(self):
|
|
@@ -429,9 +403,9 @@ class _GeoidBase(_HeightsBase):
|
|
|
429
403
|
|
|
430
404
|
@Property_RO
|
|
431
405
|
def _highest(self):
|
|
432
|
-
'''(INTERNAL) Cache for
|
|
406
|
+
'''(INTERNAL) Cache for C{.highest}.
|
|
433
407
|
'''
|
|
434
|
-
return self._llh3minmax(True)
|
|
408
|
+
return self._LL3T(self._llh3minmax(True), name__=self.highest)
|
|
435
409
|
|
|
436
410
|
def highest(self, LatLon=None, **unused):
|
|
437
411
|
'''Return the location and largest height of this geoid.
|
|
@@ -451,15 +425,6 @@ class _GeoidBase(_HeightsBase):
|
|
|
451
425
|
'''
|
|
452
426
|
return self._yx_hits
|
|
453
427
|
|
|
454
|
-
@deprecated_method
|
|
455
|
-
def _interp2d(self, xs, ys, hs=(), k=0): # overwritten in .__init__ above
|
|
456
|
-
'''DEPRECATED on 23.01.06, use keyword argument C{B{kind}=1..5}.'''
|
|
457
|
-
# assert k in _interp2d_ks # and len(hs) == len(xs) == len(ys)
|
|
458
|
-
try:
|
|
459
|
-
return self.scipy_interpolate.interp2d(xs, ys, hs, kind=_interp2d_ks[k])
|
|
460
|
-
except AttributeError as x:
|
|
461
|
-
raise SciPyError(interp2d=MISSING, kind=k, cause=x)
|
|
462
|
-
|
|
463
428
|
@Property_RO
|
|
464
429
|
def kind(self):
|
|
465
430
|
'''Get the interpolator kind and order (C{int}).
|
|
@@ -488,7 +453,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
488
453
|
def _llh3LL(self, llh, LatLon):
|
|
489
454
|
return llh if LatLon is None else self._xnamed(LatLon(*llh))
|
|
490
455
|
|
|
491
|
-
def _llh3minmax(self, highest
|
|
456
|
+
def _llh3minmax(self, highest, *unused):
|
|
492
457
|
hs, np = self._hs_y_x, self.numpy
|
|
493
458
|
# <https://docs.SciPy.org/doc/numpy/reference/generated/
|
|
494
459
|
# numpy.argmin.html#numpy.argmin>
|
|
@@ -503,7 +468,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
503
468
|
|
|
504
469
|
@Property_RO
|
|
505
470
|
def _lowerleft(self):
|
|
506
|
-
'''(INTERNAL) Cache for
|
|
471
|
+
'''(INTERNAL) Cache for C{.lowerleft}.
|
|
507
472
|
'''
|
|
508
473
|
return self._llh3(self._lat_lo, self._lon_lo)
|
|
509
474
|
|
|
@@ -521,7 +486,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
521
486
|
|
|
522
487
|
@Property_RO
|
|
523
488
|
def _loweright(self):
|
|
524
|
-
'''(INTERNAL) Cache for
|
|
489
|
+
'''(INTERNAL) Cache for C{.loweright}.
|
|
525
490
|
'''
|
|
526
491
|
return self._llh3(self._lat_lo, self._lon_hi)
|
|
527
492
|
|
|
@@ -535,16 +500,15 @@ class _GeoidBase(_HeightsBase):
|
|
|
535
500
|
otherwise a B{C{LatLon}} instance with the lat-, longitude and
|
|
536
501
|
geoid height of the lower-right, SE grid corner.
|
|
537
502
|
'''
|
|
538
|
-
|
|
539
503
|
return self._llh3LL(self._loweright, LatLon)
|
|
540
504
|
|
|
541
505
|
lowerright = loweright # synonymous
|
|
542
506
|
|
|
543
507
|
@Property_RO
|
|
544
508
|
def _lowest(self):
|
|
545
|
-
'''(INTERNAL) Cache for
|
|
509
|
+
'''(INTERNAL) Cache for C{.lowest}.
|
|
546
510
|
'''
|
|
547
|
-
return self._llh3minmax(False)
|
|
511
|
+
return self._LL3T(self._llh3minmax(False), name__=self.lowest)
|
|
548
512
|
|
|
549
513
|
def lowest(self, LatLon=None, **unused):
|
|
550
514
|
'''Return the location and lowest height of this geoid.
|
|
@@ -570,7 +534,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
570
534
|
def name(self):
|
|
571
535
|
'''Get the name of this geoid (C{str}).
|
|
572
536
|
'''
|
|
573
|
-
return
|
|
537
|
+
return _HeightBase.name.fget(self) or self._geoid # recursion
|
|
574
538
|
|
|
575
539
|
@Property_RO
|
|
576
540
|
def nBytes(self):
|
|
@@ -591,7 +555,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
591
555
|
self._datum = _ellipsoidal_datum(datum, name=name)
|
|
592
556
|
self._kind = int(kind)
|
|
593
557
|
if name:
|
|
594
|
-
|
|
558
|
+
_HeightBase.name.fset(self, name) # rename
|
|
595
559
|
if smooth:
|
|
596
560
|
self._smooth = Int_(smooth=smooth, Error=GeoidError, low=0)
|
|
597
561
|
|
|
@@ -651,8 +615,8 @@ class _GeoidBase(_HeightsBase):
|
|
|
651
615
|
swne = crop
|
|
652
616
|
if len(swne) == 4:
|
|
653
617
|
s, w, n, e = map(float, swne)
|
|
654
|
-
if
|
|
655
|
-
|
|
618
|
+
if _N_90_0 <= s <= (n - _1_0) <= 89.0 and \
|
|
619
|
+
_N_180_0 <= w <= (e - _1_0) <= 179.0:
|
|
656
620
|
return s, w, n, e
|
|
657
621
|
except (IndexError, TypeError, ValueError):
|
|
658
622
|
pass
|
|
@@ -688,7 +652,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
688
652
|
|
|
689
653
|
@Property_RO
|
|
690
654
|
def _upperleft(self):
|
|
691
|
-
'''(INTERNAL) Cache for
|
|
655
|
+
'''(INTERNAL) Cache for C{.upperleft}.
|
|
692
656
|
'''
|
|
693
657
|
return self._llh3(self._lat_hi, self._lon_lo)
|
|
694
658
|
|
|
@@ -706,7 +670,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
706
670
|
|
|
707
671
|
@Property_RO
|
|
708
672
|
def _upperright(self):
|
|
709
|
-
'''(INTERNAL) Cache for
|
|
673
|
+
'''(INTERNAL) Cache for C{.upperright}.
|
|
710
674
|
'''
|
|
711
675
|
return self._llh3(self._lat_hi, self._lon_hi)
|
|
712
676
|
|
|
@@ -723,12 +687,6 @@ class _GeoidBase(_HeightsBase):
|
|
|
723
687
|
return self._llh3LL(self._upperright, LatLon)
|
|
724
688
|
|
|
725
689
|
|
|
726
|
-
class GeoidError(HeightError):
|
|
727
|
-
'''Geoid interpolator C{Geoid...} or interpolation issue.
|
|
728
|
-
'''
|
|
729
|
-
pass
|
|
730
|
-
|
|
731
|
-
|
|
732
690
|
class GeoidG2012B(_GeoidBase):
|
|
733
691
|
'''Geoid height interpolator for U{GEOID12B Model
|
|
734
692
|
<https://www.NGS.NOAA.gov/GEOID/GEOID12B/>} grids U{CONUS
|
|
@@ -740,10 +698,11 @@ class GeoidG2012B(_GeoidBase):
|
|
|
740
698
|
U{Puerto Rico and U.S. Virgin Islands
|
|
741
699
|
<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_PRVI.shtml>} and
|
|
742
700
|
U{American Samoa<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_AS.shtml>}
|
|
743
|
-
based on C{SciPy} U{RectBivariateSpline<https://docs.SciPy.org/doc/
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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.
|
|
747
706
|
|
|
748
707
|
Use any of the binary C{le} (little endian) or C{be} (big endian)
|
|
749
708
|
C{g2012b*.bin} grid files.
|
|
@@ -753,38 +712,34 @@ class GeoidG2012B(_GeoidBase):
|
|
|
753
712
|
'''New L{GeoidG2012B} interpolator.
|
|
754
713
|
|
|
755
714
|
@arg g2012b_bin: A C{GEOID12B} grid file name (C{.bin}).
|
|
756
|
-
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}
|
|
757
|
-
|
|
758
|
-
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
reference/generated/scipy.
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
@raise ImportError: Package C{numpy} or C{scipy} not found or not
|
|
775
|
-
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.
|
|
776
732
|
|
|
777
733
|
@raise LenError: Grid file B{C{g2012b_bin}} axis mismatch.
|
|
778
734
|
|
|
779
|
-
@raise SciPyError: A C{
|
|
735
|
+
@raise SciPyError: A C{scipy} issue.
|
|
780
736
|
|
|
781
|
-
@raise SciPyWarning: A C{
|
|
782
|
-
warning as exception.
|
|
737
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
783
738
|
|
|
784
739
|
@raise TypeError: Invalid B{C{datum}}.
|
|
785
740
|
|
|
786
|
-
@note: C{
|
|
787
|
-
|
|
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.
|
|
788
743
|
'''
|
|
789
744
|
crop, name = _xkwds_pop2(name_crop, crop=None)
|
|
790
745
|
if crop is not None:
|
|
@@ -927,6 +882,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
927
882
|
_T( 0, 2),
|
|
928
883
|
_T( 1, 2))
|
|
929
884
|
|
|
885
|
+
# _cropped = None
|
|
930
886
|
_endian = '>H' # struct.unpack 1 ushort (big endian, unsigned short)
|
|
931
887
|
_4endian = '>4H' # struct.unpack 4 ushorts
|
|
932
888
|
_Rendian = NN # struct.unpack a row of ushorts
|
|
@@ -944,9 +900,9 @@ class GeoidKarney(_GeoidBase):
|
|
|
944
900
|
_u2B = _calcsize(_endian) # pixelsize_ in bytes
|
|
945
901
|
_4u2B = _calcsize(_4endian) # 4 pixelsize_s in bytes
|
|
946
902
|
_Ru2B = 0 # row of pixelsize_s in bytes
|
|
947
|
-
_yxH = () # cache (y, x) indices
|
|
948
|
-
_yxHt = () # cached 4- or 10-tuple for _ev2H resp. _ev3H
|
|
949
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
|
|
950
906
|
|
|
951
907
|
def __init__(self, egm_pgm, crop=None, datum=None, # WGS84
|
|
952
908
|
kind=3, **name_smooth):
|
|
@@ -956,34 +912,31 @@ class GeoidKarney(_GeoidBase):
|
|
|
956
912
|
C++/doc/geoid.html#geoidinst>} file name (C{egm*.pgm}), see
|
|
957
913
|
note below.
|
|
958
914
|
@kwarg crop: Optional box to limit geoid locations, a 4-tuple (C{south,
|
|
959
|
-
west, north, east}), 2-tuple (C{(south, west), (north,
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
@kwarg kind: Interpolation order (C{int}), 2 for C{bilinear} or 3
|
|
966
|
-
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}.
|
|
967
921
|
@kwarg name_smooth: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED
|
|
968
922
|
keyword argument C{B{smooth}}, use C{B{smooth}=None} to ignore.
|
|
969
923
|
|
|
970
|
-
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid
|
|
971
|
-
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}}.
|
|
972
926
|
|
|
973
927
|
@raise TypeError: Invalid B{C{datum}}.
|
|
974
928
|
|
|
975
929
|
@see: Class L{GeoidPGM} and function L{egmGeoidHeights}.
|
|
976
930
|
|
|
977
|
-
@note: Geoid file B{C{egm_pgm}} remains open and must be closed
|
|
978
|
-
|
|
979
|
-
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.
|
|
980
933
|
'''
|
|
981
934
|
smooth, name = _xkwds_pop2(name_smooth, smooth=None)
|
|
982
935
|
if smooth is not None:
|
|
983
936
|
raise GeoidError(smooth=smooth, txt_not_=_supported_)
|
|
984
937
|
|
|
985
938
|
if kind in (2,):
|
|
986
|
-
self.
|
|
939
|
+
self._ev2d = self._ev2k # see ._ev_name
|
|
987
940
|
elif kind not in (3,):
|
|
988
941
|
raise GeoidError(kind=kind)
|
|
989
942
|
|
|
@@ -999,7 +952,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
999
952
|
# set earth (lat, lon) limits (s, w, n, e)
|
|
1000
953
|
self._lat_lo, self._lon_lo, \
|
|
1001
954
|
self._lat_hi, self._lon_hi = self._swne(crop if crop else p.crop4)
|
|
1002
|
-
self._cropped =
|
|
955
|
+
self._cropped = bool(crop)
|
|
1003
956
|
|
|
1004
957
|
def __call__(self, *llis, **wrap_H):
|
|
1005
958
|
'''Interpolate the geoid height for one or several locations.
|
|
@@ -1015,16 +968,15 @@ class GeoidKarney(_GeoidBase):
|
|
|
1015
968
|
(C{float}) or a list or tuple of interpolated geoid
|
|
1016
969
|
(or orthometric) heights (C{float}s).
|
|
1017
970
|
|
|
1018
|
-
@raise GeoidError: Insufficient number of B{C{llis}}, an
|
|
1019
|
-
|
|
1020
|
-
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.
|
|
1021
973
|
|
|
1022
|
-
@raise RangeError: An B{C{lli}} is outside this geoid's lat-
|
|
1023
|
-
|
|
974
|
+
@raise RangeError: An B{C{lli}} is outside this geoid's lat- or
|
|
975
|
+
longitude range.
|
|
1024
976
|
|
|
1025
|
-
@note: To obtain I{orthometric} heights, each B{C{llis}}
|
|
1026
|
-
|
|
1027
|
-
|
|
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.
|
|
1028
980
|
|
|
1029
981
|
@see: Function L{pygeodesy.heightOrthometric}.
|
|
1030
982
|
'''
|
|
@@ -1072,38 +1024,38 @@ class GeoidKarney(_GeoidBase):
|
|
|
1072
1024
|
y, x = int(floor(fy)), int(floor(fx))
|
|
1073
1025
|
fy -= y
|
|
1074
1026
|
fx -= x
|
|
1075
|
-
H = self.
|
|
1027
|
+
H = self._ev2d(fy, fx, y, x) # PYCHOK ._ev2k or ._ev3k
|
|
1076
1028
|
H *= self._pgm.Scale # H.fmul(self._pgm.Scale)
|
|
1077
1029
|
H += self._pgm.Offset # H.fadd(self._pgm.Offset)
|
|
1078
|
-
return H.fsum()
|
|
1030
|
+
return H.fsum() # float(H)
|
|
1079
1031
|
|
|
1080
|
-
def
|
|
1032
|
+
def _ev2k(self, fy, fx, *yx):
|
|
1081
1033
|
# compute the bilinear 4-tuple and interpolate raw H
|
|
1082
|
-
if self.
|
|
1083
|
-
t = self._yxHt
|
|
1034
|
+
if self._yx_i == yx:
|
|
1084
1035
|
self._yx_hits += 1
|
|
1085
1036
|
else:
|
|
1086
|
-
y, x = self.
|
|
1087
|
-
self.
|
|
1037
|
+
y, x = self._yx_i = yx
|
|
1038
|
+
self._yx_t = self._raws(y, x, GeoidKarney._BT)
|
|
1039
|
+
t = self._yx_t
|
|
1088
1040
|
v = _1_0, -fx, fx
|
|
1089
1041
|
H = Fdot(v, t[0], t[0], t[1]).fmul(_1_0 - fy) # c = a * (1 - fy)
|
|
1090
1042
|
H += Fdot(v, t[2], t[2], t[3]).fmul(fy) # c += b * fy
|
|
1091
1043
|
return H
|
|
1092
1044
|
|
|
1093
|
-
def
|
|
1045
|
+
def _ev3k(self, fy, fx, *yx):
|
|
1094
1046
|
# compute the cubic 10-tuple and interpolate raw H
|
|
1095
|
-
if self.
|
|
1096
|
-
t = self._yxHt
|
|
1047
|
+
if self._yx_i == yx:
|
|
1097
1048
|
self._yx_hits += 1
|
|
1098
1049
|
else:
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
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
|
|
1103
1054
|
# GeographicLib/Geoid.cpp Geoid::height(lat, lon) ...
|
|
1104
1055
|
# real h = t[0] + fx * (t[1] + fx * (t[3] + fx * t[6])) +
|
|
1105
1056
|
# fy * (t[2] + fx * (t[4] + fx * t[7]) +
|
|
1106
1057
|
# fy * (t[5] + fx * t[8] + fy * t[9]));
|
|
1058
|
+
t = self._yx_t
|
|
1107
1059
|
v = _1_0, fx, fy
|
|
1108
1060
|
H = Fdot(v, t[5], t[8], t[9])
|
|
1109
1061
|
H *= fy
|
|
@@ -1112,7 +1064,7 @@ class GeoidKarney(_GeoidBase):
|
|
|
1112
1064
|
H += Fhorner(fx, t[0], t[1], t[3], t[6])
|
|
1113
1065
|
return H
|
|
1114
1066
|
|
|
1115
|
-
|
|
1067
|
+
_ev2d = _ev3k # overriden for kind=2, see ._ev_name
|
|
1116
1068
|
|
|
1117
1069
|
def _g2ll2(self, lat, lon):
|
|
1118
1070
|
# convert grid (lat, lon) to earth (lat, lon), uncropped
|
|
@@ -1149,13 +1101,14 @@ class GeoidKarney(_GeoidBase):
|
|
|
1149
1101
|
@raise RangeError: A B{C{lat}} or B{C{lon}} is outside this
|
|
1150
1102
|
geoid's lat- or longitude range.
|
|
1151
1103
|
'''
|
|
1152
|
-
|
|
1104
|
+
lls = self._as_lls(lats, lons)
|
|
1105
|
+
return self(lls, **wrap) # __call__(ll) or __call__(lls)
|
|
1153
1106
|
|
|
1154
1107
|
@Property_RO
|
|
1155
1108
|
def _highest_ltd(self):
|
|
1156
|
-
'''(INTERNAL) Cache for
|
|
1109
|
+
'''(INTERNAL) Cache for C{.highest}.
|
|
1157
1110
|
'''
|
|
1158
|
-
return self._llh3minmax(True, -12, -4)
|
|
1111
|
+
return self._LL3T(self._llh3minmax(True, -12, -4), name__=self.highest)
|
|
1159
1112
|
|
|
1160
1113
|
def highest(self, LatLon=None, full=False): # PYCHOK full
|
|
1161
1114
|
'''Return the location and largest height of this geoid.
|
|
@@ -1185,30 +1138,34 @@ class GeoidKarney(_GeoidBase):
|
|
|
1185
1138
|
lon += _360_0
|
|
1186
1139
|
return lat, lon
|
|
1187
1140
|
|
|
1188
|
-
def _llh3minmax(self, highest
|
|
1141
|
+
def _llh3minmax(self, highest, *lat2):
|
|
1189
1142
|
# find highest or lowest, takes 10+ secs for egm2008-1.pgm geoid
|
|
1190
1143
|
# (Python 2.7.16, macOS 10.13.6 High Sierra, iMac 3 GHz Core i3)
|
|
1191
|
-
y = x = 0
|
|
1192
|
-
h = self._raw(y, x)
|
|
1193
1144
|
if highest:
|
|
1194
|
-
|
|
1145
|
+
def _mt(r, h):
|
|
1195
1146
|
m = max(r)
|
|
1196
|
-
|
|
1197
|
-
|
|
1147
|
+
return m, (m > h)
|
|
1148
|
+
|
|
1198
1149
|
else: # lowest
|
|
1199
|
-
|
|
1150
|
+
def _mt(r, h): # PYCHOK redef
|
|
1200
1151
|
m = min(r)
|
|
1201
|
-
|
|
1202
|
-
|
|
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)
|
|
1203
1160
|
h *= self._pgm.Scale
|
|
1204
1161
|
h += self._pgm.Offset
|
|
1205
1162
|
return self._g2ll2(*self._gyx2g2(y, x)) + (h,)
|
|
1206
1163
|
|
|
1207
1164
|
@Property_RO
|
|
1208
1165
|
def _lowest_ltd(self):
|
|
1209
|
-
'''(INTERNAL) Cache for
|
|
1166
|
+
'''(INTERNAL) Cache for C{.lowest}.
|
|
1210
1167
|
'''
|
|
1211
|
-
return self._llh3minmax(False, 0, 8)
|
|
1168
|
+
return self._LL3T(self._llh3minmax(False, 0, 8), name__=self.lowest)
|
|
1212
1169
|
|
|
1213
1170
|
def lowest(self, LatLon=None, full=False): # PYCHOK full
|
|
1214
1171
|
'''Return the location and lowest height of this geoid.
|
|
@@ -1273,25 +1230,21 @@ class GeoidKarney(_GeoidBase):
|
|
|
1273
1230
|
|
|
1274
1231
|
class GeoidPGM(_GeoidBase):
|
|
1275
1232
|
'''Geoid height interpolator for I{Karney}'s U{GeographicLib Earth
|
|
1276
|
-
Gravitational Model (EGM)<https://GeographicLib.SourceForge.io/C++/doc/
|
|
1277
|
-
geoid
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
generated/scipy.interpolate.
|
|
1281
|
-
U{interp2d<https://docs.SciPy.org/doc/scipy/reference/generated/
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
Use any of the U{egm84-, egm96- or egm2008-*.pgm
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
is
|
|
1288
|
-
doc/
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
2-byte C{int} to 8-byte C{dtype float64}. Therefore, internal memory
|
|
1292
|
-
usage is 4x the U{egm*.pgm<https://GeographicLib.SourceForge.io/C++/doc/
|
|
1293
|
-
geoid.html#geoidinst>} file size and may exceed the available memory,
|
|
1294
|
-
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}.
|
|
1295
1248
|
'''
|
|
1296
1249
|
_cropped = False
|
|
1297
1250
|
_endian = '>u2'
|
|
@@ -1304,48 +1257,44 @@ class GeoidPGM(_GeoidBase):
|
|
|
1304
1257
|
C++/doc/geoid.html#geoidinst>} file name (C{egm*.pgm}).
|
|
1305
1258
|
@kwarg crop: Optional box to crop B{C{egm_pgm}}, a 4-tuple (C{south, west,
|
|
1306
1259
|
north, east}) or 2-tuple (C{(south, west), (north, east)}),
|
|
1307
|
-
in C{degrees90} lat- and C{degrees180} longitudes or a
|
|
1308
|
-
|
|
1309
|
-
@kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}
|
|
1310
|
-
|
|
1311
|
-
@kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
reference/generated/scipy.
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
scipy.interpolate.RectBivariateSpline.html>}
|
|
1320
|
-
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}).
|
|
1321
1272
|
@kwarg name: Optional geoid C{B{name}=NN} (C{str}).
|
|
1322
1273
|
|
|
1323
|
-
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}},
|
|
1324
|
-
|
|
1274
|
+
@raise GeoidError: EGM dataset B{C{egm_pgm}} issue or invalid B{C{crop}}, B{C{kind}}
|
|
1275
|
+
or B{C{smooth}}.
|
|
1325
1276
|
|
|
1326
1277
|
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
|
|
1327
1278
|
|
|
1328
1279
|
@raise LenError: EGM dataset B{C{egm_pgm}} axis mismatch.
|
|
1329
1280
|
|
|
1330
|
-
@raise SciPyError: A C{
|
|
1281
|
+
@raise SciPyError: A C{scipy} issue.
|
|
1331
1282
|
|
|
1332
|
-
@raise SciPyWarning: A C{
|
|
1333
|
-
warning as exception.
|
|
1283
|
+
@raise SciPyWarning: A C{scipy} warning as exception.
|
|
1334
1284
|
|
|
1335
1285
|
@raise TypeError: Invalid B{C{datum}} or unexpected argument.
|
|
1336
1286
|
|
|
1337
|
-
@note: C{
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
@note: The U{GeographicLib egm*.pgm<https://GeographicLib.SourceForge.io/
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
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>}
|
|
1349
1298
|
(CONUS), less than 3% of the entire C{egm2008-1.pgm} dataset.
|
|
1350
1299
|
|
|
1351
1300
|
@see: Class L{GeoidKarney} and function L{egmGeoidHeights}.
|
|
@@ -1715,9 +1664,10 @@ def egmGeoidHeights(GeoidHeights_dat):
|
|
|
1715
1664
|
|
|
1716
1665
|
__all__ += _ALL_DOCS(_GeoidBase)
|
|
1717
1666
|
|
|
1718
|
-
if __name__ == '__main__':
|
|
1667
|
+
if __name__ == '__main__': # MCCABE 14
|
|
1719
1668
|
|
|
1720
|
-
from pygeodesy.internals import printf, _sys
|
|
1669
|
+
from pygeodesy.internals import printf, _secs2str, _sys, _versions
|
|
1670
|
+
from time import time
|
|
1721
1671
|
|
|
1722
1672
|
_crop = ()
|
|
1723
1673
|
_GeoidEGM = GeoidKarney
|
|
@@ -1741,7 +1691,10 @@ if __name__ == '__main__':
|
|
|
1741
1691
|
|
|
1742
1692
|
elif geoid[-4:].lower() in ('.pgm',):
|
|
1743
1693
|
g = _GeoidEGM(geoid, crop=_crop, kind=_kind)
|
|
1744
|
-
|
|
1694
|
+
t = time()
|
|
1695
|
+
_ = g.highest()
|
|
1696
|
+
t = _secs2str(time() - t)
|
|
1697
|
+
printf('%s: %s (%s)', g.toStr(), t, _versions(), nl=1, nt=1)
|
|
1745
1698
|
printf(repr(g.pgm), nt=1)
|
|
1746
1699
|
# <https://GeographicLib.SourceForge.io/cgi-bin/GeoidEval>:
|
|
1747
1700
|
# The height of the EGM96 geoid at Timbuktu
|
|
@@ -1771,27 +1724,6 @@ if __name__ == '__main__':
|
|
|
1771
1724
|
_I = int # PYCHOK unused _I
|
|
1772
1725
|
del _intCs # trash ints cache
|
|
1773
1726
|
|
|
1774
|
-
# **) MIT License
|
|
1775
|
-
#
|
|
1776
|
-
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1777
|
-
#
|
|
1778
|
-
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1779
|
-
# copy of this software and associated documentation files (the "Software"),
|
|
1780
|
-
# to deal in the Software without restriction, including without limitation
|
|
1781
|
-
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
1782
|
-
# and/or sell copies of the Software, and to permit persons to whom the
|
|
1783
|
-
# Software is furnished to do so, subject to the following conditions:
|
|
1784
|
-
#
|
|
1785
|
-
# The above copyright notice and this permission notice shall be included
|
|
1786
|
-
# in all copies or substantial portions of the Software.
|
|
1787
|
-
#
|
|
1788
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
1789
|
-
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1790
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
1791
|
-
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
1792
|
-
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
1793
|
-
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
1794
|
-
# OTHER DEALINGS IN THE SOFTWARE.
|
|
1795
1727
|
|
|
1796
1728
|
# <https://GeographicLib.SourceForge.io/cgi-bin/GeoidEval>
|
|
1797
1729
|
# _lowerleft = -90, -179, -30.1500 # egm2008-1.pgm
|
|
@@ -1807,23 +1739,47 @@ del _intCs # trash ints cache
|
|
|
1807
1739
|
# _upperright = 90, 180, 13.0980 # egm84-15.pgm
|
|
1808
1740
|
|
|
1809
1741
|
|
|
1810
|
-
# % python3 -m pygeodesy.geoids
|
|
1742
|
+
# % python3.12 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1743
|
+
#
|
|
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)
|
|
1745
|
+
#
|
|
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'
|
|
1747
|
+
#
|
|
1748
|
+
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1749
|
+
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1750
|
+
#
|
|
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)
|
|
1752
|
+
#
|
|
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'
|
|
1754
|
+
#
|
|
1755
|
+
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1756
|
+
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1757
|
+
#
|
|
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)
|
|
1759
|
+
#
|
|
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'
|
|
1761
|
+
#
|
|
1762
|
+
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.775833, -3.009444): 28.7068 vs 28.7067
|
|
1763
|
+
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
# % python3.8 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1811
1767
|
#
|
|
1812
|
-
# 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)
|
|
1813
1769
|
#
|
|
1814
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'
|
|
1815
1771
|
#
|
|
1816
1772
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1817
1773
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1818
1774
|
#
|
|
1819
|
-
# 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)
|
|
1820
1776
|
#
|
|
1821
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'
|
|
1822
1778
|
#
|
|
1823
1779
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1824
1780
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1825
1781
|
#
|
|
1826
|
-
# 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)
|
|
1827
1783
|
#
|
|
1828
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'
|
|
1829
1785
|
#
|
|
@@ -1831,23 +1787,23 @@ del _intCs # trash ints cache
|
|
|
1831
1787
|
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1832
1788
|
|
|
1833
1789
|
|
|
1834
|
-
# %
|
|
1790
|
+
# % python2 -m pygeodesy.geoids -Karney ../testGeoids/egm*.pgm
|
|
1835
1791
|
#
|
|
1836
|
-
# 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)
|
|
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)
|
|
1837
1793
|
#
|
|
1838
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'
|
|
1839
1795
|
#
|
|
1840
1796
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1841
1797
|
# Timbuktu GeoidKarney('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1842
1798
|
#
|
|
1843
|
-
# 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)
|
|
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)
|
|
1844
1800
|
#
|
|
1845
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'
|
|
1846
1802
|
#
|
|
1847
1803
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.775833, -3.009444): 31.2983 vs 31.2979
|
|
1848
1804
|
# Timbuktu GeoidKarney('egm84-15.pgm').height(16.776, -3.009): 31.2979 vs 31.2979
|
|
1849
1805
|
#
|
|
1850
|
-
# 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)
|
|
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)
|
|
1851
1807
|
#
|
|
1852
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'
|
|
1853
1809
|
#
|
|
@@ -1855,25 +1811,47 @@ del _intCs # trash ints cache
|
|
|
1855
1811
|
# Timbuktu GeoidKarney('egm96-5.pgm').height(16.776, -3.009): 28.7067 vs 28.7067
|
|
1856
1812
|
|
|
1857
1813
|
|
|
1858
|
-
# %
|
|
1814
|
+
# % python3.12 -m pygeodesy.geoids -PGM ../testGeoids/egm*.pgm
|
|
1859
1815
|
#
|
|
1860
|
-
# 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)
|
|
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)
|
|
1861
1817
|
#
|
|
1862
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'
|
|
1863
1819
|
#
|
|
1864
1820
|
# Timbuktu GeoidPGM('egm2008-1.pgm').height(16.775833, -3.009444): 28.7881 vs 28.7880
|
|
1865
1821
|
# Timbuktu GeoidPGM('egm2008-1.pgm').height(16.776, -3.009): 28.7880 vs 28.7880
|
|
1866
1822
|
#
|
|
1867
|
-
# 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)
|
|
1868
1824
|
#
|
|
1869
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'
|
|
1870
1826
|
#
|
|
1871
1827
|
# Timbuktu GeoidPGM('egm84-15.pgm').height(16.775833, -3.009444): 31.2979 vs 31.2979
|
|
1872
1828
|
# Timbuktu GeoidPGM('egm84-15.pgm').height(16.776, -3.009): 31.2975 vs 31.2979
|
|
1873
1829
|
#
|
|
1874
|
-
# 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)
|
|
1875
1831
|
#
|
|
1876
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'
|
|
1877
1833
|
#
|
|
1878
1834
|
# Timbuktu GeoidPGM('egm96-5.pgm').height(16.775833, -3.009444): 28.7065 vs 28.7067
|
|
1879
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.
|