summaryrefslogtreecommitdiffstats
path: root/core/divesite.c
diff options
context:
space:
mode:
authorGravatar Doug Junkins <junkins@foghead.com>2019-04-30 06:53:31 -0700
committerGravatar bstoeger <32835590+bstoeger@users.noreply.github.com>2019-04-30 23:32:50 +0200
commit14a763a6a0148a42fad06717bd2532181a54c626 (patch)
treed8b71f0c9a2d33d40d60aeccb44e12111abcb2e0 /core/divesite.c
parent154792ffd1c217e5c1c9774b5593a753ae553601 (diff)
downloadsubsurface-14a763a6a0148a42fad06717bd2532181a54c626.tar.gz
Bugfix for algorithm in get_distance()
Fixed bug in the Haversine function in get_distance() based on algorithm at https://www.movable-type.co.uk/scripts/latlong.html and added bounds to the 'a' term to avoid floating point errors for antipodal points. Signed-off-by: Doug Junkins <junkins@foghead.com>
Diffstat (limited to 'core/divesite.c')
-rw-r--r--core/divesite.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/core/divesite.c b/core/divesite.c
index b5ce99a8d..45601537c 100644
--- a/core/divesite.c
+++ b/core/divesite.c
@@ -77,15 +77,18 @@ struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *lo
// Calculate the distance in meters between two coordinates.
unsigned int get_distance(const location_t *loc1, const location_t *loc2)
{
+ double lat1_r = udeg_to_radians(loc1->lat.udeg);
double lat2_r = udeg_to_radians(loc2->lat.udeg);
double lat_d_r = udeg_to_radians(loc2->lat.udeg - loc1->lat.udeg);
double lon_d_r = udeg_to_radians(loc2->lon.udeg - loc1->lon.udeg);
double a = sin(lat_d_r/2) * sin(lat_d_r/2) +
- cos(lat2_r) * cos(lat2_r) * sin(lon_d_r/2) * sin(lon_d_r/2);
+ cos(lat1_r) * cos(lat2_r) * sin(lon_d_r/2) * sin(lon_d_r/2);
+ if (a < 0.0) a = 0.0;
+ if (a > 1.0) a = 1.0;
double c = 2 * atan2(sqrt(a), sqrt(1.0 - a));
- // Earth radious in metres
+ // Earth radius in metres
return lrint(6371000 * c);
}