Exemple #1
0
def thomas(lat1, lon1, lat2, lon2, datum=Datums.WGS84, wrap=False):
    '''Compute the distance between two (ellipsoidal) points using
       U{Thomas'<https://apps.DTIC.mil/dtic/tr/fulltext/u2/703541.pdf>}
       formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg datum: Ellipsoidal datum to use (L{Datum}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as the B{C{datum}}'s
                ellipsoid axes).

       @raise TypeError: Invalid B{C{datum}}.

       @see: Functions L{thomas_}, L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert},
             L{cosineLaw}, L{equirectangular}, L{euclidean}, L{flatLocal}/L{hubeny},
             L{flatPolar}, L{haversine}, L{vincentys} and method L{Ellipsoid.distance2}.
    '''
    d, _ = unroll180(lon1, lon2, wrap=wrap)
    r = thomas_(Phi_(lat2, name=_lat2_),
                Phi_(lat1, name=_lat1_),
                radians(d),
                datum=datum)
    return r * datum.ellipsoid.a
Exemple #2
0
def cosineForsytheAndoyerLambert(lat1,
                                 lon1,
                                 lat2,
                                 lon2,
                                 datum=Datums.WGS84,
                                 wrap=False):
    '''Compute the distance between two (ellipsoidal) points using the
       U{Forsythe-Andoyer-Lambert correction<https://www2.UNB.CA/gge/Pubs/TR77.pdf>} of
       the U{Law of Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
       formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg datum: Ellipsoidal datum to use (L{Datum}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as the B{C{datum}}'s
                ellipsoid axes).

       @raise TypeError: Invalid B{C{datum}}.

       @see: Functions L{cosineForsytheAndoyerLambert_}, L{cosineAndoyerLambert},
             L{cosineLaw}, L{equirectangular}, L{euclidean}, L{flatLocal}/L{hubeny},
             L{flatPolar}, L{haversine}, L{thomas} and L{vincentys} and method
             L{Ellipsoid.distance2}.
    '''
    d, _ = unroll180(lon1, lon2, wrap=wrap)
    r = cosineForsytheAndoyerLambert_(Phi_(lat2, name=_lat2_),
                                      Phi_(lat1, name=_lat1_),
                                      radians(d),
                                      datum=datum)
    return r * datum.ellipsoid.a
