Module pymap3d.haversine
Compute angular separation in the sky using haversine
Note:
decimal points on constants made 0 difference in %timeit
execution time
The Meeus algorithm is about 9.5% faster than Astropy/Vicenty on my PC, and gives virtually identical result within double precision arithmetic limitations
Source code
"""
Compute angular separation in the sky using haversine
Note:
decimal points on constants made 0 difference in `%timeit` execution time
The Meeus algorithm is about 9.5% faster than Astropy/Vicenty on my PC,
and gives virtually identical result
within double precision arithmetic limitations
"""
try:
from numpy import cos, arcsin, sqrt, radians, degrees
except ImportError:
from math import cos, sqrt, radians, degrees, asin as arcsin
try:
from astropy.coordinates.angle_utilities import angular_separation
except ImportError:
angular_separation = None
__all__ = ["anglesep", "anglesep_meeus", "haversine"]
def anglesep_meeus(lon0: float, lat0: float, lon1: float, lat1: float, deg: bool = True) -> float:
"""
Parameters
----------
lon0 : float
longitude of first point
lat0 : float
latitude of first point
lon1 : float
longitude of second point
lat1 : float
latitude of second point
deg : bool, optional
degrees input/output (False: radians in/out)
Returns
-------
sep_rad : float
angular separation
Meeus p. 109
from "Astronomical Algorithms" by Jean Meeus Ch. 16 p. 111 (16.5)
gives angular distance in degrees between two rightAscension,Declination
points in the sky. Neglecting atmospheric effects, of course.
Meeus haversine method is stable all the way to exactly 0 deg.
either the arrays must be the same size, or one of them must be a scalar
"""
if deg:
lon0 = radians(lon0)
lat0 = radians(lat0)
lon1 = radians(lon1)
lat1 = radians(lat1)
sep_rad = 2 * arcsin(sqrt(haversine(lat0 - lat1) + cos(lat0) * cos(lat1) * haversine(lon0 - lon1)))
return degrees(sep_rad) if deg else sep_rad
def anglesep(lon0: float, lat0: float, lon1: float, lat1: float, deg: bool = True) -> float:
"""
Parameters
----------
lon0 : float
longitude of first point
lat0 : float
latitude of first point
lon1 : float
longitude of second point
lat1 : float
latitude of second point
deg : bool, optional
degrees input/output (False: radians in/out)
Returns
-------
sep_rad : float
angular separation
For reference, this is from astropy astropy/coordinates/angle_utilities.py
Angular separation between two points on a sphere.
"""
if angular_separation is None:
raise ImportError("angledist requires AstroPy. Try angledis_meeus")
if deg:
lon0 = radians(lon0)
lat0 = radians(lat0)
lon1 = radians(lon1)
lat1 = radians(lat1)
sep_rad = angular_separation(lon0, lat0, lon1, lat1)
return degrees(sep_rad) if deg else sep_rad
def haversine(theta: float) -> float:
"""
Compute haversine
Parameters
----------
theta : float
angle (radians)
Results
-------
htheta : float
haversine of `theta`
https://en.wikipedia.org/wiki/Haversine
Meeus p. 111
"""
return (1 - cos(theta)) / 2.0
Functions
def anglesep(lon0, lat0, lon1, lat1, deg=True)
-
Parameters
lon0
:float
- longitude of first point
lat0
:float
- latitude of first point
lon1
:float
- longitude of second point
lat1
:float
- latitude of second point
deg
:bool
, optional- degrees input/output (False: radians in/out)
Returns
sep_rad
:float
- angular separation
For
reference
,this
is
from
astropy
astropy
/coordinates
/angle_utilities.py
Angular separation between two points on a sphere.
Source code
def anglesep(lon0: float, lat0: float, lon1: float, lat1: float, deg: bool = True) -> float: """ Parameters ---------- lon0 : float longitude of first point lat0 : float latitude of first point lon1 : float longitude of second point lat1 : float latitude of second point deg : bool, optional degrees input/output (False: radians in/out) Returns ------- sep_rad : float angular separation For reference, this is from astropy astropy/coordinates/angle_utilities.py Angular separation between two points on a sphere. """ if angular_separation is None: raise ImportError("angledist requires AstroPy. Try angledis_meeus") if deg: lon0 = radians(lon0) lat0 = radians(lat0) lon1 = radians(lon1) lat1 = radians(lat1) sep_rad = angular_separation(lon0, lat0, lon1, lat1) return degrees(sep_rad) if deg else sep_rad
def anglesep_meeus(lon0, lat0, lon1, lat1, deg=True)
-
Parameters
lon0
:float
- longitude of first point
lat0
:float
- latitude of first point
lon1
:float
- longitude of second point
lat1
:float
- latitude of second point
deg
:bool
, optional- degrees input/output (False: radians in/out)
Returns
sep_rad
:float
- angular separation
Meeus
p.
109
from
"Astronomical
Algorithms"
by
Jean
Meeus
Ch.
16
p.
111
(16.5
)gives
angular
distance
in
degrees
between
two
rightAscension
,Declination
points in the sky. Neglecting atmospheric effects, of course.
Meeus haversine method is stable all the way to exactly 0 deg.
either
the
arrays
must
be
the
same
size
, orone
ofthem
must
be
a
scalar
Source code
def anglesep_meeus(lon0: float, lat0: float, lon1: float, lat1: float, deg: bool = True) -> float: """ Parameters ---------- lon0 : float longitude of first point lat0 : float latitude of first point lon1 : float longitude of second point lat1 : float latitude of second point deg : bool, optional degrees input/output (False: radians in/out) Returns ------- sep_rad : float angular separation Meeus p. 109 from "Astronomical Algorithms" by Jean Meeus Ch. 16 p. 111 (16.5) gives angular distance in degrees between two rightAscension,Declination points in the sky. Neglecting atmospheric effects, of course. Meeus haversine method is stable all the way to exactly 0 deg. either the arrays must be the same size, or one of them must be a scalar """ if deg: lon0 = radians(lon0) lat0 = radians(lat0) lon1 = radians(lon1) lat1 = radians(lat1) sep_rad = 2 * arcsin(sqrt(haversine(lat0 - lat1) + cos(lat0) * cos(lat1) * haversine(lon0 - lon1))) return degrees(sep_rad) if deg else sep_rad
def haversine(theta)
-
Compute haversine
Parameters
theta
:float
- angle (radians)
Results
htheta
:float
- haversine of
theta
https://en.wikipedia.org/wiki/Haversine Meeus p. 111
Source code
def haversine(theta: float) -> float: """ Compute haversine Parameters ---------- theta : float angle (radians) Results ------- htheta : float haversine of `theta` https://en.wikipedia.org/wiki/Haversine Meeus p. 111 """ return (1 - cos(theta)) / 2.0