Coverage for pygeodesy/heights.py : 91%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*-
L{HeightIDWeuclidean}, L{HeightIDWhaversine}, L{HeightIDWkarney}, L{HeightIDWvincentys}, L{HeightLinear}, L{HeightLSQBiSpline} and L{HeightSmoothBiSpline} to interpolate the height of C{LatLon} locations or separate lat-/longitudes from a set of C{LatLon} points with known heights.
Except for L{HeightIDWequirectangular}, L{HeightIDWeuclidean}, L{HeightIDWhaversine} and L{HeightIDWvincentys}, the height interpolators in this module require the packages U{numpy <https://PyPI.org/project/numpy>} and U{scipy<https://SciPy.org>} or U{geographiclib<https://PyPI.org/project/geographiclib>} to be installed.
Typical usage is as follows. First create an interpolator from a given set of C{LatLon} points with known heights, called C{knots}.
C{hinterpolator = HeightXyz(knots, **options)}
Get the interpolated height of other C{LatLon} location(s) with
C{h = hinterpolator(ll)}
or
C{h0, h1, h2, ... = hinterpolator(ll0, ll1, ll2, ...)}
or
C{hs = hinterpolator(lls)} # C{list, tuple, generator, ...}
For separate lat-/longitudes invoke the C{.height} method
C{h = hinterpolator.height(lat, lon)}
or
C{h0, h1, h2, ... = hinterpolator.height(lats, lons)} # C{list, ...}
The C{knots} do not need to be ordered for any of the height interpolators.
Errors from C{scipy} as raised as L{SciPyError}s. Warnings issued by C{scipy} can be thrown as L{SciPyWarning} exceptions, provided Python C{warnings} are filtered accordingly, see L{SciPyWarning}.
@see: U{SciPy<https://docs.SciPy.org/doc/scipy/reference/interpolate.html>}. '''
radiansPI, radiansPI2, unroll180, unrollPI
'''Height interpolator C{Height...} or interpolation issue. '''
'''Error raised for C{SciPy} errors. '''
'''Exception thrown for C{SciPy} warnings.
To raise C{SciPy} warnings as L{SciPyWarning} exceptions, Python C{warnings} must be filtered as U{warnings.filterwarnings('error') <https://docs.Python.org/3/library/warnings.html#the-warnings-filter>} I{prior to} C{import scipy} or by setting environment variable U{PYTHONWARNINGS<https://docs.Python.org/3/using/cmdline.html #envvar-PYTHONWARNINGS>} or with C{python} command line option U{-W<https://docs.Python.org/3/using/cmdline.html#cmdoption-w>} as C{error}. '''
# return tuple of floats, not numpy.float64s
# dtermine return type and convert lli C{LatLon}s to list raise AssertionError('type(%s): %r' % ('*llis', llis))
else: # of 0, 2 or more llis
raise Error('insufficient %s: %s, need %s' % ('llis', n, m))
# return single float, not numpy.float64 raise AssertionError('len[%r] = %s == 1' % (ais, len(ais)))
# return tuple of floats, not numpy.float64s
# convert lli C{LatLon}s to tuples or C{NumPy} arrays of # C{SciPy} sphericals and determine the return type
# clip, order and remove duplicates
t = ' '.join(str(x).strip().split() + map(str, extras)) if isinstance(x, (RuntimeWarning, UserWarning)): return SciPyWarning(t) else: return SciPyError(t) # PYCHOK not really
# map (lat, lon, h) to (x, y, h) in radians, offset as # x: 0 <= lon <= PI2, y: 0 <= lat <= PI if off is True # else x: -PI <= lon <= PI, y: -PI_2 <= lat <= PI_2 else: # undo offset (max(0.0, radiansPI( ll.lat + 90.0)) - yf), ll.height raise HeightError('%s: %r' % (x, ll))
# convert knot C{LatLon}s to tuples or C{NumPy} arrays and C{SciPy} sphericals raise HeightError('insufficient %s: %s, need %s' % ('knots', n, m))
'''(INTERNAL) Interpolator base class. '''
'''(INTERNAL) I{Must be overloaded}. ''' self._notOverloaded('__call__', *args)
'''(INTERNAL) I{Must be overloaded}. ''' self._notOverloaded(self._ev.__name__, *args)
except Exception as x: raise _SciPyIssue(x)
else: raise Error('non-matching %s: %s vs %s' % ('len', n, m))
'''(INTERNAL) Import C{numpy} and C{scipy}. ''' if throwarnings: # raise SciPyWarnings, but ... # ... not if scipy has been imported already import sys if 'scipy' not in sys.modules: import warnings warnings.filterwarnings('error')
'''Height interpolator based on C{SciPy} U{interp2d<https://docs.SciPy.org/ doc/scipy/reference/generated/scipy.interpolate.interp2d.html>} C{kind='cubic'}. '''
'''New L{HeightCubic} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}.
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
@raise SciPyError: A C{scipy.interpolate.interp2d} issue.
@raise SciPyWarning: A C{scipy.interpolate.interp2d} warning as exception. '''
except Exception as x: raise _SciPyIssue(x)
self.name = name
'''Interpolate the height for one or several locations.
@param llis: The location or locations (C{LatLon}, ... or C{LatLon}s).
@return: A single interpolated height (C{float}) or a list or tuple of interpolated heights (C{float}s).
@raise HeightError: Insufficient number of B{C{llis}} or invalid B{C{lli}}.
@raise SciPyError: A C{scipy.interpolate.interp2d} issue.
@raise SciPyWarning: A C{scipy.interpolate.interp2d} warning as exception. '''
# to make SciPy .interp2d signature(x, y), single (x, y) # match SciPy .ev signature(ys, xs), flipped multiples
'''Interpolate the height for one or several lat-/longitudes.
@param lats: Latitude or latitudes (C{degrees} or C{degrees}s). @param lons: Longitude or longitudes (C{degrees} or C{degrees}s).
@return: A single interpolated height (C{float}) or a list of interpolated heights (C{float}s).
@raise HeightError: Insufficient or non-matching number of B{C{lats}} and B{C{lons}}.
@raise SciPyError: A C{scipy.interpolate.interp2d} issue.
@raise SciPyWarning: A C{scipy.interpolate.interp2d} warning as exception. '''
'''Height interpolator based on C{SciPy} U{interp2d<https://docs.SciPy.org/ doc/scipy/reference/generated/scipy.interpolate.interp2d.html>} C{kind='linear}. '''
'''New L{HeightLinear} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}.
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
@raise SciPyError: A C{scipy.interpolate.interp2d} issue.
@raise SciPyWarning: A C{scipy.interpolate.interp2d} warning as exception. '''
'''(INTERNAL) Base class for U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) height interpolators. '''
'''New L{_HeightIDW} interpolator. ''' self.name = name
'''Interpolate the height for one or several locations.
@param llis: The location or locations (C{LatLon}, ... or C{LatLon}s).
@return: A single interpolated height (C{float}) or a list or tuple of interpolated heights (C{float}s).
@raise HeightError: Insufficient number of B{C{llis}}, invalid B{C{lli}} or an L{fidw} issue. '''
'''Must be overloaded. ''' raise NotImplementedError('method: %s' % ('_distances',))
# interpolate height at (x, y) radians or degrees except ValueError as x: raise HeightError(str(x))
def beta(self): '''Get the inverse distance power (C{int}). ''' return self._beta
def beta(self, beta): '''Set the inverse distance power.
@param beta: New inverse distance power (C{int} 1, 2, or 3).
@raise HeightError: Invalid B{C{beta}}. ''' raise ValueError except (TypeError, ValueError): raise HeightError('%s invalid: %r' % ('beta', beta))
'''Interpolate the height for one or several lat-/longitudes.
@param lats: Latitude or latitudes (C{degrees} or C{degrees}s). @param lons: Longitude or longitudes (C{degrees} or C{degrees}s).
@return: A single interpolated height (C{float}) or a list of interpolated heights (C{float}s).
@raise HeightError: Insufficient or non-matching number of B{C{lats}} and B{C{lons}} or an L{fidw} issue. '''
'''Height interpolator using U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and the C{equirectangular} distance (in radians squared) like function L{equirectangular_}.
@see: L{HeightIDWeuclidean}, L{HeightIDWhaversine}, L{HeightIDWvincentys}, U{Inverse distance weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>}, U{IDW<https://www.Geo.FU-Berlin.De/en/v/soga/Geodata-analysis/ geostatistics/Inverse-Distance-Weighting/index.html>} and U{SHEPARD_INTERP_2D<https://People.SC.FSU.edu/~jburkardt/c_src/ shepard_interp_2d/shepard_interp_2d.html>}. '''
'''New L{HeightIDWequirectangular} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine of the mean latitude (C{bool}). @keyword wrap: Wrap and L{unroll180} longitudes (C{bool}). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}. '''
'''Height interpolator using U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and the C{Euclidean} distance from function L{euclidean_}.
@see: L{HeightIDWequirectangular}, L{HeightIDWhaversine}, L{HeightIDWkarney}, L{HeightIDWvincentys}, U{Inverse distance weighting<https://WikiPedia.org/wiki/Inverse_distance_weighting>}, U{IDW<https://www.Geo.FU-Berlin.De/en/v/soga/Geodata-analysis/ geostatistics/Inverse-Distance-Weighting/index.html>} and U{SHEPARD_INTERP_2D<https://People.SC.FSU.edu/~jburkardt/c_src/ shepard_interp_2d/shepard_interp_2d.html>}. '''
'''New L{HeightIDWeuclidean} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword adjust: Adjust the longitudinal delta by the cosine of the mean latitude for B{C{adjust}}=C{True}. @keyword beta: Inverse distance power (C{int} 1, 2, or 3). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}, B{C{adjust}} or B{C{beta}}. ''' raise HeightError('%s=%r invalid' % ('adjust', adjust))
'''Height interpolator using U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and the I{angular} C{Haversine} distance from function L{haversine_}.
@note: See note under L{HeightIDWvincentys}.
@see: L{HeightIDWequirectangular}, L{HeightIDWeuclidean}, L{HeightIDWkarney}, L{HeightIDWvincentys}, U{Inverse distance weighting<https://WikiPedia.org/wiki/Inverse_distance_weighting>}, U{IDW<https://www.Geo.FU-Berlin.De/en/v/soga/Geodata-analysis/ geostatistics/Inverse-Distance-Weighting/index.html>} and U{SHEPARD_INTERP_2D<https://People.SC.FSU.edu/~jburkardt/c_src/ shepard_interp_2d/shepard_interp_2d.html>}. '''
'''New L{HeightIDWhaversine} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword beta: Inverse distance power (C{int} 1, 2, or 3). @keyword wrap: Wrap and L{unroll180} longitudes (C{bool}). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}} or B{C{beta}}. '''
'''Height interpolator using U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and the I{angular} distance from I{Charles F. F. Karney's} U{GeographicLib<https://PyPI.org/project/geographiclib>} U{Geodesic <https://geographiclib.sourceforge.io/1.49/python/code.html>} Inverse method.
@see: L{HeightIDWequirectangular}, L{HeightIDWeuclidean}, L{HeightIDWhaversine}, L{HeightIDWvincentys}, U{Inverse distance weighting<https://WikiPedia.org/wiki/Inverse_distance_weighting>}, U{IDW<https://www.Geo.FU-Berlin.De/en/v/soga/Geodata-analysis/ geostatistics/Inverse-Distance-Weighting/index.html>} and U{SHEPARD_INTERP_2D<https://People.SC.FSU.edu/~jburkardt/c_src/ shepard_interp_2d/shepard_interp_2d.html>}. '''
'''New L{HeightIDWhaversine} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword datum: Optional datum (L{Datum} to use, overriding the default C{B{knots}[0].datum} @keyword beta: Inverse distance power (C{int} 1, 2, or 3). @keyword wrap: Wrap and L{unroll180} longitudes (C{bool}). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}, B{C{datum}} or B{C{beta}}.
@raise ImportError: Package U{GeographicLib <https://PyPI.org/project/geographiclib>} missing.
@raise TypeError: Invalid B{C{datum}}. ''' raise HeightError('insufficient %s: %s, need %s' % ('knots', n, self._kmin)) raise TypeError except (AttributeError, TypeError): raise _IsNotError('valid', datum=self.datum or datum)
self.name = name
# see .ellipsoidalKarney.LatLon._inverse # XXX g.DISTANCE needed for 's12', distance in meters?
def _hs(self):
'''Interpolate the height for one or several locations.
@param llis: The location or locations (C{LatLon}, ... or C{LatLon}s).
@return: A single interpolated height (C{float}) or a list or tuple of interpolated heights (C{float}s).
@raise HeightError: Insufficient number of B{C{llis}}, invalid B{C{lli}} or an L{fidw} issue. ''' raise HeightError('%s: %r' % (x, ll))
def datum(self): '''Get the datum of this interpolator (L{Datum}). '''
'''Height interpolator using U{Inverse Distance Weighting <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and the I{angular} C{Vincenty} distance from function L{vincentys_}.
@note: See note under L{vincentys_}.
@see: L{HeightIDWequirectangular}, L{HeightIDWeuclidean}, L{HeightIDWhaversine}, L{HeightIDWkarney}, U{Inverse distance weighting<https://WikiPedia.org/wiki/Inverse_distance_weighting>}, U{IDW<https://www.Geo.FU-Berlin.De/en/v/soga/Geodata-analysis/ geostatistics/Inverse-Distance-Weighting/index.html>} and U{SHEPARD_INTERP_2D<https://People.SC.FSU.edu/~jburkardt/c_src/ shepard_interp_2d/shepard_interp_2d.html>}. '''
'''New L{HeightIDWvincentys} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword beta: Inverse distance power (C{int} 1, 2, or 3). @keyword wrap: Wrap and L{unroll180} longitudes (C{bool}). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}} or B{C{beta}}. '''
'''Height interpolator using C{SciPy} U{LSQSphereBivariateSpline <https://docs.SciPy.org/doc/scipy/reference/generated/scipy. interpolate.LSQSphereBivariateSpline.html>}. '''
'''New L{HeightLSQBiSpline} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword weight: Optional weight or weights for each B{C{knot}} (C{scalar} or C{scalar}s). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or B{C{weight}}s or invalid B{C{knot}} or B{C{weight}}.
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
@raise SciPyError: A C{LSQSphereBivariateSpline} issue.
@raise SciPyWarning: A C{LSQSphereBivariateSpline} warning as exception. '''
elif isscalar(weight): w = float(weight) if w <= 0: raise HeightError('%s invalid: %.6f' % ('weight', w)) else: n, w = len2(weight) if n != m: raise HeightError('%s invalid: %s, not %s' % ( 'number of weights', n, m)) w = np.array(map(float, w)) for i in range(m): if w[i] <= 0: raise HeightError('%s[%s] invalid: %.6f' % ( 'weight', i, w[i])) ts, ps, eps=EPS, w=w).ev except Exception as x: raise _SciPyIssue(x)
self.name = name
'''Interpolate the height for one or several locations.
@param llis: The location or locations (C{LatLon}, ... or C{LatLon}s).
@return: A single interpolated height (C{float}) or a list or tuple of interpolated heights (C{float}s).
@raise HeightError: Insufficient number of B{C{llis}} or invalid B{C{lli}}.
@raise SciPyError: A C{LSQSphereBivariateSpline} issue.
@raise SciPyWarning: A C{LSQSphereBivariateSpline} warning as exception. '''
'''Interpolate the height for one or several lat-/longitudes.
@param lats: Latitude or latitudes (C{degrees} or C{degrees}s). @param lons: Longitude or longitudes (C{degrees} or C{degrees}s).
@return: A single interpolated height (C{float}) or a list of interpolated heights (C{float}s).
@raise HeightError: Insufficient or non-matching number of B{C{lats}} and B{C{lons}}.
@raise SciPyError: A C{LSQSphereBivariateSpline} issue.
@raise SciPyWarning: A C{LSQSphereBivariateSpline} warning as exception. '''
'''Height interpolator using C{SciPy} U{SmoothSphereBivariateSpline <https://docs.SciPy.org/doc/scipy/reference/generated/scipy. interpolate.SmoothSphereBivariateSpline.html>}. '''
'''New L{HeightSmoothBiSpline} interpolator.
@param knots: The points with known height (C{LatLon}s). @keyword s: The spline smoothing factor (C{4}). @keyword name: Optional height interpolator name (C{str}).
@raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}} or B{C{s}}.
@raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
@raise SciPyError: A C{SmoothSphereBivariateSpline} issue.
@raise SciPyWarning: A C{SmoothSphereBivariateSpline} warning as exception. '''
raise HeightError('%s too small: %s' % ('smoothing', s))
eps=EPS, s=s).ev except Exception as x: raise _SciPyIssue(x)
self.name = name
'''Interpolate the height for one or several locations.
@param llis: The location or locations (C{LatLon}, ... or C{LatLon}s).
@return: A single interpolated height (C{float}) or a list or tuple of interpolated heights (C{float}s).
@raise HeightError: Insufficient number of B{C{llis}} or invalid B{C{lli}}.
@raise SciPyError: A C{SmoothSphereBivariateSpline} issue.
@raise SciPyWarning: A C{SmoothSphereBivariateSpline} warning as exception. '''
'''Interpolate the height for one or several lat-/longitudes.
@param lats: Latitude or latitudes (C{degrees} or C{degrees}s). @param lons: Longitude or longitudes (C{degrees} or C{degrees}s).
@return: A single interpolated height (C{float}) or a list of interpolated heights (C{float}s).
@raise HeightError: Insufficient or non-matching number of B{C{lats}} and B{C{lons}}.
@raise SciPyError: A C{SmoothSphereBivariateSpline} issue.
@raise SciPyWarning: A C{SmoothSphereBivariateSpline} warning as exception. '''
# **) MIT License # # Copyright (C) 2016-2020 -- mrJean1 at Gmail -- All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. |