Coverage for pygeodesy/latlonBase.py : 96%

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 -*-
and N-vectorial C{LatLon}s.
After I{(C) Chris Veness 2011-2015} published under the same MIT Licence**, see U{https://www.Movable-Type.co.UK/scripts/latlong.html}, U{<https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html>} and U{https://www.Movable-Type.co.UK/scripts/latlong-vectors.html}. '''
# from pygeodesy.datums import _spherical_datum # from .formy _ValueError, _xdatum, _xError, _xkwds, _xkwds_not cosineForsytheAndoyerLambert_, cosineLaw, \ equirectangular, euclidean, flatLocal_, \ flatPolar, hartzell, haversine, isantipode, \ latlon2n_xyz, _spherical_datum, thomas_, vincentys _intersection_, _m_, _no_, _overlap_, _point_ Trilaterate5Tuple, Vector3Tuple property_doc_, property_RO, _update_all Scalar, Scalar_ circum4_, Circum4Tuple, _radii11ABC
'''(INTERNAL) Base class for C{LatLon} points on spherical or ellipsoidal earth models. '''
'''New C{LatLon}.
@arg lat: Latitude (C{degrees} or DMS C{str} with N or S suffix). @arg lon: Longitude (C{degrees} or DMS C{str} with E or W suffix). @kwarg height: Optional height (C{meter} above or below the earth surface). @kwarg name: Optional name (C{str}).
@return: New instance (C{LatLon}).
@raise RangeError: Value of B{C{lat}} or B{C{lon}} outside the valid range and C{rangerrors} set to C{True}.
@raise UnitError: Invalid B{C{lat}}, B{C{lon}} or B{C{height}}.
@example:
>>> p = LatLon(50.06632, -5.71475) >>> q = LatLon('50°03′59″N', """005°42'53"W""") '''
'''Return the antipode, the point diametrically opposite to this point.
@kwarg height: Optional height of the antipode (C{meter}), this point's height otherwise.
@return: The antipodal point (C{LatLon}). '''
def bounds(self, wide, tall, radius=R_M): # PYCHOK no cover '''DEPRECATED, use method C{boundsOf}.''' return self.boundsOf(wide, tall, radius=radius)
'''Return the SW and NE lat-/longitude of a great circle bounding box centered at this location.
@arg wide: Longitudinal box width (C{meter}, same units as B{C{radius}} or C{degrees} if B{C{radius}} is C{None}). @arg tall: Latitudinal box size (C{meter}, same units as B{C{radius}} or C{degrees} if B{C{radius}} is C{None}). @kwarg radius: Mean earth radius (C{meter}). @kwarg height: Height for C{latlonSW} and C{latlonNE} (C{meter}), overriding the point's height.
@return: A L{Bounds2Tuple}C{(latlonSW, latlonNE)}, the lower-left and upper-right corner (C{LatLon}).
@see: U{https://www.Movable-Type.co.UK/scripts/latlong-db.html} '''
'''Compute the length of the chord through the earth between this and an other point.
@arg other: The other point (C{LatLon}). @kwarg height: Overriding height for both points (C{meter}) or C{None} for each point's height.
@return: The chord length (conventionally C{meter}).
@raise TypeError: The B{C{other}} point is not C{LatLon}. '''
'''Return the radius and center of the I{inscribed} aka I{In-}circle of the (planar) triangle formed by this and two other points.
@arg point2: Second point (C{LatLon}). @arg point3: Third point (C{LatLon}). @kwarg eps: Tolerance for function L{pygeodesy.trilaterate3d2}.
@return: L{Circin6Tuple}C{(radius, center, deltas, cA, cB, cC)}. The C{center} and contact points C{cA}, C{cB} and C{cC}, each an instance of this (sub-)class, are co-planar with this and the two given points, see the B{Note} below.
@raise ImportError: Package C{numpy} not found, not installed or older than version 1.10.
@raise IntersectionError: Near-coincident or -colinear points or a trilateration or C{numpy} issue.
@raise TypeError: Invalid B{C{point2}} or B{C{point3}}.
@note: The C{center} is trilaterated in cartesian (ECEF) space and converted back to geodetic lat-, longitude and height. The latter, conventionally in C{meter} indicates whether the C{center} is above, below or on the surface of the earth model. If C{deltas} is C{None}, the C{center} is I{un}ambigous. Otherwise C{deltas} is a L{LatLon3Tuple}C{(lat, lon, height)} representing the differences between both results from L{pygeodesy.trilaterate3d2} and C{center} is the mean thereof.
@see: Function L{pygeodesy.circin6}, method L{circum3}, U{Incircle <https://MathWorld.Wolfram.com/Incircle.html>} and U{Contact Triangle <https://MathWorld.Wolfram.com/ContactTriangle.html>}. ''' datum=self.datum) # PYCHOK unpack except (AssertionError, TypeError, ValueError) as x: raise _xError(x, point=self, point2=point2, point3=point3)
'''Return the radius and center of the smallest circle I{through} or I{containing} this and two other points.
@arg point2: Second point (C{LatLon}). @arg point3: Third point (C{LatLon}). @kwarg circum: If C{True} return the C{circumradius} and C{circumcenter}, always, ignoring the I{Meeus}' Type I case (C{bool}). @kwarg eps: Tolerance for function L{pygeodesy.trilaterate3d2}.
@return: A L{Circum3Tuple}C{(radius, center, deltas)}. The C{center}, an instance of this (sub-)class, is co-planar with this and the two given points. If C{deltas} is C{None}, the C{center} is I{un}ambigous. Otherwise C{deltas} is a L{LatLon3Tuple}C{(lat, lon, height)} representing the difference between both results from L{pygeodesy.trilaterate3d2} and C{center} is the mean thereof.
@raise ImportError: Package C{numpy} not found, not installed or older than version 1.10.
@raise IntersectionError: Near-concentric, -coincident or -colinear points, incompatible C{Ecef} classes or a trilateration or C{numpy} issue.
@raise TypeError: Invalid B{C{point2}} or B{C{point3}}.
@note: The C{center} is trilaterated in cartesian (ECEF) space and converted back to geodetic lat-, longitude and height. The latter, conventionally in C{meter} indicates whether the C{center} is above, below or on the surface of the earth model. If C{deltas} is C{None}, the C{center} is I{un}ambigous. Otherwise C{deltas} is a L{LatLon3Tuple}C{(lat, lon, height)} representing the difference between both results from L{pygeodesy.trilaterate3d2} and C{center} is the mean thereof.
@see: Function L{pygeodesy.circum3} and methods L{circin6} and L{circum4_}. ''' clas=cs[0].classof, datum=self.datum) # PYCHOK unpack except (AssertionError, TypeError, ValueError) as x: raise _xError(x, point=self, point2=point2, point3=point3, circum=circum)
'''Best-fit a sphere through this and two or more other points.
@arg points: The other points (each a C{LatLon}).
@return: L{Circum4Tuple}C{(radius, center, rank, residuals)} with C{center} an instance of this (sub-)class.
@raise ImportError: Package C{numpy} not found, not installed or older than version 1.10.
@raise NumPyError: Some C{numpy} issue.
@raise TypeError: One of the B{C{points}} invalid.
@raise ValueError: Too few B{C{points}}.
@see: Function L{pygeodesy.circum4_} and L{circum3}. '''
def compassAngle(self, other, adjust=True, wrap=False): # PYCHOK no cover '''DEPRECATED, use method L{compassAngleTo}.''' return self.compassAngleTo(other, adjust=adjust, wrap=wrap)
'''Return the angle from North for the direction vector between this and an other point.
Suitable only for short, non-near-polar vectors up to a few hundred Km or Miles. Use method C{initialBearingTo} for larger distances.
@arg other: The other point (C{LatLon}). @kwarg adjust: Adjust the longitudinal delta by the cosine of the mean latitude (C{bool}). @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes and longitudinal delta (C{bool}).
@return: Compass angle from North (C{degrees360}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@note: Courtesy of Martin Schultz.
@see: U{Local, flat earth approximation <https://www.EdWilliams.org/avform.htm#flat>}. ''' adjust=adjust, wrap=wrap)
'''Compute the distance between this and an other point 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>} formula.
@arg other: The other point (C{LatLon}). @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.cosineAndoyerLambert} and methods L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
'''Compute the distance between this and an other point 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 other: The other point (C{LatLon}). @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.cosineForsytheAndoyerLambert} and methods L{cosineAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
'''Compute the distance between this and an other point using the U{spherical Law of Cosines <https://www.Movable-Type.co.UK/scripts/latlong.html#cosine-law>} formula.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.cosineLaw} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
def datum(self): # PYCHOK no cover '''(INTERNAL) I{Must be overloaded}, see function C{notOverloaded}. ''' notOverloaded(self)
'''Calculate the destination using a I{local} delta from this point.
@arg delta: Local delta to the destination (L{XyzLocal}, L{Enu}, L{Ned} or L{Local9Tuple}). @kwarg LatLon: Optional (geodetic) class to return the destination or C{None}. @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon} is None}.
@return: Destination as a C{B{LatLon}(lat, lon, **B{LatLon_kwds})} instance or if C{B{LatLon} is None}, a L{LatLon3Tuple}C{(lat, lon, height)} respectively L{LatLon4Tuple}C{(lat, lon, height, datum)} depending on whether a C{datum} keyword is un-/specified.
@raise TypeError: Invalid B{C{delta}}, B{C{LatLon}} or B{C{LatLon_kwds}}. ''' t = self._ltp._local2ecef(delta, nine=True) return t.toLatLon(LatLon=LatLon, **_xkwds(LatLon_kwds, name=self.name))
'''(INTERNAL) Helper for methods C{<func>To}. ''' radius=radius, **options)
'''(INTERNAL) Helper for (ellipsoidal) methods C{<func>To}. '''
'''Get the ECEF I{class} (L{EcefKarney}), I{lazily}. '''
'''(INTERNAL) Helper for L{_ecef9} and L{toEcef} (C{callable}). '''
'''(INTERNAL) Helper for L{toCartesian}, L{toEcef} and L{toCartesian} (L{Ecef9Tuple}). '''
def equals(self, other, eps=None): # PYCHOK no cover '''DEPRECATED, use method L{isequalTo}.''' return self.isequalTo(other, eps=eps)
def equals3(self, other, eps=None): # PYCHOK no cover '''DEPRECATED, use method L{isequalTo3}.''' return self.isequalTo3(other, eps=eps)
'''Compute the distance between this and an other point using the U{Equirectangular Approximation / Projection <https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}.
Suitable only for short, non-near-polar distances up to a few hundred Km or Miles. Use method L{haversineTo} or C{distanceTo*} for more accurate and/or larger distances.
See function L{pygeodesy.equirectangular_} for more details, the available B{C{options}} and errors raised.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg options: Optional keyword arguments for function L{pygeodesy.equirectangular}.
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.equirectangular} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, C{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
'''Approximate the C{Euclidian} distance between this and an other point.
See function L{pygeodesy.euclidean} for the available B{C{options}}.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg options: Optional keyword arguments for function L{pygeodesy.euclidean}.
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.euclidean} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
'''Compute the distance between this and an other point 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 other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the major radius of this point's datum/ellipsoid. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@raise ValueError: Invalid B{C{radius}}.
@see: Function L{pygeodesy.flatLocal}/L{pygeodesy.hubeny}, methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatPolarTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo} and U{local, flat Earth approximation<https://www.edwilliams.org/avform.htm#flat>}. '''
'''Compute the distance between this and an other point using the U{polar coordinate flat-Earth<https://WikiPedia.org/wiki/ Geographical_distance#Polar_coordinate_flat-Earth_formula>}formula.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.flatPolar} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{haversineTo}, L{thomasTo} and L{vincentysTo}. '''
'''Compute the intersection of a Line-Of-Sight (los) from this Point-Of-View (pov) with this point's ellipsoid surface.
@kwarg los: Line-Of-Sight, I{direction} to earth (L{Vector3d}) or C{None} to point to the ellipsoid's center. @kwarg earth: The earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}, L{a_f2Tuple} or C{scalar} radius in C{meter}) overriding this point's C{datum} ellipsoid.
@return: The ellipsoid intersection (C{LatLon}) or this very instance if this C{pov's height} is C{0}.
@raise IntersectionError: Null C{pov} or B{C{los}} vector, this C{pov's height} is negative or B{C{los}} points outside the ellipsoid or in an opposite direction.
@raise TypeError: Invalid B{C{los}}.
@see: Function C{hartzell} for further details. ''' raise IntersectionError(pov=self, los=los, height=h, txt=_no_(_height_)) d = self.datum if earth is None else _spherical_datum(earth) r = self.dup(datum=d, height=0, name=self.hartzell.__name__) else:
'''Compute the distance between this and an other point using the U{Haversine<https://www.Movable-Type.co.UK/scripts/latlong.html>} formula.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.haversine} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{thomasTo} and L{vincentysTo}. '''
'''(INTERNAL) Weighted, average height.
@arg other: An other point (C{LatLon}). @kwarg f: Optional fraction (C{float}).
@return: Average, fractional height (C{float}). '''
'''Get the height (C{meter}). '''
'''Set the height (C{meter}).
@raise TypeError: Invalid B{C{height}} C{type}.
@raise ValueError: Invalid B{C{height}}. '''
'''Compute the height above or below and the projection on this datum's ellipsoid surface.
@kwarg earth: A datum, ellipsoid or earth radius I{overriding} this datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}, L{a_f2Tuple} or C{meter}, conventionally). @kwarg normal: If C{True} the projection is the nearest point on the ellipsoid's surface, otherwise the intersection of the radial line to the center and the ellipsoid's surface. @kwarg LatLon: Optional class to return the height and projection (C{LatLon}) or C{None}. @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon} is None}.
@note: Use keyword argument C{height=0} to override C{B{LatLon}.height} to {0} or any other C{scalar}, conventionally in C{meter}.
@return: An instance of B{C{LatLon}} or if C{B{LatLon} is None}, a L{Vector4Tuple}C{(x, y, z, h)} with the I{projection} C{x}, C{y} and C{z} coordinates and height C{h} in C{meter}, conventionally.
@raise TypeError: Invalid B{C{earth}}.
@see: L{Ellipsoid.height4} for more information. ''' else:
'''Return this B{C{height}} as C{str}ing.
@kwarg prec: Number of (decimal) digits, unstripped (C{int}). @kwarg m: Optional unit of the height (C{str}).
@see: Function L{pygeodesy.hstr}. '''
def isantipode(self, other, eps=EPS): # PYCHOK no cover '''DEPRECATED, use method L{isantipodeTo}.''' return self.isantipodeTo(other, eps=eps)
'''Check whether this and an other point are antipodal, on diametrically opposite sides of the earth.
@arg other: The other point (C{LatLon}). @kwarg eps: Tolerance for near-equality (C{degrees}).
@return: C{True} if points are antipodal within the given tolerance, C{False} otherwise. ''' other.lat, other.lon, eps=eps)
'''Check whether this point is ellipsoidal (C{bool} or C{None} if unknown). '''
'''Get C{LatLon} base. ''' return False
'''Compare this point with an other point, I{ignoring} height.
@arg other: The other point (C{LatLon}). @kwarg eps: Tolerance for equality (C{degrees}).
@return: C{True} if both points are identical, I{ignoring} height, C{False} otherwise.
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch of the B{C{other}} and this C{class} or C{type}.
@raise UnitError: Invalid B{C{eps}}.
@see: Method L{isequalTo3}. '''
(self.lat == other.lat and self.lon == other.lon)
'''Compare this point with an other point, I{including} height.
@arg other: The other point (C{LatLon}). @kwarg eps: Tolerance for equality (C{degrees}).
@return: C{True} if both points are identical I{including} height, C{False} otherwise.
@raise TypeError: The B{C{other}} point is not C{LatLon} or mismatch of the B{C{other}} and this C{class} or C{type}.
@see: Method L{isequalTo}. '''
'''Check whether this point is spherical (C{bool} or C{None} if unknown). '''
'''Get the longitude (B{C{radians}}). '''
'''Get the latitude (C{degrees90}). '''
'''Set the latitude (C{str[N|S]} or C{degrees}).
@raise ValueError: Invalid B{C{lat}}. '''
'''Get the lat- and longitude (L{LatLon2Tuple}C{(lat, lon)}). '''
'''Set the lat- and longitude and optionally the height (2- or 3-tuple or comma- or space-separated C{str} of C{degrees90}, C{degrees180} and C{meter}).
@raise TypeError: Height of B{C{latlonh}} not C{scalar} or B{C{latlonh}} not C{list} or C{tuple}.
@raise ValueError: Invalid B{C{latlonh}} or M{len(latlonh)}.
@see: Function L{pygeodesy.parse3llh} to parse a B{C{latlonh}} string into a 3-tuple (lat, lon, h). ''' latlonh = parse3llh(latlonh, height=self.height) else: raise _ValueError(latlonh=latlonh) else:
'''Return this point's lat- and longitude in C{degrees}, rounded.
@kwarg ndigits: Number of (decimal) digits (C{int}).
@return: A L{LatLon2Tuple}C{(lat, lon)}, both C{float} and rounded away from zero.
@note: The C{round}ed values are always C{float}, also if B{C{ndigits}} is omitted. ''' round(self.lon, ndigits), name=self.name)
def latlon_(self, ndigits=0): # PYCHOK no cover '''DEPRECATED, use method L{latlon2}.''' return self.latlon2(ndigits=ndigits)
latlon2round = latlon_ # PYCHOK no cover
'''Get the lat-, longitude and height (L{LatLon3Tuple}C{(lat, lon, height)}). '''
'''Get the longitude (C{degrees180}). '''
'''Set the longitude (C{str[E|W]} or C{degrees}).
@raise ValueError: Invalid B{C{lon}}. ''' _update_all(self) self._lon = lon
'''(INTERNAL) Cache for L{toLtp}. '''
'''Locate the point on a path or polygon closest to this point.
Points are converted to and distances are computed in I{geocentric}, cartesian space.
@arg points: The path or polygon points (C{LatLon}[]). @kwarg closed: Optionally, close the polygon (C{bool}). @kwarg height: Optional height, overriding the height of this and all other points (C{meter}). If C{None}, take the height of points into account for distances. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: A L{NearestOn6Tuple}C{(closest, distance, fi, j, start, end)} with the C{closest}, the C{start} and the C{end} point each an instance of this C{LatLon} and C{distance} in C{meter}, same units as the cartesian axes.
@raise PointsError: Insufficient number of B{C{points}}.
@raise TypeError: Some B{C{points}} or some B{C{points}}' C{Ecef} invalid.
@raise ValueError: Some B{C{points}}' C{Ecef} is incompatible.
@see: Function L{pygeodesy.nearestOn6}. ''' q = _unrollon(p, q)
height=height)
'''(INTERNAL) Get the (C{nvectorBase._N_vector_}) '''
'''Get the latitude (B{C{radians}}). '''
'''Get the lat- and longitude (L{PhiLam2Tuple}C{(phi, lam)}). '''
'''Return this point's lat- and longitude in C{radians}, rounded.
@kwarg ndigits: Number of (decimal) digits (C{int}).
@return: A L{PhiLam2Tuple}C{(phi, lam)}, both C{float} and rounded away from zero.
@note: The C{round}ed values are always C{float}, also if B{C{ndigits}} is omitted. ''' round(self.lam, ndigits), name=self.name)
'''Get the lat-, longitude in C{radians} and height (L{PhiLam3Tuple}C{(phi, lam, height)}). '''
def points(self, points, closed=True): # PYCHOK no cover '''DEPRECATED, use method L{points2}.''' return self.points2(points, closed=closed)
'''Check a path or polygon represented by points.
@arg points: The path or polygon points (C{LatLon}[]) @kwarg closed: Optionally, consider the polygon closed, ignoring any duplicate or closing final B{C{points}} (C{bool}).
@return: A L{Points2Tuple}C{(number, points)}, C{int} and C{list} or C{tuple}.
@raise PointsError: Insufficient number of B{C{points}}.
@raise TypeError: Some B{C{points}} are not C{LatLon}. '''
'''Return a C{PointsIter} iterator.
@arg points: The path or polygon points (C{LatLon}[]) @kwarg loop: Number of loop-back points (non-negative C{int}). @kwarg dedup: Skip duplicate points (C{bool}).
@return: A new C{PointsIter} iterator.
@raise PointsError: Insufficient number of B{C{points}}. '''
'''Return the radii of the C{Circum-}, C{In-}, I{Soddy} and C{Tangent} circles of a (planar) triangle formed by this and two other points.
@arg point2: Second point (C{LatLon}). @arg point3: Third point (C{LatLon}).
@return: L{Radii11Tuple}C{(rA, rB, rC, cR, rIn, riS, roS, a, b, c, s)}.
@raise IntersectionError: Near-coincident or -colinear points.
@raise TypeError: Invalid B{C{point2}} or B{C{point3}}.
@see: Function L{pygeodesy.radii11}, U{Incircle <https://MathWorld.Wolfram.com/Incircle.html>}, U{Soddy Circles <https://MathWorld.Wolfram.com/SoddyCircles.html>} and U{Tangent Circles<https://MathWorld.Wolfram.com/TangentCircles.html>}. ''' except (TypeError, ValueError) as x: raise _xError(x, point=self, point2=point2, point3=point3)
'''(INTERNAL) Get the C{rhumb} for this point's datum or for the earth model or earth B{C{radius}} if not C{None}. ''' _MODS.rhumbx.Rhumb(D, exact=False, name=D.name)
'''Return the azimuth (bearing) of a rhumb line (loxodrome) between this and an other (ellipsoidal) point.
@arg other: The other point (C{LatLon}). @kwarg exact: If C{True}, use the I{exact} L{Rhumb} (C{bool}), default C{False}. @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
@return: Rhumb azimuth (compass C{degrees360}).
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid. ''' outmask=C.AZIMUTH).azi12
'''Return the destination point having travelled the given distance from this point along a rhumb line (loxodrome) at the given azimuth.
@arg distance: Distance travelled (C{meter}, same units as this point's datum (ellipsoid) axes or B{C{radius}}, may be negative. @arg azimuth: Azimuth (bearing) at this point (compass C{degrees}). @kwarg exact: If C{True}, use the I{exact} L{Rhumb} (C{bool}), default C{False}. @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum. @kwarg height: Optional height, overriding the default height (C{meter}).
@return: The destination point (ellipsoidal C{LatLon}).
@raise TypeError: Invalid B{C{radius}}.
@raise ValueError: Invalid B{C{distance}}, B{C{azimuth}}, B{C{radius}} or B{C{height}}. '''
'''Return the distance from this to an other point along a rhumb line (loxodrome).
@arg other: The other point (C{LatLon}). @kwarg exact: If C{True}, use the I{exact} L{Rhumb} (C{bool}), default C{False}. @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum.
@return: Distance (C{meter}, the same units as this point's datum (ellipsoid) axes or B{C{radius}}.
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
@raise ValueError: Invalid B{C{radius}}. ''' outmask=C.DISTANCE).s12
'''Get a rhumb line through this point at a given azimuth or through this and an other point.
@arg azimuth_other: The azimuth of the rhumb line (compass) C{degrees} or the other point (C{LatLon}). @kwarg exact: If C{True}, use the I{exact} L{Rhumb} (C{bool}), default C{False}. @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum. @kwarg name: Optional name (C{str}). @kwarg caps: Optional C{caps}, see L{RhumbLine} C{B{caps}}.
@return: A L{RhumbLine} instance.
@raise TypeError: Invalid B{C{radius}} or BC{C{azimuth_other}} not a C{scalar} nor a C{LatLon}.
@see: Classes L{RhumbLine} and L{Rhumb}, property L{Rhumb.exact} and methods L{Rhumb.DirectLine} and L{Rhumb.InverseLine}. ''' name=name or self.name, **caps) name=name or self.name, **caps) else: raise _TypeError(azimuth_other=a)
height=None, fraction=_0_5): '''Return the (loxodromic) midpoint on the rhumb line between this and an other point.
@arg other: The other point (C{LatLon}). @kwarg exact: If C{True}, use the I{exact} L{Rhumb} (C{bool}), default C{False}. @kwarg radius: Optional earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}), overriding this point's datum. @kwarg height: Optional height, overriding the mean height (C{meter}). @kwarg fraction: Midpoint location from this point (C{scalar}), may be negative or greater than 1.0.
@return: The midpoint at the given B{C{fraction}} along the rhumb line (C{LatLon}).
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
@raise ValueError: Invalid B{C{height}} or B{C{fraction}}. '''
'''Compute the distance between this and an other point using U{Thomas'<https://apps.DTIC.mil/dtic/tr/fulltext/u2/703541.pdf>} formula.
@arg other: The other point (C{LatLon}). @kwarg wrap: Wrap and L{pygeodesy.unrollPI} longitudes (C{bool}).
@return: Distance (C{meter}, same units as the axes of this point's datum ellipsoid).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.thomas} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo} and L{vincentysTo}. '''
def to2ab(self): # PYCHOK no cover '''DEPRECATED, use property L{philam}.''' return self.philam
'''Convert this point to cartesian, I{geocentric} coordinates, also known as I{Earth-Centered, Earth-Fixed} (ECEF).
@kwarg height: Optional height, overriding this point's height (C{meter}, conventionally). @kwarg Cartesian: Optional class to return the geocentric coordinates (C{Cartesian}) or C{None}. @kwarg Cartesian_kwds: Optional, additional B{C{Cartesian}} keyword arguments, ignored if C{B{Cartesian} is None}.
@return: A B{C{Cartesian}} or if B{C{Cartesian}} is C{None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C=0} and C{M} if available.
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}}. '''
'''(INTERNAL) Convert this and 2 other points. ''' self._toCartesianEcef(up=3, point2=point2), self._toCartesianEcef(up=3, point3=point3))
'''(INTERNAL) Convert to cartesian and check Ecef's before and after. ''' if e not in (None, E): # PYCHOK no cover n, _ = name_point.popitem() if i is not None: Fmt.SQUARE(n, i) raise _ValueError(n, e, txt=_incompatible(E.__name__))
'''Convert this point to I{geocentric} coordinates, also known as I{Earth-Centered, Earth-Fixed} (U{ECEF<https://WikiPedia.org/wiki/ECEF>}).
@kwarg height: Optional height, overriding this point's height (C{meter}, conventionally). @kwarg M: Optionally, include the rotation L{EcefMatrix} (C{bool}).
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C=0} and C{M} if available.
@raise EcefError: A C{.datum} or an ECEF issue. ''' self._Ecef_forward(self.lat, self.lon, height=height, M=M)
def to3llh(self, height=None): # PYCHOK no cover '''DEPRECATED, use property L{latlonheight} or C{latlon.to3Tuple(B{height})}.''' return self.latlonheight if height in (None, self.height) else \ self.latlon.to3Tuple(height)
'''Convert this I{geodetic} point to I{local} C{X}, C{Y} and C{Z}.
@kwarg Xyz: Optional class to return C{X}, C{Y} and C{Z} (L{XyzLocal}, L{Enu}, L{Ned}) or C{None}. @kwarg ltp: The I{local tangent plane} (LTP) to use, overriding this point's LTP (L{Ltp}). @kwarg Xyz_kwds: Optional, additional B{C{Xyz}} keyword arguments, ignored if C{B{Xyz} is None}.
@return: An B{C{Xyz}} instance or if C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)} with C{M=None}, always.
@raise TypeError: Invalid B{C{ltp}}. '''
'''Return the I{local tangent plane} (LTP) for this point.
@kwarg Ecef: Optional ECEF I{class} (L{EcefKarney}, ... L{EcefYou}), overriding this point's C{Ecef}. ''' return self._ltp if Ecef in (None, self.Ecef) else _MODS.ltp.Ltp( self, ecef=Ecef(self.datum), name=self.name)
'''Convert this point to C{n-vector} (normal to the earth's surface) components, I{including height}.
@kwarg h: Optional height, overriding this point's height (C{meter}). @kwarg Nvector: Optional class to return the C{n-vector} components (C{Nvector}) or C{None}. @kwarg Nvector_kwds: Optional, additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector} is None}.
@return: A B{C{Nvector}} or an L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector}} is C{None}.
@raise TypeError: Invalid B{C{Nvector}} or B{C{Nvector_kwds}}. ''' ll=self, **Nvector_kwds)
'''Convert this point to a "lat, lon[, +/-height]" string, formatted in the given C{B{form}at}.
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see functions L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}. @kwarg joined: Separator to join the lat-, longitude and heigth strings (C{str} or C{None} or C{NN} for non-joined). @kwarg m: Optional unit of the height (C{str}), use C{None} to exclude height from the returned string. @kwarg prec_sep_s_D_M_S: Optional C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}}, B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}} keyword arguments, see function L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
@return: This point in the specified C{B{form}at}, etc. (C{str} or a 2- or 3-tuple C{(lat_str, lon_str[, height_str])} if C{B{joined}=NN} or C{B{joined}=None}).
@see: Function L{pygeodesy.latDMS} or L{pygeodesy.lonDMS} for more details about keyword arguments C{B{form}at}, C{B{prec}ision}, C{B{sep}arator}, B{C{s_D}}, B{C{s_M}}, B{C{s_S}} and B{C{s_DMS}}.
@example:
>>> LatLon(51.4778, -0.0016).toStr() # 51°28′40″N, 000°00′06″W >>> LatLon(51.4778, -0.0016).toStr(F_D) # 51.4778°N, 000.0016°W >>> LatLon(51.4778, -0.0016, 42).toStr() # 51°28′40″N, 000°00′06″W, +42.00m ''' lonDMS(self.lon, form=form, **prec_sep_s_D_M_S))
'''Convert this point to C{n-vector} (normal to the earth's surface) components, I{ignoring height}.
@kwarg Vector: Optional class to return the C{n-vector} components (L{Vector3d}) or C{None}. @kwarg Vector_kwds: Optional, additional B{C{Vector}} keyword arguments, ignored if C{B{Vector} is None}.
@return: A B{C{Vector}} or a L{Vector3Tuple}C{(x, y, z)} if B{C{Vector}} is C{None}.
@raise TypeError: Invalid B{C{Vector}} or B{C{kwds}}.
@note: These are C{n-vector} x, y and z components, I{NOT} geocentric (ECEF) x, y and z coordinates! '''
'''Convert this point to C{n-vector} (normal to the earth's surface) components, I{ignoring height}.
@return: Unit vector (L{Vector3d}).
@note: These are C{n-vector} x, y and z components, I{NOT} geocentric (ECEF) x, y and z coordinates! '''
def to3xyz(self): # PYCHOK no cover '''DEPRECATED, use property L{xyz} or method L{toNvector}, L{toVector}, L{toVector3d} or perhaps (geocentric) L{toEcef}.''' return self.xyz # self.toVector()
'''(INTERNAL) Cache for L{toVector3d}. '''
'''(INTERNAL) Cache for L{toVector}. '''
'''Compute the distance between this and an other point using U{Vincenty's<https://WikiPedia.org/wiki/Great-circle_distance>} spherical formula.
@arg other: The other point (C{LatLon}). @kwarg radius: Mean earth radius (C{meter}) or C{None} for the mean radius of this point's datum ellipsoid. @kwarg wrap: Wrap and L{pygeodesy.unroll180} longitudes (C{bool}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise TypeError: The B{C{other}} point is not C{LatLon}.
@see: Function L{pygeodesy.vincentys} and methods L{cosineAndoyerLambertTo}, L{cosineForsytheAndoyerLambertTo}, L{cosineLawTo}, C{distanceTo*}, L{equirectangularTo}, L{euclideanTo}, L{flatLocalTo}/L{hubenyTo}, L{flatPolarTo}, L{haversineTo} and L{thomasTo}. '''
'''Get the C{n-vector} X, Y and Z components (L{Vector3Tuple}C{(x, y, z)})
@note: These are C{n-vector} x, y and z components, I{NOT} geocentric (ECEF) x, y and z coordinates! '''
'''Get the C{n-vector} X, Y, Z and H components (L{Vector4Tuple}C{(x, y, z, h)})
@note: These are C{n-vector} x, y and z components, I{NOT} geocentric (ECEF) x, y and z coordinates! '''
'''(INTERNAL) Compare point lat-/lon without type. ''' abs(point1.lon - point2.lon)) < eps
radius=R_M, wrap=False): '''(INTERNAL) Trilaterate three points by area overlap or by perimeter intersection of three circles.
@note: The B{C{radius}} is only needed for both the n-vectorial and sphericalTrigonometry C{LatLon.distanceTo} methods and silently ignored by the C{ellipsoidalExact} C{-GeodSolve}, C{-Karney} and C{-Vincenty.LatLon.distanceTo} methods. '''
c = c1 else: # nearest point on radical
else: # check intersection
except IntersectionError as x: if _concentric_ in str(x): # XXX ConcentricError? pc += 1
# ... or for a single trilaterated result, # min *is* max, min- *is* maxPoint and n=1
r, p = min((r1, p1), (r2, p2), (r3, p3)) m = max(r1, r2, r3) # ... return "smallest" point twice, the smallest # and largest distance and n=0 for concentric return Trilaterate5Tuple(float(r), p, float(m), p, 0)
raise IntersectionError(area=area, eps=eps, wrap=wrap, txt=t)
# **) 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. |