forked from GPSBabel/gpsbabel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlatlng.cc
73 lines (68 loc) · 2.72 KB
/
latlng.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// -*- C++ -*-
// $Id: latlng.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
//------------------------------------------------------------------------
//
// Copyright (C) 2009 S. Khai Mong <[email protected]>.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
//------------------------------------------------------------------------
#include "latlng.h"
#include <cmath>
// copied from the web somewhere.
static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
/** @brief Computes the arc, in radian, between two WGS-84 positions.
*
* The result is equal to <code>Distance(from,to)/EARTH_RADIUS_IN_METERS</code>
* <code>= 2*asin(sqrt(h(d/EARTH_RADIUS_IN_METERS )))</code>
*
* where:<ul>
* <li>d is the distance in meters between 'from' and 'to' positions.</li>
* <li>h is the haversine function: <code>h(x)=sin²(x/2)</code></li>
* </ul>
*
* The haversine formula gives:
* <code>h(d/R) = h(from.lat-to.lat)+h(from.lon-to.lon)+cos(from.lat)*cos(to.lat)</code>
*
* @sa http://en.wikipedia.org/wiki/Law_of_haversines
*/
static double ArcInRadians(const LatLng& from, const LatLng& to)
{
double latitudeArc = (from.lat() - to.lat()) * DEG_TO_RAD;
double longitudeArc = (from.lng() - to.lng()) * DEG_TO_RAD;
double latitudeH = sin(latitudeArc * 0.5);
latitudeH *= latitudeH;
double longitudeH = sin(longitudeArc * 0.5);
longitudeH *= longitudeH;
double tmp = cos(from.lat()*DEG_TO_RAD) * cos(to.lat()*DEG_TO_RAD);
return 2.0 * asin(sqrt(latitudeH + tmp*longitudeH));
}
/** @brief Computes the distance, in meters, between two WGS-84 positions.
*
* The result is equal to <code>EARTH_RADIUS_IN_METERS*ArcInRadians(from,to)</code>
*
* @sa ArcInRadians
*/
static double DistanceInMeters(const LatLng& from, const LatLng& to)
{
return EARTH_RADIUS_IN_METERS*ArcInRadians(from, to);
}
//------------------------------------------------------------------------
double LatLng::haversineDistance(const LatLng& other) const
{
return DistanceInMeters(*this, other);
}