[geocode-glib] lib: Add function to calculate distance between 2 locations
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geocode-glib] lib: Add function to calculate distance between 2 locations
- Date: Sun, 25 Nov 2012 20:53:22 +0000 (UTC)
commit 6d20e9f79333d79c34b6f1b948162140d3fb8969
Author: Bastien Nocera <hadess hadess net>
Date: Sun Nov 25 21:48:40 2012 +0100
lib: Add function to calculate distance between 2 locations
geocode-glib/geocode-glib.symbols | 1 +
geocode-glib/geocode-location.c | 37 +++++++++++++++++++++++++++++++++++++
geocode-glib/geocode-location.h | 3 +++
geocode-glib/test-gcglib.c | 16 ++++++++++++++++
4 files changed, 57 insertions(+), 0 deletions(-)
---
diff --git a/geocode-glib/geocode-glib.symbols b/geocode-glib/geocode-glib.symbols
index 7760f10..0436a5a 100644
--- a/geocode-glib/geocode-glib.symbols
+++ b/geocode-glib/geocode-glib.symbols
@@ -2,6 +2,7 @@ geocode_location_get_type
geocode_location_new
geocode_location_new_with_description
geocode_location_free
+geocode_location_get_distance_from
geocode_forward_get_type
geocode_forward_new_for_string
geocode_forward_new_for_params
diff --git a/geocode-glib/geocode-location.c b/geocode-glib/geocode-location.c
index abf31b8..7fe4642 100644
--- a/geocode-glib/geocode-location.c
+++ b/geocode-glib/geocode-location.c
@@ -21,6 +21,9 @@
*/
#include <geocode-location.h>
+#include <math.h>
+
+#define EARTH_RADIUS_KM 6372.795
/**
* SECTION:geocode-location
@@ -115,3 +118,37 @@ geocode_location_new_with_description (gdouble latitude,
return ret;
}
+
+/**
+ * geocode_location_get_distance_from:
+ * @loca: a #GeocodeLocation
+ * @locb: a #GeocodeLocation
+ *
+ * Calculates the distance in km, along the curvature of the Earth,
+ * between 2 locations. Note that altitude changes are not
+ * taken into account.
+ *
+ * Returns: a distance in km.
+ **/
+double
+geocode_location_get_distance_from (GeocodeLocation *loca,
+ GeocodeLocation *locb)
+{
+ gdouble dlat, dlon, lat1, lat2;
+ gdouble a, c;
+
+ g_return_val_if_fail (loca != NULL || locb != NULL, 0.0);
+
+ /* Algorithm from:
+ * http://www.movable-type.co.uk/scripts/latlong.html */
+
+ dlat = (locb->latitude - loca->latitude) * M_PI / 180.0;
+ dlon = (locb->longitude - loca->longitude) * M_PI / 180.0;
+ lat1 = loca->latitude * M_PI / 180.0;
+ lat2 = locb->latitude * M_PI / 180.0;
+
+ a = sin (dlat / 2) * sin (dlat / 2) +
+ sin (dlon / 2) * sin (dlon / 2) * cos (lat1) * cos (lat2);
+ c = 2 * atan2 (sqrt (a), sqrt (1-a));
+ return EARTH_RADIUS_KM * c;
+}
diff --git a/geocode-glib/geocode-location.h b/geocode-glib/geocode-location.h
index 0b817f1..a16525d 100644
--- a/geocode-glib/geocode-location.h
+++ b/geocode-glib/geocode-location.h
@@ -57,6 +57,9 @@ GeocodeLocation *geocode_location_new_with_description (gdouble latitude,
gdouble longitude,
const char *description);
+double geocode_location_get_distance_from (GeocodeLocation *loca,
+ GeocodeLocation *locb);
+
void geocode_location_free (GeocodeLocation *loc);
G_END_DECLS
diff --git a/geocode-glib/test-gcglib.c b/geocode-glib/test-gcglib.c
index 0348beb..ab92d74 100644
--- a/geocode-glib/test-gcglib.c
+++ b/geocode-glib/test-gcglib.c
@@ -260,6 +260,21 @@ test_search_lat_long (void)
g_list_free_full (res, (GDestroyNotify) geocode_location_free);
}
+/* Test case from:
+ * http://andrew.hedges.name/experiments/haversine/ */
+static void
+test_distance (void)
+{
+ GeocodeLocation *loca, *locb;
+
+ /* 1600 Pennsylvania Ave NW, Washington, DC */
+ loca = geocode_location_new (38.898556, -77.037852);
+ /* 1600 Pennsylvania Ave NW, Washington, DC */
+ locb = geocode_location_new (38.897147, -77.043934);
+
+ g_assert_cmpfloat (geocode_location_get_distance_from (loca, locb) - 0.549311, <, 0.000001);
+}
+
static void
test_locale (void)
{
@@ -408,6 +423,7 @@ int main (int argc, char **argv)
g_test_add_func ("/geocode/locale", test_locale);
g_test_add_func ("/geocode/search", test_search);
g_test_add_func ("/geocode/search_lat_long", test_search_lat_long);
+ g_test_add_func ("/geocode/distance", test_distance);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]