Coverage for pygeodesy/sphericalBase.py : 95%

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 -*-
C{LatLonSphericalBase} for L{sphericalNvector} and L{sphericalTrigonometry}.
A pure Python implementation of geodetic (lat-/longitude) functions, transcoded in part from JavaScript originals by I{(C) Chris Veness 2011-2016} and published under the same MIT Licence**, see U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}. ''' # make sure int/int division yields float quotient, see .basics
# from pygeodesy.basics import map1 # from .nvectorBase _umod_360, isnear0, isnon0, _0_0, \ _0_5, _1_0, _180_0 # from pygeodesy.errors import IntersectionError # from .latlonBase _distant_, _exceed_PI_radians_, _name_, \ _near_, _radius_, _too_ _trilaterate5 # PYCHOK passed # from pygeodesy.namedTuples import Bearing2Tuple # from .cartesianBase property_RO, _update_all Scalar_ sincos2, tanPI_2_2, wrap360, wrapPI
'''(INTERNAL) Return the angular distance in C{radians}.
@raise UnitError: Invalid B{C{distance}} or B{C{radius}}. '''
'''(INTERNAL) Convert radii to radians. '''
raise IntersectionError(rad1=rad1, rad2=rad2, txt=_exceed_PI_radians_)
'''(INTERNAL) Base class for spherical C{Cartesian}s. '''
'''Compute the intersection points of two circles each defined by a center point and a radius.
@arg rad1: Radius of the this circle (C{meter} or C{radians}, see B{C{radius}}). @arg other: Center of the other circle (C{Cartesian}). @arg rad2: Radius of the other circle (C{meter} or C{radians}, see B{C{radius}}). @kwarg radius: Mean earth radius (C{meter} or C{None} if both B{C{rad1}} and B{C{rad2}} are given in C{radians}).
@return: 2-Tuple of the intersection points, each C{Cartesian}. The intersection points are the same C{Cartesian} instance for abutting circles, aka I{radical center}.
@raise IntersectionError: Concentric, antipodal, invalid or non-intersecting circles.
@raise TypeError: If B{C{other}} is not C{Cartesian}.
@raise ValueError: Invalid B{C{rad1}}, B{C{rad2}} or B{C{radius}}.
@see: U{Calculating intersection of two Circles <https://GIS.StackExchange.com/questions/48937/ calculating-intersection-of-two-circles>} and method or function C{trilaterate3d2}. ''' raise ValueError(_near_(_concentric_)) x2.times((c2 - q * c1) / q1)) raise ValueError(_too_(_distant_)) except ValueError as x: raise IntersectionError(center=self, rad1=rad1, other=other, rad2=rad2, txt=str(x)) else: # abutting circles x1 = x2 = x0
_xattrs(x2, self, _datum_, _name_))
'''(INTERNAL) Base class for spherical C{LatLon}s. '''
'''Create a spherical C{LatLon} point frome the given lat-, longitude and height on the given datum.
@arg lat: Latitude (C{degrees} or DMS C{[N|S]}). @arg lon: Longitude (C{degrees} or DMS C{str[E|W]}). @kwarg height: Optional elevation (C{meter}, the same units as the datum's half-axes). @kwarg datum: Optional, spherical datum to use (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}, L{a_f2Tuple}) or C{scalar} earth radius). @kwarg name: Optional name (string).
@raise TypeError: If B{C{datum}} invalid or not not spherical.
@example:
>>> p = LatLon(51.4778, -0.0016) # height=0, datum=Datums.WGS84 ''' self.datum = datum
'''Return the initial and final bearing (forward and reverse azimuth) from this to an other point.
@arg other: The other point (C{LatLon}). @kwarg wrap: Wrap and unroll longitudes (C{bool}). @kwarg raiser: Optionally, raise L{CrossError} (C{bool}).
@return: A L{Bearing2Tuple}C{(initial, final)}.
@raise TypeError: The B{C{other}} point is not spherical.
@see: Methods C{initialBearingTo} and C{finalBearingTo}. ''' # .initialBearingTo is inside .-Nvector and .-Trigonometry
'''Get this point's datum (L{Datum}). '''
'''Set this point's datum I{without conversion} (L{Datum}, L{Ellipsoid}, L{Ellipsoid2}, L{a_f2Tuple}) or C{scalar} spherical earth radius).
@raise TypeError: If B{C{datum}} invalid or not not spherical. '''
'''Return the final bearing (reverse azimuth) from this to an other point.
@arg other: The other point (spherical C{LatLon}). @kwarg wrap: Wrap and unroll longitudes (C{bool}). @kwarg raiser: Optionally, raise L{CrossError} (C{bool}).
@return: Final bearing (compass C{degrees360}).
@raise TypeError: The B{C{other}} point is not spherical.
@example:
>>> p = LatLon(52.205, 0.119) >>> q = LatLon(48.857, 2.351) >>> b = p.finalBearingTo(q) # 157.9 '''
# final bearing is the reverse of the other, initial one; # .initialBearingTo is inside .-Nvector and .-Trigonometry
'''Return the maximum latitude reached when travelling on a great circle on given bearing from this point based on Clairaut's formula.
The maximum latitude is independent of longitude and the same for all points on a given latitude.
Negate the result for the minimum latitude (on the Southern hemisphere).
@arg bearing: Initial bearing (compass C{degrees360}).
@return: Maximum latitude (C{degrees90}).
@raise ValueError: Invalid B{C{bearing}}. '''
'''Return the minimum latitude reached when travelling on a great circle on given bearing from this point.
@arg bearing: Initial bearing (compass C{degrees360}).
@return: Minimum latitude (C{degrees90}).
@see: Method L{maxLat} for more details.
@raise ValueError: Invalid B{C{bearing}}. '''
'''Parse a string representing a similar, spherical C{LatLon} point, consisting of C{"lat, lon[, height]"}.
@arg strllh: Lat, lon and optional height (C{str}), see function L{pygeodesy.parse3llh}. @kwarg height: Optional, default height (C{meter}). @kwarg sep: Optional separator (C{str}). @kwarg name: Optional instance name (C{str}), overriding this name.
@return: The similar point (spherical C{LatLon}).
@raise ParseError: Invalid B{C{strllh}}. '''
'''(INTERNAL) Get this sphere's radius. '''
'''(INTERNAL) Rhumb_ helper function.
@arg other: The other point (spherical C{LatLon}). '''
# if |db| > 180 take shorter rhumb # line across the anti-meridian # on Mercator projection, longitude distances shrink # by latitude; the 'stretch factor' q becomes ill- # conditioned along E-W line (0/0); use an empirical # tolerance to avoid it
'''Return the azimuth (bearing) of a rhumb line (loxodrome) between this and an other (spherical) point.
@arg other: The other point (spherical C{LatLon}). @kwarg radius: Earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}). @kwarg exact: If C{True}, use class L{Rhumb} (C{bool}), default C{False} for backward compatibility.
@return: Rhumb line azimuth (compass C{degrees180}).
@raise TypeError: The B{C{other}} point is incompatible or B{C{radius}} is invalid.
@example:
>>> p = LatLon(51.127, 1.338) >>> q = LatLon(50.964, 1.853) >>> b = p.rhumbBearingTo(q) # 116.7 ''' else:
'''DEPRECATED, use method C{.rhumbAzimuthTo}.'''
'''Return the destination point having travelled the given distance from this point along a rhumb line (loxodrome) at the given bearing.
@arg distance: Distance travelled (C{meter}, same units as B{C{radius}}), may be negative if C{B{exact}=True}. @arg bearing: Bearing (azimuth) at this point (compass C{degrees360}). @kwarg radius: Earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}) if C{B{exact}=True}. @kwarg height: Optional height, overriding the default height (C{meter}, same unit as B{C{radius}}). @kwarg exact: If C{True}, use class L{Rhumb} (C{bool}), default C{False} for backward compatibility.
@return: The destination point (spherical C{LatLon}).
@raise ValueError: Invalid B{C{distance}}, B{C{bearing}}, B{C{radius}} or B{C{height}}.
@example:
>>> p = LatLon(51.127, 1.338) >>> q = p.rhumbDestination(40300, 116.7) # 50.9642°N, 001.8530°E ''' radius=radius, height=height) else: # radius=None from .rhumbMidpointTo else: d = _spherical_datum(radius, raiser=_radius_) # spherical only r = d.ellipsoid.equatoradius
# normalize latitude if past pole a2 = PI - a2 a2 = -PI - a2
# q becomes ill-conditioned on E-W course 0/0
'''Return the distance from this to an other point along a rhumb line (loxodrome).
@arg other: The other point (spherical C{LatLon}). @kwarg radius: Earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}) if C{B{exact}=True}. @kwarg exact: If C{True}, use class L{Rhumb} (C{bool}), default C{False} for backward compatibility.
@return: Distance (C{meter}, the same units as B{C{radius}} or C{radians} if B{C{radius}} is C{None}).
@raise TypeError: The B{C{other}} point is incompatible.
@raise ValueError: Invalid B{C{radius}}.
@example:
>>> p = LatLon(51.127, 1.338) >>> q = LatLon(50.964, 1.853) >>> d = p.rhumbDistanceTo(q) # 403100 ''' r = r / self._radius # /= chokes PyChecker else: # see <https://www.EdWilliams.org/avform.htm#Rhumb>
exact=False, fraction=_0_5): '''Return the (loxodromic) midpoint on the rhumb line between this and an other point.
@arg other: The other point (spherical LatLon). @kwarg height: Optional height, overriding the mean height (C{meter}). @kwarg radius: Optional mean earth radius (C{meter}), overriding the default C{R_M}. @kwarg radius: Earth radius (C{meter}) or earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}). @kwarg exact: If C{True}, use class L{Rhumb} (C{bool}), default C{False} for backward compatibility. @kwarg fraction: Midpoint location from this point (C{scalar}), may negative if C{B{exact}=True}.
@return: The (mid)point at the given B{C{fraction}} along the rhumb line (spherical C{LatLon}).
@raise TypeError: The B{C{other}} point is incompatible.
@raise ValueError: Invalid B{C{height}} or B{C{fraction}}
@example:
>>> p = LatLon(51.127, 1.338) >>> q = LatLon(50.964, 1.853) >>> m = p.rhumb_midpointTo(q) >>> m.toStr() # '51.0455°N, 001.5957°E' ''' radius=radius, height=height, fraction=fraction)
else: # for backward compatibility # see <https://MathForum.org/library/drmath/view/51822.html> b1 += PI2 # crossing anti-meridian
-b2, b1, b2 - b1) / f
_spherical_datum(radius, name=self.name, raiser=_radius_)
'''Convert this point to C{Nvector} components, I{including height}.
@kwarg Nvector_kwds: Optional, additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector} is None}.
@return: An B{C{Nvector}} or a 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}}. '''
'''Convert this point to a I{WM} coordinate.
@kwarg radius: Optional earth radius (C{meter}).
@return: The WM coordinate (L{Wm}).
@see: Function L{pygeodesy.toWm} in module L{webmercator} for details. '''
# **) 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. |