[libgweather] New api with the support of geocoding to find_nearest_city
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgweather] New api with the support of geocoding to find_nearest_city
- Date: Tue, 1 Apr 2014 20:52:06 +0000 (UTC)
commit 31270499ceac3ba7119c29a3312c85fee9dcdee0
Author: Saurabh_P <srp201201051 gmail com>
Date: Thu Mar 13 04:28:47 2014 +0530
New api with the support of geocoding to find_nearest_city
Use geocoding to get the nearest place and using that geocode place
looks for the nearest city that lies in the same country and return
the newly created detached location using current location name and
coordinates and metar code of the nearest weather station.
https://bugzilla.gnome.org/show_bug.cgi?id=725842
configure.ac | 3 +-
libgweather/gweather-location.c | 149 ++++++++++++++++++++++++++++++++++++++-
libgweather/gweather-location.h | 9 +++
3 files changed, 157 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fc0d374..69d6ca9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,7 +61,8 @@ PKG_CHECK_MODULES(DEPS, [gtk+-3.0 >= $GTK_REQUIRED
libxml-2.0 >= $LIBXML_REQUIRED
libsoup-2.4 >= $LIBSOUP_REQUIRED
glib-2.0 >= $GLIB_REQUIRED
- gio-2.0])
+ gio-2.0
+ geocode-glib-1.0])
dnl -- check for glib; redundant at this point, but sets $GLIB_MKENUMS
AM_PATH_GLIB_2_0($GLIB_REQUIRED)
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index 5fc5f2e..4efb778 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -28,6 +28,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <libxml/xmlreader.h>
+#include <geocode-glib/geocode-glib.h>
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
#include "gweather-location.h"
@@ -522,9 +523,16 @@ static void
foreach_city (GWeatherLocation *loc,
GFunc callback,
gpointer user_data,
+ const char *country_code,
GWeatherFilterFunc func,
gpointer user_data_func)
{
+ if (country_code) {
+ const char *loc_country_code = gweather_location_get_country(loc);
+ if (loc_country_code && (g_strcmp0 (loc_country_code, country_code) != 0))
+ return;
+ }
+
if (func) {
if (!func (loc, user_data_func))
return;
@@ -535,7 +543,7 @@ foreach_city (GWeatherLocation *loc,
} else if (loc->children) {
int i;
for (i = 0; loc->children[i]; i++)
- foreach_city (loc->children[i], callback, user_data, func, user_data_func);
+ foreach_city (loc->children[i], callback, user_data, country_code, func, user_data_func);
}
}
@@ -546,6 +554,15 @@ struct FindNearestCityData {
double distance;
};
+struct ArgData {
+ double latitude;
+ double longitude;
+ GWeatherLocation *location;
+ GSimpleAsyncResult *simple;
+};
+
+typedef struct ArgData ArgData;
+
static double
location_distance (double lat1, double long1,
double lat2, double long2)
@@ -614,7 +631,7 @@ gweather_location_find_nearest_city (GWeatherLocation *loc,
data.location = NULL;
data.distance = 0.0;
- foreach_city (loc, (GFunc) find_nearest_city, &data, NULL, NULL);
+ foreach_city (loc, (GFunc) find_nearest_city, &data, NULL, NULL, NULL);
return gweather_location_ref (data.location);
}
@@ -669,13 +686,139 @@ gweather_location_find_nearest_city_full (GWeatherLocation *loc,
data.location = NULL;
data.distance = 0.0;
- foreach_city (loc, (GFunc) find_nearest_city, &data, func, user_data);
+ foreach_city (loc, (GFunc) find_nearest_city, &data, NULL, func, user_data);
destroy (user_data);
return gweather_location_ref (data.location);
}
+static
+void _got_place (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ ArgData *info = (user_data);
+ GSimpleAsyncResult *simple = info->simple;
+
+ GeocodePlace *place;
+ GError *error = NULL;
+ place = geocode_reverse_resolve_finish (GEOCODE_REVERSE (source_object), result, &error);
+ if (place == NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_slice_free (ArgData, info);
+ g_object_unref (simple);
+ return;
+ }
+ const char *country_code = geocode_place_get_country_code (place);
+
+ struct FindNearestCityData data;
+ data.latitude = info->latitude * M_PI / 180.0;
+ data.longitude = info->longitude * M_PI / 180.0;
+ data.location = NULL;
+ data.distance = 0.0;
+
+ foreach_city (info->location, (GFunc) find_nearest_city, &data, country_code, NULL, NULL);
+
+ g_slice_free (ArgData, info);
+
+ if (data.location == NULL) {
+ g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
+ g_simple_async_result_complete_in_idle (simple);
+ }
+ else {
+ GWeatherLocation *location;
+ location = _gweather_location_new_detached(data.location, geocode_place_get_town (place), TRUE,
data.latitude, data.longitude);
+
+ g_simple_async_result_set_op_res_gpointer (simple, location,
(GDestroyNotify)gweather_location_unref);
+ g_simple_async_result_complete_in_idle (simple);
+ }
+ g_object_unref (simple);
+}
+
+/**
+ * gweather_location_detect_nearest_city:
+ * @loc: (allow-none): The parent location, which will be searched recursively
+ * @lat: Latitude, in degrees
+ * @lon: Longitude, in degrees
+ * @cancellable: optional, NULL to ignore
+ * @callback: callback function for GAsyncReadyCallback argument for GSimpleAsyncResult
+ *
+ * Initializes geocode reversing to find place for (@lat, @lon) coordinates. Calls the callback
+ * function passed by user when the result is ready.
+ *
+ * @loc must be at most a %GWEATHER_LOCATION_LEVEL_ADM2 location.
+ * This restriction may be lifted in a future version.
+ *
+ * Returns: void
+ *
+ * Since: 3.12
+ */
+void
+gweather_location_detect_nearest_city (GWeatherLocation *loc,
+ double lat,
+ double lon,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ArgData *data;
+
+ g_return_val_if_fail (loc == NULL || loc->level < GWEATHER_LOCATION_CITY, NULL);
+
+ if (loc == NULL)
+ loc = gweather_location_get_world ();
+
+ GeocodeLocation *location = geocode_location_new (lat, lon, GEOCODE_LOCATION_ACCURACY_CITY);
+ GeocodeReverse *reverse = geocode_reverse_new_for_location (location);
+
+ GSimpleAsyncResult *simple;
+ simple = g_simple_async_result_new (NULL, callback, user_data, gweather_location_detect_nearest_city);
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ data = g_slice_new0 (ArgData);
+ data->latitude = lat;
+ data->longitude = lon;
+ data->location = loc;
+ data->simple = simple;
+
+ geocode_reverse_resolve_async (reverse, cancellable, _got_place, data);
+}
+
+/**
+ * gweather_location_detect_nearest_location_finish:
+ * @result: Passed by GSimpleAsyncResult in _got_place method and used to get result pointer
+ * that might contain location
+ * @error: Stores error if any occurs in retrieving the result
+ *
+ * Fetches the location from @result.
+ *
+ * Returns: (transfer full): Customized GWeatherLocation
+ *
+ * Since: 3.12
+ */
+
+GWeatherLocation *
+gweather_location_detect_nearest_city_finish (GAsyncResult *result, GError **error)
+{
+ GSimpleAsyncResult *simple;
+ GWeatherLocation *loc;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ NULL,
+ gweather_location_detect_nearest_city),
+ NULL);
+
+ simple = (GSimpleAsyncResult *) result;
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ loc = (g_simple_async_result_get_op_res_gpointer (simple));
+
+ return gweather_location_ref (loc);
+}
+
/**
* gweather_location_has_coords:
* @loc: a #GWeatherLocation
diff --git a/libgweather/gweather-location.h b/libgweather/gweather-location.h
index 63803a6..ae960bc 100644
--- a/libgweather/gweather-location.h
+++ b/libgweather/gweather-location.h
@@ -27,6 +27,7 @@
#include <glib.h>
#include <libgweather/gweather-timezone.h>
+#include <gio/gio.h>
G_BEGIN_DECLS
@@ -81,6 +82,14 @@ GWeatherLocation *gweather_location_find_nearest_city_full (GWeatherLocatio
gpointer user_data,
GDestroyNotify destroy);
+void gweather_location_detect_nearest_city (GWeatherLocation *loc,
+ double lat,
+ double lon,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GWeatherLocation *gweather_location_detect_nearest_city_finish (GAsyncResult *result, GError **error);
+
const char *gweather_location_get_country (GWeatherLocation *loc);
GWeatherTimezone *gweather_location_get_timezone (GWeatherLocation *loc);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]