[geocode-glib] lib: Report accuracy of location result(s)



commit a1deb1b9b163354ea346eb2268a2062b222f02a3
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Sun Mar 24 03:01:11 2013 +0200

    lib: Report accuracy of location result(s)
    
    Currently only accuracy of IP-based location search is reported but we
    should also make use of this new API to report accuracy of other
    location(s) yielding searches too (bug#697174).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696527

 geocode-glib/geocode-forward.c  |   11 ++++++--
 geocode-glib/geocode-ipclient.c |   51 ++++++++++++++++++++++++++++++++++++--
 geocode-glib/geocode-location.c |   18 ++++++++++---
 geocode-glib/geocode-location.h |   17 ++++++++++--
 geocode-glib/test-gcglib.c      |    8 +++---
 geocode-glib/test-geoip.c       |    2 +
 6 files changed, 90 insertions(+), 17 deletions(-)
---
diff --git a/geocode-glib/geocode-forward.c b/geocode-glib/geocode-forward.c
index 33a7202..2ef7800 100644
--- a/geocode-glib/geocode-forward.c
+++ b/geocode-glib/geocode-forward.c
@@ -108,8 +108,10 @@ _geocode_parse_single_result_json (const char  *contents,
 
        longitude = g_ascii_strtod (g_hash_table_lookup (ht, "longitude"), NULL);
        latitude = g_ascii_strtod (g_hash_table_lookup (ht, "latitude"), NULL);
-       loc = geocode_location_new_with_description (longitude, latitude,
-                                                    g_hash_table_lookup (ht, "line2"));
+       loc = geocode_location_new_with_description (longitude,
+                                                 latitude,
+                                                 GEOCODE_LOCATION_ACCURACY_UNKNOWN,
+                                                 g_hash_table_lookup (ht, "line2"));
        g_hash_table_destroy (ht);
 
        return g_list_append (NULL, loc);
@@ -616,7 +618,10 @@ insert_place_into_tree (GNode *location_tree, GHashTable *ht)
        latitude = g_ascii_strtod (g_hash_table_lookup (ht, "latitude"), NULL);
        name = g_hash_table_lookup (ht, "name");
 
-       loc = geocode_location_new_with_description (latitude, longitude, name);
+       loc = geocode_location_new_with_description (latitude,
+                                                 longitude,
+                                                 GEOCODE_LOCATION_ACCURACY_UNKNOWN,
+                                                 name);
 
        g_node_insert_data (start, -1, loc);
 }
diff --git a/geocode-glib/geocode-ipclient.c b/geocode-glib/geocode-ipclient.c
index 1697a67..d1b7f12 100644
--- a/geocode-glib/geocode-ipclient.c
+++ b/geocode-glib/geocode-ipclient.c
@@ -24,9 +24,11 @@
 #include <glib.h>
 #include <libsoup/soup.h>
 #include <json-glib/json-glib.h>
+#include <string.h>
 #include "geocode-glib-private.h"
 #include "geocode-ipclient.h"
 #include "geocode-error.h"
+#include "geocode-enum-types.h"
 #include "geocode-ip-server/geoip-server.h"
 
 /**
@@ -317,6 +319,46 @@ parse_server_error (JsonObject *object, GError **error)
         return TRUE;
 }
 
+static gdouble
+get_accuracy_from_string (const char *str)
+{
+        if (strcmp (str, "street") == 0)
+                return GEOCODE_LOCATION_ACCURACY_STREET;
+        else if (strcmp (str, "city") == 0)
+                return GEOCODE_LOCATION_ACCURACY_CITY;
+        else if (strcmp (str, "region") == 0)
+                return GEOCODE_LOCATION_ACCURACY_REGION;
+        else if (strcmp (str, "country") == 0)
+                return GEOCODE_LOCATION_ACCURACY_COUNTRY;
+        else if (strcmp (str, "continent") == 0)
+                return GEOCODE_LOCATION_ACCURACY_CONTINENT;
+        else
+                return GEOCODE_LOCATION_ACCURACY_UNKNOWN;
+}
+
+static gdouble
+get_accuracy_from_json_location (JsonObject *object)
+{
+        if (json_object_has_member (object, "accuracy")) {
+                const char *str;
+
+                str = json_object_get_string_member (object, "accuracy");
+                return get_accuracy_from_string (str);
+        } else if (json_object_has_member (object, "street")) {
+                return GEOCODE_LOCATION_ACCURACY_STREET;
+        } else if (json_object_has_member (object, "city")) {
+                return GEOCODE_LOCATION_ACCURACY_CITY;
+        } else if (json_object_has_member (object, "region_name")) {
+                return GEOCODE_LOCATION_ACCURACY_REGION;
+        } else if (json_object_has_member (object, "country_name")) {
+                return GEOCODE_LOCATION_ACCURACY_COUNTRY;
+        } else if (json_object_has_member (object, "continent")) {
+                return GEOCODE_LOCATION_ACCURACY_CONTINENT;
+        } else {
+                return GEOCODE_LOCATION_ACCURACY_UNKNOWN;
+        }
+}
+
 GeocodeLocation *
 _geocode_ip_json_to_location (const char *json,
                               GError    **error)
@@ -325,6 +367,7 @@ _geocode_ip_json_to_location (const char *json,
         JsonNode *node;
         JsonObject *object;
         GeocodeLocation *location;
+        gdouble latitude, longitude, accuracy;
         char *desc = NULL;
 
         parser = json_parser_new ();
@@ -338,9 +381,11 @@ _geocode_ip_json_to_location (const char *json,
         if (parse_server_error (object, error))
                 return NULL;
 
-        location = geocode_location_new (0, 0);
-        location->latitude = json_object_get_double_member (object, "latitude");
-        location->longitude = json_object_get_double_member (object, "longitude");
+        latitude = json_object_get_double_member (object, "latitude");
+        longitude = json_object_get_double_member (object, "longitude");
+        accuracy = get_accuracy_from_json_location (object);
+
+        location = geocode_location_new (latitude, longitude, accuracy);
 
         if (json_object_has_member (object, "country_name")) {
                 if (json_object_has_member (object, "region_name")) {
diff --git a/geocode-glib/geocode-location.c b/geocode-glib/geocode-location.c
index 9855f39..d2bc61c 100644
--- a/geocode-glib/geocode-location.c
+++ b/geocode-glib/geocode-location.c
@@ -43,6 +43,7 @@ geocode_location_copy (gpointer boxed)
        to->latitude = from->latitude;
        to->timestamp = from->timestamp;
        to->description = from->description;
+       to->accuracy = from->accuracy;
 
        return to;
 }
@@ -66,6 +67,7 @@ G_DEFINE_BOXED_TYPE(GeocodeLocation, geocode_location, geocode_location_copy, ge
  * geocode_location_new:
  * @latitude: a valid latitude
  * @longitude: a valid longitude
+ * @accuracy: accuracy of location in meters
  *
  * Creates a new #GeocodeLocation object.
  *
@@ -73,7 +75,8 @@ G_DEFINE_BOXED_TYPE(GeocodeLocation, geocode_location, geocode_location_copy, ge
  **/
 GeocodeLocation *
 geocode_location_new (gdouble latitude,
-                     gdouble longitude)
+                      gdouble longitude,
+                      gdouble accuracy)
 {
        GeocodeLocation *ret;
        GTimeVal tv;
@@ -86,10 +89,15 @@ geocode_location_new (gdouble latitude,
                g_warning ("Invalid latitude %lf passed, using 0.0 instead", latitude);
                latitude = 0.0;
        }
+       if (accuracy < GEOCODE_LOCATION_ACCURACY_UNKNOWN) {
+               g_warning ("Invalid accuracy %lf passed, assuming its unknown", accuracy);
+               accuracy = GEOCODE_LOCATION_ACCURACY_UNKNOWN;
+       }
 
        ret = g_new0 (GeocodeLocation, 1);
        ret->longitude = longitude;
        ret->latitude = latitude;
+       ret->accuracy = accuracy;
        g_get_current_time (&tv);
        ret->timestamp = tv.tv_sec;
 
@@ -100,6 +108,7 @@ geocode_location_new (gdouble latitude,
  * geocode_location_new_with_description:
  * @latitude: a valid latitude
  * @longitude: a valid longitude
+ * @accuracy: accuracy of location in meters
  * @description: a description for the location
  *
  * Creates a new #GeocodeLocation object.
@@ -108,12 +117,13 @@ geocode_location_new (gdouble latitude,
  **/
 GeocodeLocation *
 geocode_location_new_with_description (gdouble     latitude,
-                                      gdouble     longitude,
-                                      const char *description)
+                                       gdouble     longitude,
+                                       gdouble     accuracy,
+                                       const char *description)
 {
        GeocodeLocation *ret;
 
-       ret = geocode_location_new (latitude, longitude);
+       ret = geocode_location_new (latitude, longitude, accuracy);
        ret->description = g_strdup (description);
 
        return ret;
diff --git a/geocode-glib/geocode-location.h b/geocode-glib/geocode-location.h
index 351bf59..51242b4 100644
--- a/geocode-glib/geocode-location.h
+++ b/geocode-glib/geocode-location.h
@@ -33,6 +33,7 @@ typedef struct _GeocodeLocation GeocodeLocation;
  * GeocodeLocation:
  * @longitude: a longitude, in degrees
  * @latitude: a latitude, in degrees
+ * @accuracy: accuracy of location, in meters
  * @timestamp: a timestamp in seconds since <ulink 
url="http://en.wikipedia.org/wiki/Unix_epoch";>Epoch</ulink>.
  * @description: a description for display
  *
@@ -42,20 +43,30 @@ typedef struct _GeocodeLocation GeocodeLocation;
 struct _GeocodeLocation {
        gdouble longitude;
        gdouble latitude;
+       gdouble accuracy;
        gint64  timestamp;
        char   *description;
 };
 
+#define GEOCODE_LOCATION_ACCURACY_UNKNOWN   -1
+#define GEOCODE_LOCATION_ACCURACY_STREET    1000    /*    1 km */
+#define GEOCODE_LOCATION_ACCURACY_CITY      25000   /*   25 km */
+#define GEOCODE_LOCATION_ACCURACY_REGION    50000   /*   50 km */
+#define GEOCODE_LOCATION_ACCURACY_COUNTRY   150000  /*  150 km */
+#define GEOCODE_LOCATION_ACCURACY_CONTINENT 3000000 /* 3000 km */
+
 #define GEOCODE_TYPE_LOCATION (geocode_location_get_type ())
 
 GType geocode_location_get_type (void) G_GNUC_CONST;
 
 GeocodeLocation *geocode_location_new (gdouble latitude,
-                                      gdouble longitude);
+                                       gdouble longitude,
+                                       gdouble accuracy);
 
 GeocodeLocation *geocode_location_new_with_description (gdouble     latitude,
-                                                       gdouble     longitude,
-                                                       const char *description);
+                                                        gdouble     longitude,
+                                                        gdouble     accuracy,
+                                                        const char *description);
 
 double geocode_location_get_distance_from (GeocodeLocation *loca,
                                           GeocodeLocation *locb);
diff --git a/geocode-glib/test-gcglib.c b/geocode-glib/test-gcglib.c
index 5ccf107..70a9258 100644
--- a/geocode-glib/test-gcglib.c
+++ b/geocode-glib/test-gcglib.c
@@ -89,7 +89,7 @@ test_rev (void)
        GError *error = NULL;
        GHashTable *ht;
 
-       loc = geocode_location_new (51.237070, -0.589669);
+       loc = geocode_location_new (51.237070, -0.589669, GEOCODE_LOCATION_ACCURACY_UNKNOWN);
        rev = geocode_reverse_new_for_location (loc);
        geocode_location_free (loc);
 
@@ -271,9 +271,9 @@ test_distance (void)
        GeocodeLocation *loca, *locb;
 
        /* 1600 Pennsylvania Ave NW, Washington, DC */
-       loca = geocode_location_new (38.898556, -77.037852);
+       loca = geocode_location_new (38.898556, -77.037852, GEOCODE_LOCATION_ACCURACY_UNKNOWN);
        /* 1600 Pennsylvania Ave NW, Washington, DC */
-       locb = geocode_location_new (38.897147, -77.043934);
+       locb = geocode_location_new (38.897147, -77.043934, GEOCODE_LOCATION_ACCURACY_UNKNOWN);
 
        g_assert_cmpfloat (geocode_location_get_distance_from (loca, locb) - 0.549311, <, 0.000001);
 }
