search
[last updated: 2022-03-02]
go to: GPS module
go to: GPS module function test
go to: derivation from wikipedia
-----
--------------------------------------------------
// Utility function for
// converting degrees to radians
long double toRadians(const long double °ree)
{
// cmath library in C++
// defines the constant
// M_PI as the value of
// pi accurate to 1e-30
long double one_deg = (M_PI) / 180;
return (one_deg * degree);
}
long double distance(long double lat1, long double long1,
long double lat2, long double long2)
{
// Convert the latitudes
// and longitudes
// from degree to radians.
lat1 = toRadians(lat1);
long1 = toRadians(long1);
lat2 = toRadians(lat2);
long2 = toRadians(long2);
// Haversine Formula
long double dlong = long2 - long1;
long double dlat = lat2 - lat1;
long double ans = pow(sin(dlat / 2), 2) +
cos(lat1) * cos(lat2) *
pow(sin(dlong / 2), 2);
ans = 2 * asin(sqrt(ans));
// Radius of Earth in
// Kilometers, R = 6371
// Use R = 3956 for miles
long double R = 6371;
// Calculate the result
ans = ans * R;
return ans;
}
// Driver Code
int main()
{
long double lat1 = 53.32055555555556;
long double long1 = -1.7297222222222221;
long double lat2 = 53.31861111111111;
long double long2 = -1.6997222222222223;
// call the distance function
cout << setprecision(15) << fixed;
cout << distance(lat1, long1,
lat2, long2) << " K.M";
return 0;
}
// This code is contributed
// by Aayush Chaturvedi
----------------------------------------------------
#include
#include "haversine.h"
#define d2r (M_PI / 180.0)
//calculate haversine distance for linear distance
double haversine_km(double lat1, double long1, double lat2, double long2)
{
double dlong = (long2 - long1) * d2r;
double dlat = (lat2 - lat1) * d2r;
double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
double c = 2 * atan2(sqrt(a), sqrt(1-a));
double d = 6367 * c;
return d;
}
double haversine_mi(double lat1, double long1, double lat2, double long2)
{
double dlong = (long2 - long1) * d2r;
double dlat = (lat2 - lat1) * d2r;
double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
double c = 2 * atan2(sqrt(a), sqrt(1-a));
double d = 3956 * c;
return d;
}
------------------------------------------------------------------
TL;DR - By making a few geometric assumptions, the Haversine formula provies an exceptionally simple way of calculating the distance between two latitude/longitude pairs. This tutorial will show you how to implement your own version in Python.
A lot of my posts recently have focused on the analysis of spatial data coming from either the GPS on my phone (collected through Strava) or geo-tagged tweets. Because of this I ended up writing my own Python module for calculating the distance between two latitude/longitude pairs. This is accomplished using the Haversine formula. While more accurate methods exist for calculating the distance between two points on earths surface, the Haversine formula and Python implementation couldn’t be any simpler. Below is a breakdown of the Haversine formula.
Haversine:
a=sin2(Δϕ2)+cos(ϕ1)⋅cos(ϕ2)⋅sin2(Δλ2) a=\sin^2\left(\frac{\Delta\phi}{2}\right) +\cos(\phi_1)\cdot\cos(\phi_2)\cdot\sin^2\left(\frac{\Delta\lambda}{2}\right)a=sin2(2Δϕ)+cos(ϕ1)⋅cos(ϕ2)⋅sin2(2Δλ)
With:
c=2⋅arctan2(a,1−a) c=2\cdot arctan2\left(\sqrt{a},\sqrt{1-a}\right) c=2⋅arctan2(a
,1−a
)
and:
d=R⋅c d=R\cdot c d=R⋅c
Where:
ϕ \phi ϕ = latitude
λ \lambda λ = longitude
R R R = 6371 (Earth's mean radius in km)
Much of Haverines’ simplicity comes from the underlying assumption that Earth is a perfect sphere (which it isn’t…). Because of this, it can lead to errors of up to 0.5%. More accurate methods exist but at the expense of computational complexity. Below is the Python implementation:
#------------------------------------------------------------------------------+
#
# Nathan A. Rooy
# Haversine Formula
# June, 2016
#
#------------------------------------------------------------------------------+
import math
class Haversine:
'''
use the haversine class to calculate the distance between
two lon/lat coordnate pairs.
output distance available in kilometers, meters, miles, and feet.
example usage: Haversine([lon1,lat1],[lon2,lat2]).feet
'''
def __init__(self,coord1,coord2):
lon1,lat1=coord1
lon2,lat2=coord2
R=6371000 # radius of Earth in meters
phi_1=math.radians(lat1)
phi_2=math.radians(lat2)
delta_phi=math.radians(lat2-lat1)
delta_lambda=math.radians(lon2-lon1)
a=math.sin(delta_phi/2.0)**2+\
math.cos(phi_1)*math.cos(phi_2)*\
math.sin(delta_lambda/2.0)**2
c=2*math.atan2(math.sqrt(a),math.sqrt(1-a))
self.meters=R*c # output distance in meters
self.km=self.meters/1000.0 # output distance in kilometers
self.miles=self.meters*0.000621371 # output distance in miles
self.feet=self.miles*5280 # output distance in feet
if __name__ == "__Haversine__":
main()
Example usage:
>>> import haversine
>>> Haversine([-84.412977,39.152501],[-84.412946,39.152505]).feet
8.890493621837097
>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).feet
8.890493621837097
>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).km
0.0027098232942902385
>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).miles
0.00168380561019642
Note haversine script accepts the coordinates in both tuple “()” and list “[]” form. Additionally, the script can be downloaded from my GitHub located (here).
home page iconabout page iconrss page icon
© Nathan A. Rooy.
Built with Hugo. Powered by GitHub
------------------------------------------------------
.
.
.
eof