[geocode-glib] geocode-glib: Accept a hash table for GeocodeBackend.reverse_resolve()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geocode-glib] geocode-glib: Accept a hash table for GeocodeBackend.reverse_resolve()
- Date: Fri, 13 Jan 2017 23:13:08 +0000 (UTC)
commit 4c27e04be856a81bf09e3697052c514e1e5a5f26
Author: Philip Withnall <philip withnall collabora co uk>
Date: Thu Oct 13 16:58:23 2016 +0100
geocode-glib: Accept a hash table for GeocodeBackend.reverse_resolve()
Instead of only accepting a GeocodeLocation, accept a hash table of
string keys and GValues. Typically, this will contain `lat` and `lon`
entries which represent the GeocodeLocation. But in future, it could
contain other keys to look up a GeocodePlace by its backend-specific ID,
for example; or to limit the search results by place type.
Whether the keys are static or non-static is decided by the caller.
This changes the API in GeocodeBackend (which is not stable yet), but
not in GeocodeReverse, so it’s not an API break.
https://bugzilla.gnome.org/show_bug.cgi?id=756311
geocode-glib/geocode-backend.c | 52 +++++++++++++++---------
geocode-glib/geocode-backend.h | 8 ++--
geocode-glib/geocode-nominatim.c | 80 ++++++++++++++++++-------------------
geocode-glib/geocode-reverse.c | 51 +++++++++++++++++++++++-
4 files changed, 125 insertions(+), 66 deletions(-)
---
diff --git a/geocode-glib/geocode-backend.c b/geocode-glib/geocode-backend.c
index 9fbf524..17f8d1b 100644
--- a/geocode-glib/geocode-backend.c
+++ b/geocode-glib/geocode-backend.c
@@ -145,14 +145,26 @@ geocode_backend_forward_search (GeocodeBackend *backend,
/**
* geocode_backend_reverse_resolve_async:
* @backend: a #GeocodeBackend.
- * @location: a #GeocodeLocation.
+ * @params: (transfer none) (element-type utf8 GValue): a #GHashTable with string keys, and #GValue values.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback to call when the request is satisfied.
* @user_data: the data to pass to callback function.
*
* Asynchronously gets the result of a reverse geocoding query using the
- * backend. Use geocode_backend_reverse_resolve() to do the same thing
- * synchronously.
+ * backend.
+ *
+ * Typically, a single result will be returned representing the place at a
+ * given latitude and longitude (the `lat` and `lon` keys to @params); but in
+ * some cases the results will be ambiguous and *multiple* results will be
+ * returned. They will be returned in order of relevance, with the most
+ * relevant result first in the list.
+ *
+ * The @params hash table is in the format used by Telepathy, and documented
+ * in the [Telepathy
specification](http://telepathy.freedesktop.org/spec/Connection_Interface_Location.html#Mapping:Location).
+ *
+ * See also: [XEP-0080 specification](http://xmpp.org/extensions/xep-0080.html).
+ *
+ * Use geocode_backend_reverse_resolve() to do the same thing synchronously.
*
* When the operation is finished, @callback will be called. You can then call
* geocode_backend_reverse_resolve_finish() to get the result of the operation.
@@ -161,7 +173,7 @@ geocode_backend_forward_search (GeocodeBackend *backend,
*/
void
geocode_backend_reverse_resolve_async (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -169,12 +181,12 @@ geocode_backend_reverse_resolve_async (GeocodeBackend *backend,
GeocodeBackendInterface *iface;
g_return_if_fail (GEOCODE_IS_BACKEND (backend));
- g_return_if_fail (GEOCODE_IS_LOCATION (location));
+ g_return_if_fail (params != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
iface = GEOCODE_BACKEND_GET_IFACE (backend);
- return (* iface->reverse_resolve_async) (backend, location,
+ return (* iface->reverse_resolve_async) (backend, params,
cancellable, callback, user_data);
}
@@ -212,15 +224,16 @@ geocode_backend_reverse_resolve_finish (GeocodeBackend *backend,
/**
* geocode_backend_reverse_resolve:
* @backend: a #GeocodeBackend.
- * @location: a #GeocodeLocation.
+ * @params: (transfer none) (element-type utf8 GValue): a #GHashTable with string keys, and #GValue values.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @error: a #GError.
*
- * Gets the result of a reverse geocoding query using the @backend. Typically, a
- * single result will be returned representing the place at the given location;
- * but in some cases the results will be ambiguous and multiple results will
- * be returned. They will be returned in order of relevance, with the most
- * relevant result first in the list.
+ * Gets the result of a reverse geocoding query using the @backend.
+ *
+ * This is a synchronous function, which means it may block on network requests.
+ * In most situations, the asynchronous version,
+ * geocode_backend_forward_search_async(), is more appropriate. See its
+ * documentation for more information on usage.
*
* Returns: (transfer full) (element-type GeocodePlace): A list of
* #GeocodePlace instances, or %NULL in case of errors. The list is ordered
@@ -231,14 +244,14 @@ geocode_backend_reverse_resolve_finish (GeocodeBackend *backend,
*/
GList *
geocode_backend_reverse_resolve (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GError **error)
{
GeocodeBackendInterface *iface;
g_return_val_if_fail (GEOCODE_IS_BACKEND (backend), NULL);
- g_return_val_if_fail (GEOCODE_IS_LOCATION (location), NULL);
+ g_return_val_if_fail (params != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -254,7 +267,7 @@ geocode_backend_reverse_resolve (GeocodeBackend *backend,
return NULL;
}
- return (* iface->reverse_resolve) (backend, location,
+ return (* iface->reverse_resolve) (backend, params,
cancellable, error);
}
@@ -309,13 +322,13 @@ real_forward_search_finish (GeocodeBackend *backend,
static void
reverse_resolve_async_thread (GTask *task,
GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable)
{
GError *error = NULL;
GList *places; /* (element-type GeocodePlace) */
- places = geocode_backend_reverse_resolve (backend, location,
+ places = geocode_backend_reverse_resolve (backend, params,
cancellable, &error);
if (error)
g_task_return_error (task, error);
@@ -326,7 +339,7 @@ reverse_resolve_async_thread (GTask *task,
static void
real_reverse_resolve_async (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -334,7 +347,8 @@ real_reverse_resolve_async (GeocodeBackend *backend,
GTask *task;
task = g_task_new (backend, cancellable, callback, user_data);
- g_task_set_task_data (task, g_object_ref (location), g_object_unref);
+ g_task_set_task_data (task, g_hash_table_ref (params),
+ (GDestroyNotify) g_hash_table_unref);
g_task_run_in_thread (task, (GTaskThreadFunc) reverse_resolve_async_thread);
g_object_unref (task);
}
diff --git a/geocode-glib/geocode-backend.h b/geocode-glib/geocode-backend.h
index a003826..9adfbc5 100644
--- a/geocode-glib/geocode-backend.h
+++ b/geocode-glib/geocode-backend.h
@@ -78,11 +78,11 @@ struct _GeocodeBackendInterface
/* Reverse */
GList *(*reverse_resolve) (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GError **error);
void (*reverse_resolve_async) (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -110,7 +110,7 @@ GList *geocode_backend_forward_search (GeocodeBackend *backe
/* Reverse geocoding operations */
void geocode_backend_reverse_resolve_async (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -118,7 +118,7 @@ GList *geocode_backend_reverse_resolve_finish (GeocodeBackend *back
GAsyncResult *result,
GError **error);
GList *geocode_backend_reverse_resolve (GeocodeBackend *backend,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GError **error);
diff --git a/geocode-glib/geocode-nominatim.c b/geocode-glib/geocode-nominatim.c
index b351b30..c4c9601 100644
--- a/geocode-glib/geocode-nominatim.c
+++ b/geocode-glib/geocode-nominatim.c
@@ -783,17 +783,33 @@ _geocode_glib_dup_hash_table (GHashTable *ht)
}
static gchar *
-get_resolve_uri_for_params (GeocodeNominatim *self,
- GHashTable *orig_ht)
+get_resolve_uri_for_params (GeocodeNominatim *self,
+ GHashTable *orig_ht,
+ GError **error)
{
GHashTable *ht;
char *locale;
char *params, *uri;
GeocodeNominatimPrivate *priv;
+ const GValue *lat, *lon;
priv = geocode_nominatim_get_instance_private (self);
- ht = _geocode_glib_dup_hash_table (orig_ht);
+ /* Make sure we have both lat and lon. */
+ lat = g_hash_table_lookup (orig_ht, "lat");
+ lon = g_hash_table_lookup (orig_ht, "lon");
+
+ if (lat == NULL || lon == NULL) {
+ g_set_error_literal (error, GEOCODE_ERROR, GEOCODE_ERROR_INVALID_ARGUMENTS,
+ "Only following parameters supported: lat, lon");
+
+ return NULL;
+ }
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+
+ g_hash_table_insert (ht, (gpointer) "lat", (gpointer) g_value_get_string (lat));
+ g_hash_table_insert (ht, (gpointer) "lon", (gpointer) g_value_get_string (lon));
g_hash_table_insert (ht, (gpointer) "format", (gpointer) "json");
g_hash_table_insert (ht, (gpointer) "email",
@@ -961,29 +977,6 @@ geocode_nominatim_query (GeocodeNominatim *self,
/******************************************************************************/
-static GHashTable *
-_geocode_location_to_params (GeocodeLocation *location)
-{
- GHashTable *ht;
- char coord[G_ASCII_DTOSTR_BUF_SIZE];
- char *lat;
- char *lon;
-
- lat = g_strdup (g_ascii_dtostr (coord,
- G_ASCII_DTOSTR_BUF_SIZE,
- geocode_location_get_latitude (location)));
-
- lon = g_strdup (g_ascii_dtostr (coord,
- G_ASCII_DTOSTR_BUF_SIZE,
- geocode_location_get_longitude (location)));
-
- ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_insert (ht, g_strdup ("lat"), lat);
- g_hash_table_insert (ht, g_strdup ("lon"), lon);
-
- return ht;
-}
-
static GList *
geocode_nominatim_reverse_resolve_finish (GeocodeBackend *backend,
GAsyncResult *res,
@@ -1192,21 +1185,25 @@ on_reverse_query_ready (GeocodeNominatim *self,
static void
geocode_nominatim_reverse_resolve_async (GeocodeBackend *self,
- GeocodeLocation *location,
+ GHashTable *params,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
- GHashTable *ht;
gchar *uri = NULL;
+ GError *error = NULL;
g_return_if_fail (GEOCODE_IS_BACKEND (self));
- g_return_if_fail (GEOCODE_IS_LOCATION (location));
+ g_return_if_fail (params != NULL);
- ht = _geocode_location_to_params (location);
- uri = get_resolve_uri_for_params (GEOCODE_NOMINATIM (self), ht);
- g_hash_table_unref (ht);
+ uri = get_resolve_uri_for_params (GEOCODE_NOMINATIM (self), params,
+ &error);
+
+ if (error != NULL) {
+ g_task_report_error (self, callback, user_data, NULL, error);
+ return;
+ }
task = g_task_new (self, cancellable, callback, user_data);
GEOCODE_NOMINATIM_GET_CLASS (self)->query_async (GEOCODE_NOMINATIM (self),
@@ -1219,23 +1216,24 @@ geocode_nominatim_reverse_resolve_async (GeocodeBackend *self,
}
static GList *
-geocode_nominatim_reverse_resolve (GeocodeBackend *self,
- GeocodeLocation *location,
- GCancellable *cancellable,
- GError **error)
+geocode_nominatim_reverse_resolve (GeocodeBackend *self,
+ GHashTable *params,
+ GCancellable *cancellable,
+ GError **error)
{
char *contents;
- GHashTable *ht;
GHashTable *result = NULL;
g_autoptr (GeocodePlace) place = NULL;
gchar *uri = NULL;
g_return_val_if_fail (GEOCODE_IS_BACKEND (self), NULL);
- g_return_val_if_fail (GEOCODE_IS_LOCATION (location), NULL);
+ g_return_val_if_fail (params != NULL, NULL);
- ht = _geocode_location_to_params (location);
- uri = get_resolve_uri_for_params (GEOCODE_NOMINATIM (self), ht);
- g_hash_table_unref (ht);
+ uri = get_resolve_uri_for_params (GEOCODE_NOMINATIM (self), params,
+ error);
+
+ if (uri == NULL)
+ return NULL;
contents = GEOCODE_NOMINATIM_GET_CLASS (self)->query (GEOCODE_NOMINATIM (self),
uri,
diff --git a/geocode-glib/geocode-reverse.c b/geocode-glib/geocode-reverse.c
index 43d3b77..eed4029 100644
--- a/geocode-glib/geocode-reverse.c
+++ b/geocode-glib/geocode-reverse.c
@@ -109,6 +109,48 @@ ensure_backend (GeocodeReverse *object)
object->priv->backend = GEOCODE_BACKEND (geocode_nominatim_get_gnome ());
}
+static GValue *
+str_to_value (const gchar *str)
+{
+ GValue *value;
+
+ value = g_new0 (GValue, 1);
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, str);
+
+ return value;
+}
+
+static void
+free_value (GValue *value)
+{
+ g_value_unset (value);
+ g_free (value);
+}
+
+static GHashTable *
+_geocode_location_to_params (GeocodeLocation *location)
+{
+ GHashTable *ht;
+ char lat[G_ASCII_DTOSTR_BUF_SIZE];
+ char lon[G_ASCII_DTOSTR_BUF_SIZE];
+
+ g_ascii_dtostr (lat,
+ G_ASCII_DTOSTR_BUF_SIZE,
+ geocode_location_get_latitude (location));
+ g_ascii_dtostr (lon,
+ G_ASCII_DTOSTR_BUF_SIZE,
+ geocode_location_get_longitude (location));
+
+ /* Semantics from http://xmpp.org/extensions/xep-0080.html */
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) free_value);
+ g_hash_table_insert (ht, (gpointer) "lat", str_to_value (lat));
+ g_hash_table_insert (ht, (gpointer) "lon", str_to_value (lon));
+
+ return ht;
+}
+
static void
places_list_free (GList *places)
{
@@ -155,6 +197,7 @@ geocode_reverse_resolve_async (GeocodeReverse *object,
gpointer user_data)
{
GTask *task;
+ g_autoptr (GHashTable) params = NULL;
g_return_if_fail (GEOCODE_IS_REVERSE (object));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -162,9 +205,11 @@ geocode_reverse_resolve_async (GeocodeReverse *object,
ensure_backend (object);
g_assert (object->priv->backend != NULL);
+ params = _geocode_location_to_params (object->priv->location);
+
task = g_task_new (object, cancellable, callback, user_data);
geocode_backend_reverse_resolve_async (object->priv->backend,
- object->priv->location,
+ params,
cancellable,
(GAsyncReadyCallback) backend_reverse_resolve_ready,
g_object_ref (task));
@@ -211,6 +256,7 @@ geocode_reverse_resolve (GeocodeReverse *object,
{
GList *places = NULL; /* (element-type GeocodePlace) */
GeocodePlace *place = NULL;
+ g_autoptr (GHashTable) params = NULL;
g_return_val_if_fail (GEOCODE_IS_REVERSE (object), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -218,8 +264,9 @@ geocode_reverse_resolve (GeocodeReverse *object,
ensure_backend (object);
g_assert (object->priv->backend != NULL);
+ params = _geocode_location_to_params (object->priv->location);
places = geocode_backend_reverse_resolve (object->priv->backend,
- object->priv->location,
+ params,
NULL,
error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]