@@ -415,7 +415,7 @@ new_loc (void)
                return NULL;
        latitude = g_ascii_strtod (params[0], NULL);
        longitude = g_ascii_strtod (params[1], NULL);
-       return geocode_location_new (latitude, longitude);
+       return geocode_location_new (latitude, longitude, GEOCODE_LOCATION_ACCURACY_UNKNOWN);
 }
 
 int main (int argc, char **argv)
diff --git a/geocode-glib/test-geoip.c b/geocode-glib/test-geoip.c
index 193b8e3..008fcd0 100644
--- a/geocode-glib/test-geoip.c
+++ b/geocode-glib/test-geoip.c
@@ -54,6 +54,7 @@ test_search (gconstpointer data)
         GError *error = NULL;
         GeocodeLocation *location;
         TestData *test_data = (TestData *) data;
+        gdouble accuracy = GEOCODE_LOCATION_ACCURACY_UNKNOWN;
 
         if (test_data->ip)
                 ipclient = geocode_ipclient_new_for_ip (test_data->ip);
@@ -70,6 +71,7 @@ test_search (gconstpointer data)
         g_assert (location->longitude == test_data->expected_longitude);
         g_assert (location->description != NULL &&
                   strcmp(location->description, test_data->expected_description) == 0);
+        g_assert (accuracy != GEOCODE_LOCATION_ACCURACY_UNKNOWN);
         geocode_location_free (location);
         g_object_unref (ipclient);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]