Coverage for pygeodesy/frechet.py : 97%

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 -*-
Classes L{Frechet}, L{FrechetDegrees}, L{FrechetRadians}, L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetCosineLaw}, L{FrechetDistanceTo}< L{FrechetEquirectangular}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetFlatPolar}, L{FrechetHaversine}, L{FrechetHubeny}, L{FrechetKarney}, L{FrechetThomas} and L{FrechetVincentys} to compute I{discrete} U{Fréchet <https://WikiPedia.org/wiki/Frechet_distance>} distances between two sets of C{LatLon}, C{NumPy}, C{tuples} or other types of points.
Only L{FrechetDistanceTo} -iff used with L{ellipsoidalKarney.LatLon} points- and L{FrechetKarney} requires installation of I{Charles Karney}'s U{geographiclib<https://PyPI.org/project/geographiclib>}.
Typical usage is as follows. First, create a C{Frechet} calculator from one set of C{LatLon} points.
C{f = FrechetXyz(points1, ...)}
Get the I{discrete} Fréchet distance to another set of C{LatLon} points by
C{t6 = f.discrete(points2)}
Or, use function C{frechet_} with a proper C{distance} function passed as keyword arguments as follows
C{t6 = frechet_(points1, points2, ..., distance=...)}.
In both cases, the returned result C{t6} is a L{Frechet6Tuple}.
For C{(lat, lon, ...)} points in a C{NumPy} array or plain C{tuples}, wrap the points in a L{Numpy2LatLon} respectively L{Tuple2LatLon} instance, more details in the documentation thereof.
For other points, create a L{Frechet} sub-class with the appropriate C{distance} method overloading L{Frechet.distance} as in this example.
>>> from pygeodesy import Frechet, hypot_ >>> >>> class F3D(Frechet): >>> """Custom Frechet example. >>> """ >>> def distance(self, p1, p2): >>> return hypot_(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z) >>> >>> f3D = F3D(xyz1, ..., units="...") >>> t6 = f3D.discrete(xyz2)
Transcribed from the original U{Computing Discrete Fréchet Distance <https://www.kr.TUWien.ac.AT/staff/eiter/et-archive/cdtr9464.pdf>} by Eiter, T. and Mannila, H., 1994, April 25, Technical Report CD-TR 94/64, Information Systems Department/Christian Doppler Laboratory for Expert Systems, Technical University Vienna, Austria.
This L{Frechet.discrete} implementation optionally generates intermediate points for each point set separately. For example, using keyword argument C{fraction=0.5} adds one additional point halfway between each pair of points. Or using C{fraction=0.1} interpolates nine additional points between each points pair.
The L{Frechet6Tuple} attributes C{fi1} and/or C{fi2} will be I{fractional} indices of type C{float} if keyword argument C{fraction} is used. Otherwise, C{fi1} and/or C{fi2} are simply type C{int} indices into the respective points set.
For example, C{fractional} index value 2.5 means an intermediate point halfway between points[2] and points[3]. Use function L{fractional} to obtain the intermediate point for a I{fractional} index in the corresponding set of points.
The C{Fréchet} distance was introduced in 1906 by U{Maurice Fréchet <https://WikiPedia.org/wiki/Maurice_Rene_Frechet>}, see U{reference [6]<https://www.kr.TUWien.ac.AT/staff/eiter/et-archive/cdtr9464.pdf>}. It is a measure of similarity between curves that takes into account the location and ordering of the points. Therefore, it is often a better metric than the well-known C{Hausdorff} distance, see the L{hausdorff} module. '''
cosineLaw_, euclidean_, flatPolar_, haversine_, \ thomas_, vincentys_, _scale_rad _DOT_, _n_, _points_, _units_ _Str_NN, _Str_radians, _Str_radians2, _xUnit, _xUnits
and (float(n) - fraction) < n): raise FrechetError(fraction=fraction)
'''Fréchet issue. '''
'''Frechet base class, requires method L{Frechet.distance} to be overloaded. '''
'''New C{Frechet...} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{None}, C{0} or C{1} for no intermediate B{C{points}} and no I{fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}). @kwarg units: Optional, the distance units (C{Unit} or C{str}). @kwarg wrap_adjust: Optionally, C{wrap} and unroll longitudes, iff applicable (C{bool}) and C{adjust} wrapped, unrolled longitudinal delta by the cosine of the mean latitude, iff applicable.
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}} or B{C{wrap}} or B{C{ajust}} not applicable.
''' self.name = name self.units = units
'''Get the adjust setting (C{bool} or C{None} if not applicable). '''
'''Get the datum (L{Datum} or C{None} if not applicable). '''
'''(INTERNAL) Set the datum. ''' if d and d != self.datum: # PYCHOK no cover _xinstanceof(Datum, datum=d) self._datum = d
'''Compute the C{forward, discrete Fréchet} distance.
@arg points: Second set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{None}, C{0} or C{1} for no intermediate B{C{points}} and no I{fractional} indices.
@return: A L{Frechet6Tuple}C{(fd, fi1, fi2, r, n, units)}.
@raise FrechetError: Insufficient number of B{C{points}} or an invalid B{C{point}} or B{C{fraction}}.
@raise RecursionError: Recursion depth exceeded, see U{sys.getrecursionlimit() <https://docs.Python.org/3/library/sys.html#sys.getrecursionlimit>}. '''
except TypeError as x: t = _DOT_(self.classname, self.discrete.__name__) raise FrechetError(t, txt=str(x))
def distance(self, point1, point2): # PYCHOK no cover '''(INTERNAL) I{Must be overloaded}, see function C{notOverloaded}. ''' notOverloaded(self, point1, point2)
'''Get the index fraction (C{float} or C{1}). '''
'''Set the index fraction (C{float} or C{1}).
@arg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{None}, C{0} or C{1} for no intermediate B{C{points}} and no I{fractional} indices.
@raise FrechetError: Invalid B{C{fraction}}. '''
'''Convert a point for the C{.distance} method.
@arg point: The point to convert ((C{LatLon}, L{Numpy2LatLon}, L{Tuple2LatLon} or C{other}).
@return: The converted B{C{point}}. '''
'''Get and convert a point for the C{.distance} method.
@arg points: The orignal B{C{points}} to convert ((C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @arg i: The B{C{points}} index (C{int}).
@return: The converted B{C{points[i]}}. '''
'''(INTERNAL) Check a set of points. '''
'''Get and convert a I{fractional} point for the C{.distance} method.
@arg points: The orignal B{C{points}} to convert ((C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @arg fi: The I{fractional} index in B{C{points}} (C{float} or C{int}).
@return: The interpolated, converted, intermediate B{C{points[fi]}}. '''
'''Get the distance units (C{Unit} or C{str}). '''
'''Set the distance units.
@arg units: New units (C{Unit} or C{str}).
@raise TypeError: Invalid B{C{units}}. '''
'''Get the wrap setting (C{bool} or C{None} if not applicable). '''
'''L{Frechet} base class for distances in C{degrees} from C{LatLon} points in C{degrees}. '''
if _FOR_DOCS: __init__ = Frechet.__init__ discrete = Frechet.discrete
'''L{Frechet} base class for distances in C{radians} or C{radians squared} from C{LatLon} points converted from C{degrees} to C{radians}. '''
if _FOR_DOCS: __init__ = Frechet.__init__ discrete = Frechet.discrete
'''Convert C{(lat, lon)} point in degrees to C{(a, b)} in radians.
@return: An L{PhiLam2Tuple}C{(phi, lam)}. ''' except AttributeError: return PhiLam2Tuple(radians(point.lat), radians(point.lon))
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.cosineAndoyerLambert_}.
@see: L{FrechetCosineForsytheAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetHubeny}, L{FrechetThomas} and L{FrechetKarney}. '''
'''New L{FrechetCosineAndoyerLambert} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise TypeError: Invalid B{C{datum}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.cosineAndoyerLambert_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.cosineForsytheAndoyerLambert_}.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetHubeny}, L{FrechetThomas} and L{FrechetKarney}. '''
'''New L{FrechetCosineForsytheAndoyerLambert} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise TypeError: Invalid B{C{datum}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.cosineForsytheAndoyerLambert_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.cosineLaw_}.
@see: L{FrechetEquirectangular}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetFlatPolar}, L{FrechetHaversine} and L{FrechetVincentys}.
@note: See note at function L{pygeodesy.vincentys_}. '''
'''New L{FrechetCosineLaw} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.cosineLaw_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the distance from the points' C{LatLon.distanceTo} method, conventionally in C{meter}.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetHubeny}, L{FrechetThomas} and L{FrechetKarney}. '''
'''New L{FrechetDistanceTo} calculator/interpolator.
@arg points: First set of points (C{LatLon}[]). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}). @kwarg distanceTo_kwds: Optional keyword arguments for the B{C{points}}' C{LatLon.distanceTo} method.
@raise FrechetError: Insufficient number of B{C{points}} or an invalid B{C{point}} or B{C{fraction}}.
@raise ImportError: Package U{geographiclib <https://PyPI.org/project/geographiclib>} missing iff B{C{points}} are L{ellipsoidalKarney.LatLon}s.
@note: All B{C{points}} I{must} be instances of the same ellipsoidal or spherical C{LatLon} class. ''' self._distanceTo_kwds = distanceTo_kwds
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the distance in C{meter}. '''
'''(INTERNAL) Check a set of points. ''' i = Fmt.SQUARE(_points_, i) raise FrechetError(i, p, txt=_distanceTo_)
'''Compute the C{Frechet} distance based on the I{equirectangular} distance in C{radians squared} like function L{pygeodesy.equirectangular_}.
@see: L{FrechetCosineLaw}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetFlatPolar}, L{FrechetHaversine} and L{FrechetVincentys}. '''
'''New L{FrechetEquirectangular} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine of the mean latitude (C{bool}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{adjust}} or B{C{seed}}. ''' adjust=adjust, wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.equirectangular_} distance in C{radians squared}. '''
'''Compute the C{Frechet} distance based on the I{Euclidean} distance in C{radians} from function L{pygeodesy.euclidean_}.
@see: L{FrechetCosineLaw}, L{FrechetEquirectangular}, L{FrechetExact}, L{FrechetFlatPolar}, L{FrechetHaversine} and L{FrechetVincentys}. '''
'''New L{FrechetEuclidean} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine of the mean latitude (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}. ''' adjust=adjust)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.euclidean_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{degrees} from method L{GeodesicExact}C{.Inverse}.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetFlatLocal}, L{FrechetHubeny}, L{FrechetKarney} and L{FrechetThomas}. '''
'''New L{FrechetExact} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise TypeError: Invalid B{C{datum}}. ''' FrechetDegrees.__init__(self, points, fraction=fraction, name=name, wrap=wrap) self._datum_setter(datum) self._Inverse1 = self.datum.ellipsoid.geodesicx.Inverse1 # note -x
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the non-negative I{angular} distance in C{degrees}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians squared} like function L{pygeodesy.flatLocal_}/L{pygeodesy.hubeny_}.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetExact}, L{FrechetHubeny}, L{FrechetKarney} and L{FrechetThomas}. '''
'''New L{FrechetFlatLocal}/L{FrechetHubeny} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise TypeError: Invalid B{C{datum}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.flatLocal_}/L{pygeodesy.hubeny_} distance in C{radians squared}. '''
'''(INTERNAL) Get and cache the C{.datum.ellipsoid._hubeny_2} method. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{flatPolar_}.
@see: L{FrechetCosineLaw}, L{FrechetEquirectangular}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetHaversine} and L{FrechetVincentys}. '''
'''New L{FrechetFlatPolar} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{flatPolar_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.haversine_}.
@see: L{FrechetCosineLaw}, L{FrechetEquirectangular}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetFlatPolar} and L{FrechetVincentys}.
@note: See note at function L{pygeodesy.vincentys_}. '''
'''New L{FrechetHaversine} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.haversine_} distance in C{radians}. '''
if _FOR_DOCS: __doc__ = FrechetFlatLocal.__doc__ __init__ = FrechetFlatLocal.__init__ discrete = FrechetFlatLocal.discrete distance = FrechetFlatLocal.discrete
'''Compute the C{Frechet} distance based on the I{angular} distance in C{degrees} from I{Karney}'s U{geographiclib <https://PyPI.org/project/geographiclib>} U{Geodesic <https://GeographicLib.SourceForge.io/html/python/code.html>} Inverse method.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetHubeny} and L{FrechetThomas}. ''' '''New L{FrechetKarney} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise ImportError: Package U{geographiclib <https://PyPI.org/project/geographiclib>} missing.
@raise TypeError: Invalid B{C{datum}}. ''' wrap=wrap)
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.thomas_}.
@see: L{FrechetCosineAndoyerLambert}, L{FrechetCosineForsytheAndoyerLambert}, L{FrechetDistanceTo}, L{FrechetExact}, L{FrechetFlatLocal}, L{FrechetHubeny} and L{FrechetKarney}. '''
'''New L{FrechetThomas} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg datum: Optional datum overriding the default C{Datums.WGS84} and first B{C{points}}' datum (L{Datum}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}) @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}.
@raise TypeError: Invalid B{C{datum}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.thomas_} distance in C{radians}. '''
'''Compute the C{Frechet} distance based on the I{angular} distance in C{radians} from function L{pygeodesy.vincentys_}.
@see: L{FrechetCosineLaw}, L{FrechetEquirectangular}, L{FrechetEuclidean}, L{FrechetExact}, L{FrechetFlatPolar} and L{FrechetHaversine}.
@note: See note at function L{pygeodesy.vincentys_}. '''
'''New L{FrechetVincentys} calculator/interpolator.
@arg points: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}). @kwarg fraction: Index fraction (C{float} in L{EPS}..L{EPS1}) to interpolate intermediate B{C{points}} or use C{0}, C{1} or C{None} to avoid intermediate B{C{points}} and L{pygeodesy.fractional} indices. @kwarg name: Optional calculator/interpolator name (C{str}).
@raise FrechetError: Insufficient number of B{C{points}} or invalid B{C{fraction}}. ''' wrap=wrap)
if _FOR_DOCS: discrete = Frechet.discrete
'''Return the L{pygeodesy.vincentys_} distance in C{radians}. '''
'''(INTERNAL) Recursive core of function L{frechet_} and method C{discrete} of C{Frechet...} classes. '''
except KeyError: r = iF(r + 1) try: if i > 0: if j > 0: t = min(rF(i - fi, j, r), rF(i - fi, j - fj, r), rF(i, j - fj, r)) elif j < 0: raise IndexError else: # j == 0 t = rF(i - fi, 0, r) elif i < 0: raise IndexError
elif j > 0: # i == 0 t = rF(0, j - fj, r) elif j < 0: # i == 0 raise IndexError else: # i == j == 0 t = (NINF, i, j, r)
d = dF(i, j) if d > t[0]: t = (d, i, j, r) except IndexError: t = (INF, i, j, r) cF[i][j] = t
# del cF, iFs
'''Compute the I{discrete} U{Fréchet<https://WikiPedia.org/wiki/Frechet_distance>} distance between two paths given as sets of points.
@arg points1: First set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @arg points2: Second set of points (C{LatLon}[], L{Numpy2LatLon}[], L{Tuple2LatLon}[] or C{other}[]). @kwarg distance: Callable returning the distance between a B{C{points1}} and a B{C{points2}} point (signature C{(point1, point2)}). @kwarg units: Optional, the distance units (C{Unit} or 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: Function L{frechet_} does not support I{fractional} indices for intermediate B{C{points1}} and B{C{points2}}. ''' raise _IsnotError(callable.__name__, distance=distance)
'''6-Tuple C{(fd, fi1, fi2, r, n, units)} with the I{discrete} U{Fréchet<https://WikiPedia.org/wiki/Frechet_distance>} distance C{fd}, I{fractional} indices C{fi1} and C{fi2} as C{FIx}, the recursion depth C{r}, the number of distances computed C{n} and the L{units} class or class or name of the distance C{units}.
If I{fractional} indices C{fi1} and C{fi2} are C{int}, the returned C{fd} is the distance between C{points1[fi1]} and C{points2[fi2]}. For C{float} indices, the distance is between an intermediate point along C{points1[int(fi1)]} and C{points1[int(fi1) + 1]} respectively an intermediate point along C{points2[int(fi2)]} and C{points2[int(fi2) + 1]}.
Use function L{fractional} to compute the point at a I{fractional} index. '''
'''Overloaded C{_NamedTuple.toUnits} for C{fd} units. '''
# def __gt__(self, other): # _xinstanceof(Frechet6Tuple, other=other) # return self if self.fd > other.fd else other # PYCHOK .fd=[0] # # def __lt__(self, other): # _xinstanceof(Frechet6Tuple, other=other) # return self if self.fd < other.fd else other # PYCHOK .fd=[0]
# **) MIT License # # Copyright (C) 2016-2022 -- 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. |