Exemple #3
0
def cosineLaw(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
    '''Compute the distance between two points using the
       U{spherical Law of Cosines
       <https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
       fromula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @raise TypeError: Invalid B{C{datum}}.

       @see: Functions L{cosineLaw_}, L{equirectangular}, L{euclidean},
             L{flatLocal}, L{flatPolar}, L{haversine}, L{vincentys} and
             method L{Ellipsoid.distance2}.

       @note: See note at function L{vincentys_}.
    '''
    r = Radius(radius)
    if r:
        d, _ = unroll180(lon1, lon2, wrap=wrap)
        r *= cosineLaw_(Phi_(lat2, name='lat2'), Phi_(lat1, name='lat1'),
                        radians(d))
    return r
Exemple #4
0
def cosineAndoyerLambert(lat1, lon1, lat2, lon2, datum=Datums.WGS84, wrap=False):
    '''Compute the distance between two (ellipsoidal) points using the
       U{Andoyer-Lambert correction<https://navlib.net/wp-content/uploads/
       2013/10/admiralty-manual-of-navigation-vol-1-1964-english501c.pdf>} of the
       U{Law of Cosines<https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>}
       fromula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg datum: Ellipsoidal datum to use (L{Datum}, L{Ellipsoid},
                     L{Ellipsoid2} or L{a_f2Tuple}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as the B{C{datum}}'s
                ellipsoid axes).

       @raise TypeError: Invalid B{C{datum}}.

       @see: Functions L{cosineAndoyerLambert_}, L{cosineForsytheAndoyerLambert},
             L{cosineLaw}, L{equirectangular}, L{euclidean}, L{flatLocal}/L{hubeny},
             L{flatPolar}, L{haversine}, L{thomas} and L{vincentys} and method
             L{Ellipsoid.distance2}.
    '''
    d, _ = unroll180(lon1, lon2, wrap=wrap)
    r = cosineAndoyerLambert_(Phi_(lat2=lat2),
                              Phi_(lat1=lat1), radians(d), datum=datum)
    return r * datum.ellipsoid.a
Exemple #5
0
def vincentys(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
    '''Compute the distance between two (spherical) points using
       U{Vincenty's<https://WikiPedia.org/wiki/Great-circle_distance>}
       spherical formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @see: Functions L{vincentys_}, L{cosineLaw}, L{equirectangular},
             L{euclidean}, L{flatLocal}, L{flatPolar}, L{haversine} and
             methods L{Ellipsoid.distance2}, C{LatLon.distanceTo*} and
             C{LatLon.equirectangularTo}.

       @note: See note at function L{vincentys_}.
    '''
    r = Radius(radius)
    if r:
        d, _ = unroll180(lon1, lon2, wrap=wrap)
        r *= vincentys_(Phi_(lat2, name='lat2'), Phi_(lat1, name='lat1'),
                        radians(d))
    return r
Exemple #6
0
def flatPolar(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
    '''Compute the distance between two (spherical) points using
       the U{polar coordinate flat-Earth
       <https://WikiPedia.org/wiki/Geographical_distance#Polar_coordinate_flat-Earth_formula>}
       formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @see: Functions L{flatPolar_}, L{cosineLaw}, L{flatLocal},
             L{equirectangular}, L{euclidean}, L{haversine} and
             L{vincentys}.
    '''
    r = Radius(radius)
    if r:
        d, _ = unroll180(lon1, lon2, wrap=wrap)
        r *= flatPolar_(Phi_(lat2, name='lat2'), Phi_(lat1, name='lat1'),
                        radians(d))
    return r
Exemple #7
0
def haversine(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
    '''Compute the distance between two (spherical) points using the
       U{Haversine<https://www.Movable-Type.co.UK/scripts/latlong.html>}
       formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @see: U{Distance between two (spherical) points
             <https://www.EdWilliams.org/avform.htm#Dist>}, functions
             L{cosineLaw}, L{equirectangular}, L{euclidean},
             L{flatLocal}, L{flatPolar}, L{vincentys} and methods
             L{Ellipsoid.distance2}, C{LatLon.distanceTo*} and
             C{LatLon.equirectangularTo}.

       @note: See note at function L{vincentys_}.
    '''
    r = Radius(radius)
    if r:
        d, _ = unroll180(lon1, lon2, wrap=wrap)
        r *= haversine_(Phi_(lat2, name='lat2'), Phi_(lat1, name='lat1'),
                        radians(d))
    return r
Exemple #8
0
def euclidean(lat1, lon1, lat2, lon2, radius=R_M, adjust=True, wrap=False):
    '''Approximate the C{Euclidian} distance between two (spherical) points.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg adjust: Adjust the longitudinal delta by the cosine
                      of the mean latitude (C{bool}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @see: U{Distance between two (spherical) points
             <https://www.EdWilliams.org/avform.htm#Dist>}, functions
             L{euclidean_}, L{cosineLaw}, L{equirectangular}, L{flatLocal},
             L{flatPolar}, L{haversine}, L{vincentys} and methods
             L{Ellipsoid.distance2}, C{LatLon.distanceTo*} and
             C{LatLon.equirectangularTo}.
    '''
    r = Radius(radius)
    if r:
        d, _ = unroll180(lon1, lon2, wrap=wrap)
        r *= euclidean_(Phi_(lat2, name='lat2'),
                        Phi_(lat1, name='lat1'),
                        radians(d),
                        adjust=adjust)
    return r
Exemple #9
0
def flatLocal(lat1, lon1, lat2, lon2, datum=Datums.WGS84, wrap=False):
    '''Compute the distance between two (ellipsoidal) points using
       the U{ellipsoidal Earth to plane projection
       <https://WikiPedia.org/wiki/Geographical_distance#Ellipsoidal_Earth_projected_to_a_plane>}
       fromula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg datum: Optional, (ellipsoidal) datum to use (L{Datum}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as the B{C{datum}}'s
                ellipsoid axes).

       @raise TypeError: Invalid B{C{datum}}.

       @note: The meridional and prime_vertical radii of curvature
              are taken and scaled at the mean latitude.

       @see: Functions L{flatLocal_}, L{cosineLaw}, L{flatPolar},
             L{equirectangular}, L{euclidean}, L{haversine},
             L{vincentys}, method L{Ellipsoid.distance2} and
             U{local, flat earth approximation
             <https://www.edwilliams.org/avform.htm#flat>}.
    '''
    d, _ = unroll180(lon1, lon2, wrap=wrap)
    return flatLocal_(Phi_(lat2, name='lat2'),
                      Phi_(lat1, name='lat1'),
                      radians(d),
                      datum=datum)
Exemple #10
0
def flatLocal(lat1, lon1, lat2, lon2, datum=Datums.WGS84, wrap=False):
    '''Compute the distance between two (ellipsoidal) points using
       the U{ellipsoidal Earth to plane projection<https://WikiPedia.org/
       wiki/Geographical_distance#Ellipsoidal_Earth_projected_to_a_plane>}
       aka U{Hubeny<https://www.OVG.AT/de/vgi/files/pdf/3781/>} formula.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg datum: Ellipsoidal datum to use (L{Datum}, L{Ellipsoid},
                     L{Ellipsoid2} or L{a_f2Tuple}).
       @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}).

       @return: Distance (C{meter}, same units as the B{C{datum}}'s
                ellipsoid axes).

       @raise TypeError: Invalid B{C{datum}}.

       @note: The meridional and prime_vertical radii of curvature
              are taken and scaled at the mean of both latitude.

       @see: Functions L{flatLocal_}/L{hubeny_}, L{cosineLaw},
             L{flatPolar}, L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert},
             L{equirectangular}, L{euclidean}, L{haversine}, L{thomas}, L{vincentys},
             method L{Ellipsoid.distance2} and U{local, flat earth approximation
             <https://www.EdWilliams.org/avform.htm#flat>}.
    '''
    d, _ = unroll180(lon1, lon2, wrap=wrap)
    return flatLocal_(Phi_(lat2=lat2),
                      Phi_(lat1=lat1), radians(d), datum=datum)
Exemple #11
0
    def __init__(self,
                 latlon0,
                 par1,
                 par2=None,
                 E0=0,
                 N0=0,
                 k0=1,
                 opt3=0,
                 name=NN,
                 auth=NN):
        '''New Lambert conformal conic projection.

           @arg latlon0: Origin with (ellipsoidal) datum (C{LatLon}).
           @arg par1: First standard parallel (C{degrees90}).
           @kwarg par2: Optional, second standard parallel (C{degrees90}).
           @kwarg E0: Optional, false easting (C{meter}).
           @kwarg N0: Optional, false northing (C{meter}).
           @kwarg k0: Optional scale factor (C{scalar}).
           @kwarg opt3: Optional meridian (C{degrees180}).
           @kwarg name: Optional name of the conic (C{str}).
           @kwarg auth: Optional authentication authority (C{str}).

           @return: A Lambert projection (L{Conic}).

           @raise TypeError: Non-ellipsoidal B{C{latlon0}}.

           @raise ValueError: Invalid B{C{par1}}, B{C{par2}},
                              B{C{E0}}, B{C{N0}}, B{C{k0}}
                              or B{C{opt3}}.

           @example:

           >>> from pygeodesy import Conic, Datums, ellipsoidalNvector
           >>> ll0 = ellipsoidalNvector.LatLon(23, -96, datum=Datums.NAD27)
           >>> Snyder = Conic(ll0, 33, 45, E0=0, N0=0, name='Snyder')
        '''
        if latlon0 is not None:
            _xinstanceof(_LLEB, latlon0=latlon0)
            self._phi0, self._lam0 = latlon0.philam

            self._par1 = Phi_(par1, name=_par1_)
            self._par2 = self._par1 if par2 is None else Phi_(par2,
                                                              name=_par2_)

            if k0 != 1:
                self._k0 = Scalar_(k0, name=_k0_)
            if E0:
                self._E0 = Northing(E0, name=_E0_, falsed=True)
            if N0:
                self._N0 = Easting(N0, name=_N0_, falsed=True)
            if opt3:
                self._opt3 = Lam_(opt3, name='opt3')

            self.toDatum(latlon0.datum)._dup2(self)
            self._register(Conics, name)
        elif name:
            self.name = name
        if auth:
            self._auth = str(auth)
Exemple #12
0
def heightOf(angle, distance, radius=R_M):
    '''Determine the height above the (spherical) earth after
       traveling along a straight line at a given tilt.

       @arg angle: Tilt angle above horizontal (C{degrees}).
       @arg distance: Distance along the line (C{meter} or same units as
                      B{C{radius}}).
       @kwarg radius: Optional mean earth radius (C{meter}).

       @return: Height (C{meter}, same units as B{C{distance}} and B{C{radius}}).

       @raise ValueError: Invalid B{C{angle}}, B{C{distance}} or B{C{radius}}.

       @see: U{MultiDop geog_lib.GeogBeamHt<https://GitHub.com/NASA/MultiDop>}
             (U{Shapiro et al. 2009, JTECH
             <https://Journals.AMetSoc.org/doi/abs/10.1175/2009JTECHA1256.1>}
             and U{Potvin et al. 2012, JTECH
             <https://Journals.AMetSoc.org/doi/abs/10.1175/JTECH-D-11-00019.1>}).
    '''
    r = h = Radius(radius)
    d = abs(Distance(distance))
    if d > h:
        d, h = h, d

    if d > EPS:
        d = d / h  # PyChecker chokes on ... /= ...
        s = sin(Phi_(angle, name='angle', clip=180))
        s = fsum_(1, 2 * s * d, d**2)
        if s > 0:
            return h * sqrt(s) - r

    raise InvalidError(angle=angle, distance=distance, radius=radius)
Exemple #13
0
 def philam(self):
     '''Get the lat- and longitude ((L{PhiLam2Tuple}C{(phi, lam)}).
     '''
     if self._philam is None:
         r = self.latlon
         self._philam = PhiLam2Tuple(Phi_(r.lat), Lam_(r.lon))
     return self._xnamed(self._philam)
Exemple #14
0
def bearing(lat1, lon1, lat2, lon2, **options):
    '''Compute the initial or final bearing (forward or reverse
       azimuth) between a (spherical) start and end point.

       @arg lat1: Start latitude (C{degrees}).
       @arg lon1: Start longitude (C{degrees}).
       @arg lat2: End latitude (C{degrees}).
       @arg lon2: End longitude (C{degrees}).
       @kwarg options: Optional keyword arguments for function
                       L{bearing_}.

       @return: Initial or final bearing (compass C{degrees360}) or
                zero if start and end point coincide.
    '''
    return degrees(
        bearing_(Phi_(lat1, name='lat1'), Lam_(lon1, name='lon1'),
                 Phi_(lat2, name='lat2'), Lam_(lon2, name='lon2'), **options))
Exemple #15
0
def degrees2m(deg, radius=R_M, lat=0):
    '''Convert angle to distance along the equator or along a
       parallel at an other latitude.

       @arg deg: Angle (C{degrees}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg lat: Parallel latitude (C{degrees90}, C{str}).

       @return: Distance (C{meter}, same units as B{C{radius}}).

       @raise RangeError: Latitude B{C{lat}} outside valid range
                          and L{rangerrors} set to C{True}.

       @raise ValueError: Invalid B{C{deg}}, B{C{radius}} or
                          B{C{lat}}.

       @see: Function L{m2degrees}.
    '''
    m = Lam_(deg, name=_deg_, clip=0) * Radius(radius)
    if lat:
        m *= cos(Phi_(lat))
    return float(m)
Exemple #16
0
def m2degrees(meter, radius=R_M, lat=0):
    '''Convert distance to angle along equator or along a
       parallel at an other latitude.

       @arg meter: Distance (C{meter}, same units as B{C{radius}}).
       @kwarg radius: Mean earth radius (C{meter}).
       @kwarg lat: Parallel latitude (C{degrees90}, C{str}).

       @return: Angle (C{degrees}).

       @raise RangeError: Latitude B{C{lat}} outside valid range
                          and L{rangerrors} set to C{True}.

       @raise ValueError: Invalid B{C{meter}}, B{C{radius}} or
                          B{C{lat}}.

       @see: Function L{degrees2m}.
    '''
    r = Radius(radius)
    if lat:
        r *= cos(Phi_(lat))
    return degrees(Meter(meter) / r)
Exemple #17
0
from pygeodesy.lazily import _ALL_LAZY
from pygeodesy.named import EasNor2Tuple, LatLonDatum3Tuple, \
                           _NamedBase, nameof, _xnamed
from pygeodesy.streprs import enstr2
from pygeodesy.units import Easting, Lam_, Northing, Phi_, Scalar
from pygeodesy.utily import degrees90, degrees180, sincos2

from math import cos, radians, sin, sqrt, tan

__all__ = _ALL_LAZY.osgr
__version__ = '20.09.01'

_10um = 1e-5  #: (INTERNAL) 0.01 millimeter (C{meter})
_100km = 100000  #: (INTERNAL) 100 km (int meter)

_A0 = Phi_(49)  #: (INTERNAL) NatGrid true origin latitude, 49°N.
_B0 = Lam_(-2)  #: (INTERNAL) NatGrid true origin longitude, 2°W.
_E0 = Easting(400e3)  #: (INTERNAL) Easting of true origin (C{meter}).
_N0 = Northing(-100e3)  #: (INTERNAL) Northing of true origin (C{meter}).
_F0 = Scalar(
    0.9996012717)  #: (INTERNAL) NatGrid scale of central meridian (C{float}).

_Datums_OSGB36 = Datums.OSGB36  #: (INTERNAL) Airy130 ellipsoid
_latlon_ = 'latlon'
_no_convertDatum_ = 'no .convertDatum'
_ord_A = ord('A')
_TRIPS = 33  #: (INTERNAL) .toLatLon convergence


def _ll2datum(ll, datum, name):
    '''(INTERNAL) Convert datum if needed.