def frechet_(points1, points2, distance=None, units=''): '''Compute the I{discrete} U{Fréchet<https://WikiPedia.org/wiki/Frechet_distance>} distance between two paths given as sets of points. @param points1: First set of points (C{LatLon}[], C{Numpy2LatLon}[], C{Tuple2LatLon}[] or C{other}[]). @param points2: Second set of points (C{LatLon}[], C{Numpy2LatLon}[], C{Tuple2LatLon}[] or C{other}[]). @keyword distance: Callable returning the distance between a B{C{points1}} and a B{C{points2}} point (signature C{(point1, point2)}). @keyword units: Optional, name of the distance units (C{str}). @return: A L{Frechet6Tuple}C{(fd, fi1, fi2, r, n, units)} where C{fi1} and C{fi2} are type C{int} indices into B{C{points1}} respectively B{C{points2}}. @raise FrechetError: Insufficient number of B{C{points1}} or B{C{points2}}. @raise RecursionError: Recursion depth exceeded, see U{sys.getrecursionlimit() <https://docs.Python.org/3/library/sys.html#sys.getrecursionlimit>}. @raise TypeError: If B{C{distance}} is not a callable. @note: Keyword C{fraction}, intermediate B{C{points1}} and B{C{points2}} and I{fractional} indices are I{not} supported in this L{frechet_} function. ''' if not callable(distance): raise _IsNotError(callable.__name__, distance=distance) n1, ps1 = _points2(points1, closed=False, Error=FrechetError) n2, ps2 = _points2(points2, closed=False, Error=FrechetError) def dF(i1, i2): return distance(ps1[i1], ps2[i2]) return _frechet_(n1, 1, n2, 1, dF, units)
def to2ll(self, datum=None): '''Convert this WM coordinate to a geodetic lat- and longitude. @keyword datum: Optional datum (C{Datum}). @return: A L{LatLon2Tuple}C{(lat, lon)}. @raise TypeError: Non-ellipsoidal B{C{datum}}. ''' r = self.radius x = self._x / r y = 2 * atan(exp(self._y / r)) - PI_2 if datum: E = datum.ellipsoid if not E.isEllipsoidal: raise _IsNotError('ellipsoidal', datum=datum) # <https://Earth-Info.NGA.mil/GandG/wgs84/web_mercator/ # %28U%29%20NGA_SIG_0011_1.0.0_WEBMERC.pdf> y = y / r if E.e: y -= E.e * atanh(E.e * tanh(y)) y *= E.a x *= E.a / r return self._xnamed(LatLon2Tuple(degrees90(y), degrees180(x)))
def __init__(self, knots, datum=None, beta=2, wrap=False, name=''): '''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}}. ''' n, self._lls = len2(knots) if n < self._kmin: raise HeightError('insufficient %s: %s, need %s' % ('knots', n, self._kmin)) try: self._datum = self._lls[0].datum if datum is None else datum if not isinstance(self.datum, Datum): raise TypeError except (AttributeError, TypeError): raise _IsNotError('valid', datum=self.datum or datum) self._geodesic = self.datum.ellipsoid.geodesic self.beta = beta if wrap: self._wrap = True if name: self.name = name
def toLatLon(self, LatLon=None, height=None): '''Convert this L{Css} to an (ellipsoidal) geodetic point. @keyword LatLon: Optional, ellipsoidal (sub-)class to return the geodetic point (C{LatLon}) or C{None}. @keyword height: Optional height for the point, overriding the default height (C{meter}). @return: The point (B{C{LatLon}}) or a L{LatLon4Tuple}C{(lat, lon, height, datum)} if B{C{LatLon}} is C{None}. @raise TypeError: If B{C{LatLon}} or B{C{datum}} is not ellipsoidal. ''' if LatLon and not issubclassof(LatLon, _LLEB): raise _IsNotError(_LLEB.__name__, LatLon=LatLon) lat, lon = self.latlon d = self.cs0.datum h = self.height if height is None else height r = LatLon4Tuple(lat, lon, h, d) if LatLon is None else \ LatLon(lat, lon, height=h, datum=d) return self._xnamed(r)
def _2epoch(epoch): # imported by .ellipsoidalBase.py '''(INTERNAL) Validate an C{epoch}. ''' if isscalar(epoch) and epoch > 0: # XXX 1970? return _F(epoch) raise _IsNotError('scalar', epoch=epoch)