[geocode-glib] place: Add osm-type property



commit 075d0554568b88c7ce8aa3626979184ab4d36c95
Author: Jonas Danielsson <jonas threetimestwo org>
Date:   Mon Dec 1 02:58:51 2014 -0500

    place: Add osm-type property
    
    The osm type specifies if the place is a node a place or a relation.
    The osm id is only unique within the object type so this is needed
    in order for the osm-id to have a meaning.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=740957

 geocode-glib/geocode-forward.c    |   14 +++++++++++-
 geocode-glib/geocode-glib.symbols |    2 +
 geocode-glib/geocode-place.c      |   43 ++++++++++++++++++++++++++++++++++++-
 geocode-glib/geocode-place.h      |   17 ++++++++++++++
 geocode-glib/test-gcglib.c        |   33 ++++++++++++++++++++++++++++
 5 files changed, 107 insertions(+), 2 deletions(-)
---
diff --git a/geocode-glib/geocode-forward.c b/geocode-glib/geocode-forward.c
index b7e3b56..5d20847 100644
--- a/geocode-glib/geocode-forward.c
+++ b/geocode-glib/geocode-forward.c
@@ -603,7 +603,6 @@ static struct {
         const char *place_prop; /* NULL to ignore */
 } nominatim_to_place_map[] = {
         { "license", NULL },
-        { "osm_type", NULL },
         { "osm_id", "osm-id" },
         { "lat", NULL },
         { "lon", NULL },
@@ -639,6 +638,19 @@ fill_place_from_entry (const char   *key,
                         break;
                 }
         }
+
+        if (g_str_equal (key, "osm_type")) {
+                gpointer ref = g_type_class_ref (geocode_place_osm_type_get_type ());
+                GEnumClass *class = G_ENUM_CLASS (ref);
+                GEnumValue *evalue = g_enum_get_value_by_nick (class, value);
+
+                if (evalue)
+                        g_object_set (G_OBJECT (place), "osm-type", evalue->value, NULL);
+                else
+                        g_warning ("Unsupported osm-type %s", value);
+
+                g_type_class_unref (ref);
+        }
 }
 
 static gboolean
diff --git a/geocode-glib/geocode-glib.symbols b/geocode-glib/geocode-glib.symbols
index 8664ac1..e8550e5 100644
--- a/geocode-glib/geocode-glib.symbols
+++ b/geocode-glib/geocode-glib.symbols
@@ -39,6 +39,7 @@ _geocode_read_nominatim_attributes
 _geocode_create_place_from_attributes
 geocode_place_get_type
 geocode_place_type_get_type
+geocode_place_osm_type_get_type
 geocode_place_new
 geocode_place_new_with_location
 geocode_place_get_area
@@ -74,6 +75,7 @@ geocode_place_get_icon
 geocode_place_get_bounding_box
 geocode_place_set_bounding_box
 geocode_place_get_osm_id
+geocode_place_get_osm_type
 geocode_bounding_box_get_type
 geocode_bounding_box_new
 geocode_bounding_box_get_top
diff --git a/geocode-glib/geocode-place.c b/geocode-glib/geocode-place.c
index 9e8022f..7166e81 100644
--- a/geocode-glib/geocode-place.c
+++ b/geocode-glib/geocode-place.c
@@ -57,6 +57,7 @@ struct _GeocodePlacePrivate {
         char *country;
         char *continent;
         char *osm_id;
+        GeocodePlaceOsmType osm_type;
 };
 
 enum {
@@ -79,7 +80,8 @@ enum {
         PROP_CONTINENT,
         PROP_ICON,
         PROP_BBOX,
-        PROP_OSM_ID
+        PROP_OSM_ID,
+        PROP_OSM_TYPE
 };
 
 G_DEFINE_TYPE (GeocodePlace, geocode_place, G_TYPE_OBJECT)
@@ -183,6 +185,11 @@ geocode_place_get_property (GObject    *object,
                                     geocode_place_get_osm_id (place));
                 break;
 
+        case PROP_OSM_TYPE:
+                g_value_set_enum (value,
+                                  geocode_place_get_osm_type (place));
+                break;
+
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                 break;
@@ -271,6 +278,10 @@ geocode_place_set_property(GObject      *object,
                 place->priv->osm_id = g_value_dup_string (value);
                 break;
 
+        case PROP_OSM_TYPE:
+                place->priv->osm_type = g_value_get_enum (value);
+                break;
+
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                 break;
@@ -551,6 +562,19 @@ geocode_place_class_init (GeocodePlaceClass *klass)
                                      G_PARAM_STATIC_STRINGS);
         g_object_class_install_property (gplace_class, PROP_OSM_ID, pspec);
 
+        /**
+         * GeocodePlace:osm-type:
+         *
+         * The OpenStreetMap type of the place.
+         */
+        pspec = g_param_spec_enum ("osm-type",
+                                   "OSM Type",
+                                   "The OpenStreetMap type of the place",
+                                   GEOCODE_TYPE_PLACE_OSM_TYPE,
+                                   GEOCODE_PLACE_OSM_TYPE_UNKNOWN,
+                                   G_PARAM_READWRITE |
+                                   G_PARAM_STATIC_STRINGS);
+        g_object_class_install_property (gplace_class, PROP_OSM_TYPE, pspec);
 }
 
 static void
