Coverage for /opt/obspy/update-docs/src/obspy/obspy/core/util/geodetics/base : 84%

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 -*- Various geodetic utilities for ObsPy.
:copyright: The ObsPy Development Team (devs@obspy.org) :license: GNU Lesser General Public License, Version 3 (http://www.gnu.org/copyleft/lesser.html) """
""" Vincenty Inverse Solution of Geodesics on the Ellipsoid.
Computes the distance between two geographic points on the WGS84 ellipsoid and the forward and backward azimuths between these points.
:param lat1: Latitude of point A in degrees (positive for northern, negative for southern hemisphere) :param lon1: Longitude of point A in degrees (positive for eastern, negative for western hemisphere) :param lat2: Latitude of point B in degrees (positive for northern, negative for southern hemisphere) :param lon2: Longitude of point B in degrees (positive for eastern, negative for western hemisphere) :return: (Great circle distance in m, azimuth A->B in degrees, azimuth B->A in degrees) :raises: This method may have no solution between two nearly antipodal points; an iteration limit traps this case and a ``StopIteration`` exception will be raised.
.. note:: This code is based on an implementation incorporated in Matplotlib Basemap Toolkit 0.9.5 http://sourceforge.net/projects/\ matplotlib/files/matplotlib-toolkits/basemap-0.9.5/ (matplotlib/toolkits/basemap/greatcircle.py)
Algorithm from Geocentric Datum of Australia Technical Manual.
* http://www.icsm.gov.au/gda/gdatm/index.html * http://www.icsm.gov.au/gda/gdatm/gdav2.3.pdf, pp. 15
It states::
Computations on the Ellipsoid
There are a number of formulae that are available to calculate accurate geodetic positions, azimuths and distances on the ellipsoid.
Vincenty's formulae (Vincenty, 1975) may be used for lines ranging from a few cm to nearly 20,000 km, with millimetre accuracy. The formulae have been extensively tested for the Australian region, by comparison with results from other formulae (Rainsford, 1955 & Sodano, 1965).
* Inverse problem: azimuth and distance from known latitudes and longitudes * Direct problem: Latitude and longitude from known position, azimuth and distance. """ # Check inputs lon1 += 360 lon2 -= 360
# Data on the WGS84 reference ellipsoid:
return 0.0, 0.0, 0.0
# convert latitudes and longitudes to radians:
# Iterate until no significant change in dlon or iterlimit has been # reached (http://www.movable-type.co.uk/scripts/latlong-vincenty.html) abs((last_dlon - dlon) / dlon) > 1.0e-9): pow((math.cos(U1) * math.sin(U2) - math.sin(U1) * \ math.cos(U2) * math.cos(dlon)), 2) math.cos(U2) * math.cos(dlon) math.sin(sigma) math.sin(U2) / pow(math.cos(alpha), 2)) (4 + f * (4 - 3 * pow(math.cos(alpha), 2))) math.sin(sigma) * (Cos2sigma_m + C * math.cos(sigma) * \ (-1 + 2 * pow(Cos2sigma_m, 2))))
(Cos_sigma * (-1 + 2 * pow(Cos2sigma_m, 2)) - (B / 6) * \ Cos2sigma_m * (-3 + 4 * sqr_sin_sigma) * \ (-3 + 4 * pow(Cos2sigma_m, 2))))
(math.cos(U1) * math.sin(U2) - math.sin(U1) * math.cos(U2) * \ math.cos(dlon))) (-math.sin(U1) * math.cos(U2) + math.cos(U1) * math.sin(U2) * \ math.cos(dlon))) # iteration limit reached # usually "math domain error"
alpha12 = alpha12 - (2.0 * math.pi)
alpha21 = alpha21 + (2.0 * math.pi) alpha21 = alpha21 - (2.0 * math.pi)
# convert to degrees:
""" Computes the distance between two geographic points on the WGS84 ellipsoid and the forward and backward azimuths between these points.
:param lat1: Latitude of point A in degrees (positive for northern, negative for southern hemisphere) :param lon1: Longitude of point A in degrees (positive for eastern, negative for western hemisphere) :param lat2: Latitude of point B in degrees (positive for northern, negative for southern hemisphere) :param lon2: Longitude of point B in degrees (positive for eastern, negative for western hemisphere) :return: (Great circle distance in m, azimuth A->B in degrees, azimuth B->A in degrees)
.. note:: This function will check if you have installed the Python module `geographiclib <http://geographiclib.sf.net>`_ - a very fast module for converting between geographic, UTM, UPS, MGRS, and geocentric coordinates, for geoid calculations, and for solving geodesic problems. Otherwise the locally implemented Vincenty's Inverse formulae (:func:`obspy.core.util.geodetics.calcVincentyInverse`) is used which has known limitations for two nearly antipodal points and is ca. 4x slower. """ # try using geographiclib result = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2) azim = result['azi1'] if azim < 0: azim += 360 bazim = result['azi2'] + 180 return (result['s12'], azim, bazim) except ImportError: pass raise StopIteration "The currently used Vincenty's Inverse formulae " + \ "has known limitations for two nearly antipodal points. " + \ "Install the Python module 'geographiclib' to solve this issue." return (20004314.5, 0.0, 0.0) except ValueError, e: raise e
""" Convenience function to convert kilometers to degrees assuming a perfectly spherical Earth.
:type kilometer: float :param kilometer: Distance in kilometers :type radius: int, optional :param radius: Radius of the Earth used for the calculation. :rtype: float :return: Distance in degrees as a floating point number.
.. rubric:: Example
>>> from obspy.core.util import kilometer2degrees >>> kilometer2degrees(300) 2.6979648177561915 """
""" Convenience function to calculate the great distance between two points on a spherical Earth.
This method uses the Vincenty formula in the special case of a spherical Earth. For more accurate values use the geodesic distance calculations of geopy (http://code.google.com/p/geopy/).
:type lat1: float :param lat1: Latitude of point 1 in degrees :type long1: float :param long1: Longitude of point 1 in degrees :type lat2: float :param lat2: Latitude of point 2 in degrees :type long2: float :param long2: Longitude of point 2 in degrees :rtype: float :return: Distance in degrees as a floating point number.
.. rubric:: Example
>>> from obspy.core.util import locations2degrees >>> locations2degrees(5, 5, 10, 10) 7.0397014191753815 """ # Convert to radians. math.sin(long_diff)) ** 2 + (math.cos(lat1) * math.sin(lat2) - \ math.sin(lat1) * math.cos(lat2) * math.cos(long_diff)) ** 2), math.sin(lat1) * math.sin(lat2) + math.cos(lat1) * math.cos(lat2) * \ math.cos(long_diff)))
if __name__ == '__main__': import doctest doctest.testmod(exclude_empty=True) |