@@ -560,6 +584,7 @@ geocode_place_init (GeocodePlace *place)
                                                       GEOCODE_TYPE_PLACE,
                                                       GeocodePlacePrivate);
         place->priv->bbox = NULL;
+        place->priv->osm_type = GEOCODE_PLACE_OSM_TYPE_UNKNOWN;
 }
 
 /**
@@ -1223,3 +1248,19 @@ geocode_place_get_osm_id (GeocodePlace *place)
 
         return place->priv->osm_id;
 }
+
+/**
+ * geocode_place_get_osm_type:
+ * @place: A place
+ *
+ * Gets the OpenStreetMap type of the @place.
+ *
+ * Returns: The osm type of the @place.
+ **/
+GeocodePlaceOsmType
+geocode_place_get_osm_type (GeocodePlace *place)
+{
+        g_return_val_if_fail (GEOCODE_IS_PLACE (place), GEOCODE_PLACE_OSM_TYPE_UNKNOWN);
+
+        return place->priv->osm_type;
+}
diff --git a/geocode-glib/geocode-place.h b/geocode-glib/geocode-place.h
index 21d1fb1..d7a4bd7 100644
--- a/geocode-glib/geocode-place.h
+++ b/geocode-glib/geocode-place.h
@@ -141,6 +141,22 @@ typedef enum {
         GEOCODE_PLACE_TYPE_BAR
 } GeocodePlaceType;
 
+
+/**
+ * GeocodePlaceOsmType:
+ * @GEOCODE_PLACE_OSM_TYPE_NODE: Defines a point in space.
+ * @GEOCODE_PLACE_OSM_TYPE_RELATION: Used to explain how other elements work together.
+ * @GEOCODE_PLACE_OSM_TYPE_WAY: Defines a linear feature and area boundaries.
+ *
+ * Osm type of the place.
+ */
+typedef enum {
+  GEOCODE_PLACE_OSM_TYPE_UNKNOWN,
+  GEOCODE_PLACE_OSM_TYPE_NODE,
+  GEOCODE_PLACE_OSM_TYPE_RELATION,
+  GEOCODE_PLACE_OSM_TYPE_WAY
+} GeocodePlaceOsmType;
+
 #define GEOCODE_TYPE_PLACE (geocode_place_get_type ())
 
 GeocodePlace *geocode_place_new                    (const char      *name,
@@ -215,6 +231,7 @@ const char *geocode_place_get_continent            (GeocodePlace *place);
 GIcon *geocode_place_get_icon                      (GeocodePlace *place);
 
 const char *geocode_place_get_osm_id               (GeocodePlace *place);
+GeocodePlaceOsmType geocode_place_get_osm_type     (GeocodePlace *place);
 
 G_END_DECLS
 
diff --git a/geocode-glib/test-gcglib.c b/geocode-glib/test-gcglib.c
index 392ca94..0b97d5f 100644
--- a/geocode-glib/test-gcglib.c
+++ b/geocode-glib/test-gcglib.c
@@ -328,6 +328,38 @@ test_search_lat_long (void)
        g_list_free_full (res, (GDestroyNotify) g_object_unref);
 }
 
+static void
+test_osm_type (void)
+{
+       GeocodeForward *object;
+       GError *error = NULL;
+       GList *res;
+       GeocodePlace *place;
+       guint i;
+       struct {
+               char *search_string;
+               GeocodePlaceOsmType osm_type;
+       } types[] = {
+               { "Drottning Christinas väg", GEOCODE_PLACE_OSM_TYPE_WAY },
+               { "North dakota", GEOCODE_PLACE_OSM_TYPE_RELATION },
+               { "Grand canyon", GEOCODE_PLACE_OSM_TYPE_NODE }
+       };
+       for (i = 0; i < G_N_ELEMENTS (types); i++) {
+               object = geocode_forward_new_for_string (types[i].search_string);
+               res = geocode_forward_search (object, &error);
+               if (res == NULL) {
+                       g_warning ("Failed at geocoding: %s", error->message);
+                       g_error_free (error);
+               }
+               g_assert (res != NULL);
+               g_object_unref (object);
+
+               place = res->data;
+               g_assert (geocode_place_get_osm_type (place) == types[i].osm_type);
+               g_list_free_full (res, (GDestroyNotify) g_object_unref);
+       }
+}
+
 /* Test case from:
  * http://andrew.hedges.name/experiments/haversine/ */
 static void
@@ -569,6 +601,7 @@ int main (int argc, char **argv)
                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);
+               g_test_add_func ("/geocode/osm_type", test_osm_type);
                return g_test_run ();
        }
 


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