Youngae Kang <youngae.kang@samsung.com>
-Yunhan Kim <yhan.kim@samsung.com>
-Genie Kim <daejins.kim@samsung.com>
Minjune Kim <sena06.kim@samsung.com>
+Genie Kim <daejins.kim@samsung.com>
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADER([config.h])
-AC_CONFIG_SRCDIR([modules/geoclue-nominatim.c])
+AC_CONFIG_SRCDIR([modules])
AM_INIT_AUTOMAKE([1.10.2 foreign -Wall -Werror])
# Check programs for making executable
AC_MSG_RESULT($has_visibility)
# Checks libraries
-PKG_CHECK_MODULES(MODULE, [glib-2.0 gmodule-2.0 geoclue location])
+PKG_CHECK_MODULES(MODULE, [glib-2.0 gmodule-2.0 geoclue location libcurl json-glib-1.0 dlog])
AC_SUBST(MODULE_LIBS)
AC_SUBST(MODULE_CFLAGS)
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
pkgdir = $(libdir)/location/module
-pkg_LTLIBRARIES = libgeocode0.la
+pkg_LTLIBRARIES = libmap-service-osm.la
-# geoclue nominatim plugin
-libgeocode0_la_SOURCES = geoclue-nominatim.c $(utility)
-libgeocode0_la_CFLAGS = \
+# map-serivce OpenStreetMap plugin
+libmap_service_osm_la_SOURCES = osm/location-osm.c \
+ osm/location-osm-route.c \
+ osm/location-osm-poi.c \
+ osm/location-osm-geocode.c \
+ osm/osm-http.c \
+ osm/osm-route-yours.c \
+ $(utility)
+libmap_service_osm_la_CFLAGS = \
-fPIC\
$(MODULE_CFLAGS)
-libgeocode0_la_LIBADD = \
+libmap_service_osm_la_LIBADD = \
$(MODULE_LIBS)
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+
+#include <location-module.h>
+
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-velocity.h>
+#include <geoclue/geoclue-provider.h>
+#include <dlfcn.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "log.h"
+
+typedef struct{
+ char devname[256];
+ GeocluePosition *pos;
+ GeoclueVelocity *vel;
+ LocModStatusCB status_cb;
+ LocModPositionCB pos_cb;
+ LocModVelocityCB vel_cb;
+ gpointer userdata;
+ gboolean is_started;
+} GeoclueGpsdData;
+
+static void
+status_callback (GeoclueProvider *provider,
+ gint status,
+ gpointer userdata)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)userdata;
+ g_return_if_fail(gpsd->status_cb);
+
+ switch(status){
+ case GEOCLUE_STATUS_ERROR:
+ case GEOCLUE_STATUS_UNAVAILABLE:
+ case GEOCLUE_STATUS_ACQUIRING:
+ MOD_LOGD("Status callback>> GEOCLUE_STATUS_ACQUIRING/ERROR/UNAVAILABLE");
+ gpsd->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gpsd->userdata);
+ break;
+ case GEOCLUE_STATUS_AVAILABLE:
+ MOD_LOGD("Status callback>> GEOCLUE_STATUS_AVAILABLE");
+ gpsd->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gpsd->userdata);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+position_callback (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ gpointer userdata)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)userdata;
+ g_return_if_fail(gpsd->pos_cb);
+
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+ double vert_acc;
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, &vert_acc);
+
+ LocationPosition *pos = NULL;
+ LocationAccuracy *acc = NULL;
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
+ pos = location_position_new (timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
+ else pos = location_position_new (timestamp, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
+ } else pos = location_position_new (0, 0, 0, 0, LOCATION_STATUS_NO_FIX);
+
+ if (accuracy) {
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+ double vert_acc;
+ geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, &vert_acc);
+ acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
+ } else acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, horiz_acc, vert_acc);
+
+ MOD_LOGD("Position callback>> time(%d) lat(%f) long(%f) alt(%f) status(%d) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
+ pos->timestamp, pos->latitude, pos->longitude, pos->altitude, pos->status,
+ acc->level, acc->horizontal_accuracy, acc->vertical_accuracy);
+ gpsd->pos_cb(TRUE, pos, acc, gpsd->userdata);
+ location_position_free (pos);
+ location_accuracy_free (acc);
+}
+
+static void
+velocity_callback (GeoclueVelocity *velocity,
+ GeoclueVelocityFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ gpointer userdata)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)userdata;
+ g_return_if_fail(gpsd->vel_cb);
+
+ LocationVelocity *vel = NULL;
+ LocationAccuracy *acc = NULL;
+
+ if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED &&
+ fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
+ if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB) vel = location_velocity_new (timestamp, speed, direction, climb);
+ else vel = location_velocity_new (timestamp, speed, direction, 0);
+ acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
+ } else {
+ vel = location_velocity_new (0, 0, 0, 0);
+ acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ MOD_LOGD("Velocity callback>> timestamp(%d) speed(%f) direction(%f) climb(%f) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
+ vel->timestamp, vel->speed, vel->direction, vel->climb,
+ acc->level, acc->horizontal_accuracy, acc->vertical_accuracy);
+
+ gpsd->vel_cb(TRUE, vel, acc, gpsd->userdata);
+ location_velocity_free (vel);
+ location_accuracy_free (acc);
+}
+
+static void
+_unref_geoclue(GeoclueGpsdData* gpsd)
+{
+ if(gpsd->pos) {
+ g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gpsd->pos)), G_CALLBACK (status_callback), gpsd);
+ g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gpsd->pos)), G_CALLBACK (position_callback), gpsd);
+ g_object_unref (gpsd->pos);
+ gpsd->pos = NULL;
+ }
+
+ if( gpsd->vel != NULL){
+ g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gpsd->vel)), G_CALLBACK (velocity_callback), gpsd);
+ g_object_unref (gpsd->vel);
+ gpsd->vel = NULL;
+ }
+ gpsd->is_started = FALSE;
+}
+
+static gboolean
+_ref_geoclue(GeoclueGpsdData* gpsd)
+{
+ if(gpsd->is_started == TRUE){
+ MOD_LOGW ("geoclue-gpsd is alredy started");
+ return TRUE;
+ }
+
+ gchar *service, *path;
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.Gpsd");
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/Gpsd");
+
+ if(!gpsd->pos){
+ gpsd->pos = geoclue_position_new (service, path);
+ }
+ if(!gpsd->vel){
+ gpsd->vel = geoclue_velocity_new (service, path);
+ }
+ g_free (service);
+ g_free (path);
+ if(!gpsd->pos || !gpsd->vel){
+ MOD_LOGW ("Error while creating Geoclue object.");
+ _unref_geoclue(gpsd);
+ return FALSE;
+ }
+
+ gpsd->is_started = TRUE;
+ g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gpsd->pos)), "status-changed", G_CALLBACK (status_callback), gpsd);
+ g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gpsd->pos)), "position-changed", G_CALLBACK (position_callback), gpsd);
+ g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gpsd->vel)), "velocity-changed", G_CALLBACK (velocity_callback), gpsd);
+
+ return TRUE;
+}
+
+static int
+start(gpointer handle, LocModStatusCB status_cb, LocModPositionCB pos_cb, LocModVelocityCB vel_cb, gpointer userdata)
+{
+ MOD_LOGD("start");
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(vel_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ gpsd->status_cb = status_cb;
+ gpsd->pos_cb = pos_cb;
+ gpsd->vel_cb = vel_cb;
+ gpsd->userdata = userdata;
+ if (!_ref_geoclue(gpsd)) return LOCATION_ERROR_NOT_AVAILABLE;
+ return LOCATION_ERROR_NONE;
+}
+
+static int
+stop(gpointer handle)
+{
+ MOD_LOGD("stop");
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gpsd->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+ _unref_geoclue(gpsd);
+ gpsd->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gpsd->userdata);
+ return LOCATION_ERROR_NONE;
+}
+
+static int
+get_position(
+ gpointer handle,
+ LocationPosition **position,
+ LocationAccuracy **accuracy)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gpsd->pos, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
+
+ GeocluePositionFields fields;
+ int timestamp;
+ double lat, lon, alt;
+ GeoclueAccuracy *_accuracy = NULL;
+ GError *error = NULL;
+
+ fields = geoclue_position_get_position (gpsd->pos, ×tamp,
+ &lat, &lon, &alt,
+ &_accuracy, &error);
+ if (error) {
+ MOD_LOGD ("Error getting position: %s", error->message);
+ g_error_free (error);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) *position = location_position_new (timestamp, lat, lon, alt, LOCATION_STATUS_3D_FIX);
+ else *position = location_position_new (timestamp, lat, lon, 0, LOCATION_STATUS_2D_FIX);
+ } else *position = location_position_new (0, 0, 0, 0, LOCATION_STATUS_NO_FIX);
+
+ if (_accuracy) {
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+ double vert_acc;
+ geoclue_accuracy_get_details (_accuracy, &level, &horiz_acc, &vert_acc);
+ *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
+ geoclue_accuracy_free (_accuracy);
+ } else *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int
+get_velocity(
+ gpointer handle,
+ LocationVelocity **velocity,
+ LocationAccuracy **accuracy)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gpsd->vel, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
+
+ GeoclueVelocityFields fields;
+ int timestamp;
+ double spd, dir, climb;
+ GError *error = NULL;
+
+ fields = geoclue_velocity_get_velocity (gpsd->vel, ×tamp,
+ &spd, &dir, &climb,
+ &error);
+ if (error) {
+ MOD_LOGD ("Error getting velocity: %s", error->message);
+ g_error_free (error);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED &&
+ fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
+ if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB) *velocity = location_velocity_new (timestamp, spd, dir, climb);
+ else *velocity = location_velocity_new (timestamp, spd, dir, 0);
+ *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
+ } else {
+ *velocity = location_velocity_new (0, 0, 0, 0);
+ *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ return LOCATION_ERROR_NONE;
+}
+
+static int
+get_nmea(gpointer handle,
+ char **nmea_data)
+{
+ MOD_LOGD("get_nmea: not available");
+ return LOCATION_ERROR_NOT_AVAILABLE;
+}
+
+static int
+get_satellite(gpointer handle,
+ LocationSatellite **satellite)
+{
+ MOD_LOGD("get_satellite: not available");
+ return LOCATION_ERROR_NOT_AVAILABLE;
+}
+
+static int
+set_devname(gpointer handle,
+ const char *devname)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gpsd->devname, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
+ MOD_LOGD("set_devname: %s --> %s", gpsd->devname, devname);
+ g_stpcpy(gpsd->devname, devname);
+
+ return LOCATION_ERROR_NONE;
+}
+
+
+static int
+get_devname(gpointer handle,
+ char **devname)
+{
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_val_if_fail(gpsd, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gpsd->devname, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
+
+ *devname = g_strdup(gpsd->devname);
+ MOD_LOGD("get_devname: %s", *devname);
+
+ return LOCATION_ERROR_NONE;
+}
+
+LOCATION_MODULE_API gpointer
+init(LocModGpsOps* ops)
+{
+ MOD_LOGD("init");
+ g_return_val_if_fail(ops, NULL);
+ ops->start = start;
+ ops->stop = stop ;
+ ops->get_position = get_position;
+ ops->get_velocity = get_velocity;
+ Dl_info info;
+ if (dladdr(&get_position, &info) == 0) {
+ MOD_LOGD("failed to get module name");
+ } else if (g_str_has_prefix(info.dli_fname, "gps")) {
+ ops->get_nmea = get_nmea;
+ ops->get_satellite = get_satellite;
+ ops->set_devname = set_devname;
+ ops->get_devname = get_devname;
+ }
+
+ GeoclueGpsdData* gpsd = g_new0(GeoclueGpsdData, 1);
+ g_return_val_if_fail(gpsd, NULL);
+
+ g_stpcpy(gpsd->devname, "/dev/rfcomm0");
+ gpsd->pos = NULL;
+ gpsd->vel = NULL;
+ gpsd->status_cb= NULL;
+ gpsd->pos_cb = NULL;
+ gpsd->vel_cb = NULL;
+ gpsd->userdata = NULL;
+ gpsd->is_started = FALSE;
+
+ return (gpointer)gpsd;
+}
+
+LOCATION_MODULE_API void
+shutdown(gpointer handle)
+{
+ MOD_LOGD("shutdown");
+ GeoclueGpsdData* gpsd = (GeoclueGpsdData*)handle;
+ g_return_if_fail(gpsd);
+ _unref_geoclue(gpsd);
+ if(gpsd->status_cb) gpsd->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gpsd->userdata);
+ g_free(gpsd);
+}
/*
* location-module
*
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
*
- * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
- * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#ifndef __LOCATION_LOG_H__
#define __LOCATION_LOG_H__
-#define TAG_LOCATION "location_mod"
+#define TAG_LOCATION "LOCATION_OSM"
#ifdef MOD_DLOG_DEBUG // if debug mode, show filename & line number
#include <dlog.h>
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "log.h"
+#include "location-osm.h"
+
+static GHashTable*
+_get_geoclue_addr_from_location_addr (const LocationAddress *address)
+{
+ if (!address) return NULL;
+
+ GHashTable *geoclue_addr = geoclue_address_details_new();
+ if (address->street) {
+ if (address->building_number) {
+ char *street_addr = g_strdup_printf ("%s %s", address->building_number, address->street);
+ geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET, street_addr);
+ g_free (street_addr);
+ } else geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET, address->street);
+ }
+ if (address->district) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_AREA, address->district);
+ if (address->city) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_LOCALITY, address->city);
+ if (address->state) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_REGION, address->state);
+ if (address->country_code) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_COUNTRY, address->country_code);
+ if (address->postal_code) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_POSTALCODE, address->postal_code);
+
+ return geoclue_addr;
+}
+
+static LocationAddress*
+_get_location_addr_from_geoclue_addr (GHashTable *geoclue_addr)
+{
+ if (!geoclue_addr) return NULL;
+
+ LocationAddress *addr = NULL;
+
+ gchar *country, *region, *locality, *postalcode, *area, *street;
+
+ country = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ region = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_REGION);
+ locality = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_LOCALITY);
+ area = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_AREA);
+ postalcode = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_POSTALCODE);
+ street = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET);
+
+ addr = location_address_new (NULL, street, area, locality, region, NULL, postalcode, NULL, country, NULL);
+ return addr;
+}
+
+
+static LocationAccuracy *
+_get_location_acc_from_geoclue_acc (GeoclueAccuracy *acc)
+{
+ if (!acc) return NULL;
+
+ LocationAccuracy *accuracy = NULL;
+ GeoclueAccuracyLevel level;
+ double horiz_acc;
+ double vert_acc;
+ geoclue_accuracy_get_details (acc, &level, &horiz_acc, &vert_acc);
+
+ if (level == GEOCLUE_ACCURACY_LEVEL_DETAILED) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
+ else if (level == GEOCLUE_ACCURACY_LEVEL_STREET) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, horiz_acc, vert_acc);
+ else if (level == GEOCLUE_ACCURACY_LEVEL_POSTALCODE) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, horiz_acc, vert_acc);
+ else if (level == GEOCLUE_ACCURACY_LEVEL_LOCALITY) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, horiz_acc, vert_acc);
+ else if (level == GEOCLUE_ACCURACY_LEVEL_REGION) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, horiz_acc, vert_acc);
+ else if (level == GEOCLUE_ACCURACY_LEVEL_COUNTRY) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, horiz_acc, vert_acc);
+ else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+
+ return accuracy;
+}
+
+static void
+address_cb (GeoclueReverseGeocode *revgeocode,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ OsmHandleData* data = (OsmHandleData*)userdata;
+ g_return_if_fail(data->addr_cb);
+
+ LocationAddress *addr = NULL;
+ LocationAccuracy *acc = NULL;
+ LocationError err = LOCATION_ERROR_NONE;
+
+ if (error) {
+ MOD_LOGW ("Error getting reverse geocode: %s", error->message);
+ err = LOCATION_ERROR_NOT_AVAILABLE;
+ } else {
+ if (accuracy) acc = _get_location_acc_from_geoclue_acc (accuracy);
+ else acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+
+ if (details) addr = _get_location_addr_from_geoclue_addr (details);
+ }
+
+ data->addr_cb (err, addr, acc, data->userdata);
+ if (addr) location_address_free (addr);
+ if (acc) location_accuracy_free (acc);
+ g_free (data);
+}
+
+static void
+_free_pos_list_item(gpointer data)
+{
+ g_return_if_fail(data);
+
+ LocationPosition *position = (LocationPosition *)data;
+ location_position_free(position);
+}
+
+static void
+_free_acc_list_item(gpointer data)
+{
+ g_return_if_fail(data);
+
+ LocationAccuracy *accuracy = (LocationAccuracy *)data;
+ location_accuracy_free(accuracy);
+}
+
+static void
+position_cb (GeoclueGeocode *geocode,
+ GeocluePositionFields fields,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error,
+ gpointer userdata)
+{
+ OsmHandleData* data = (OsmHandleData*)userdata;
+ GList *pos_list = NULL;
+ GList *acc_list = NULL;
+
+ g_return_if_fail(data->pos_cb);
+
+ LocationPosition *pos = NULL;
+ LocationAccuracy *acc = NULL;
+ LocationError err = LOCATION_ERROR_NONE;
+
+ if (error) {
+ MOD_LOGW ("Error getting geocode: %s", error->message);
+ err = LOCATION_ERROR_NOT_AVAILABLE;
+ } else {
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
+ else pos = location_position_new (0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
+
+ pos_list = g_list_append(pos_list, pos);
+ } else {
+ err = LOCATION_ERROR_NOT_FOUND;
+ }
+
+ if (accuracy) {
+ acc = _get_location_acc_from_geoclue_acc (accuracy);
+ acc_list = g_list_append(acc_list, acc);
+ }
+ }
+ data->pos_cb (err, pos_list, acc_list, data->userdata);
+
+ if (pos_list) g_list_free_full(pos_list, _free_pos_list_item);
+ if (acc_list) g_list_free_full(acc_list, _free_acc_list_item);
+ g_free (data);
+
+}
+
+
+int
+osm_get_geocode (OsmHandle *osm,
+ const LocationAddress *addr,
+ GList **pos_list,
+ GList **acc_list)
+{
+ double lat, lon, alt;
+ GeoclueAccuracy *geoclue_acc = NULL;
+ GError *error = NULL;
+ LocationPosition *pos = NULL;
+ LocationAccuracy *acc = NULL;
+ LocationError err = LOCATION_ERROR_NONE;
+
+ GHashTable* geoclue_addr = _get_geoclue_addr_from_location_addr (addr);
+ GeocluePositionFields fields = geoclue_geocode_address_to_position (osm->geocoder, geoclue_addr,
+ &lat, &lon, &alt,
+ &geoclue_acc, &error);
+ g_hash_table_destroy (geoclue_addr);
+
+ if (error) {
+ MOD_LOGW ("Error getting geocode: %s", error->message);
+ g_error_free (error);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, lat, lon, alt, LOCATION_STATUS_3D_FIX);
+ else pos = location_position_new (0, lat, lon, 0, LOCATION_STATUS_2D_FIX);
+
+ *pos_list = g_list_append(*pos_list, pos);
+ }
+ else {
+ err = LOCATION_ERROR_NOT_FOUND;
+ }
+
+ if (geoclue_acc) {
+ acc = _get_location_acc_from_geoclue_acc (geoclue_acc);
+ geoclue_accuracy_free (geoclue_acc);
+
+ *acc_list = g_list_append(*acc_list, acc);
+ }
+
+ if (pos) location_position_free (pos);
+ if (acc) location_accuracy_free (acc);
+
+ return err;
+}
+
+int
+osm_get_geocode_async (OsmHandle *osm,
+ const LocationAddress * addr,
+ LocationPositionCB callback,
+ gpointer userdata)
+{
+ GHashTable* geoclue_addr = _get_geoclue_addr_from_location_addr (addr);
+ OsmHandleData *data = g_new0 (OsmHandleData, 1);
+ data->pos_cb = callback;
+ data->userdata = userdata;
+ geoclue_geocode_address_to_position_async (osm->geocoder, geoclue_addr, position_cb, data);
+ g_hash_table_destroy (geoclue_addr);
+
+ return LOCATION_ERROR_NONE;
+}
+
+int
+osm_get_geocode_freetext(OsmHandle *osm,
+ const const gchar* addr,
+ GList **pos_list,
+ GList **acc_list)
+{
+ double lat, lon, alt;
+ GeoclueAccuracy *geoclue_acc = NULL;
+ GError *error = NULL;
+ LocationPosition *pos = NULL;
+ LocationAccuracy *acc = NULL;
+ LocationError err = LOCATION_ERROR_NONE;
+
+ GeocluePositionFields fields = geoclue_geocode_freeform_address_to_position (osm->geocoder, addr,
+ &lat, &lon, &alt,
+ &geoclue_acc, &error);
+ if (error) {
+ MOD_LOGW ("Error getting geocode: %s", error->message);
+ g_error_free (error);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
+ if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, lat, lon, alt, LOCATION_STATUS_3D_FIX);
+ else pos = location_position_new (0, lat, lon, 0, LOCATION_STATUS_2D_FIX);
+ *pos_list = g_list_append(*pos_list, pos);
+ }
+ else {
+ err = LOCATION_ERROR_NOT_FOUND;
+ }
+
+ if (geoclue_acc) {
+ acc = _get_location_acc_from_geoclue_acc (geoclue_acc);
+ geoclue_accuracy_free (geoclue_acc);
+ *acc_list = g_list_append(*acc_list, acc);
+ }
+
+ if (pos) location_position_free (pos);
+ if (acc) location_accuracy_free (acc);
+ return err;
+}
+
+int
+osm_get_geocode_freetext_async (OsmHandle *osm,
+ const gchar* addr,
+ LocationPositionCB callback,
+ gpointer userdata)
+{
+ OsmHandleData *data = g_new0 (OsmHandleData, 1);
+ data->pos_cb = callback;
+ data->userdata = userdata;
+ geoclue_geocode_freeform_address_to_position_async (osm->geocoder, addr, position_cb, data);
+
+ return LOCATION_ERROR_NONE;
+}
+
+int
+osm_get_reverse_geocode(OsmHandle *osm,
+ const LocationPosition *pos,
+ LocationAddress **addr,
+ LocationAccuracy **acc)
+{
+ GeoclueAccuracy *addr_acc = NULL;
+ GError *error = NULL;
+ GHashTable* geoclue_addr = NULL;
+
+ double lat = pos->latitude;
+ double lon = pos->longitude;
+ GeoclueAccuracy *pos_acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_DETAILED, 0.0, 0.0);
+
+ gboolean success = geoclue_reverse_geocode_position_to_address (osm->rev_geocoder, lat, lon,
+ pos_acc, &geoclue_addr,
+ &addr_acc, &error);
+ geoclue_accuracy_free (pos_acc);
+
+ if (!success || error) {
+ MOD_LOGW ("Error getting reverse geocode: %s", error->message);
+ g_error_free (error);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ if (addr_acc) {
+ *acc = _get_location_acc_from_geoclue_acc (addr_acc);
+ geoclue_accuracy_free (addr_acc);
+ } else *acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
+ if (geoclue_addr) {
+ *addr = _get_location_addr_from_geoclue_addr (geoclue_addr);
+ g_hash_table_destroy (geoclue_addr);
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+int
+osm_get_reverse_geocode_async (OsmHandle *osm,
+ const LocationPosition *pos,
+ LocationAddressCB callback,
+ gpointer userdata)
+{
+ double lat = pos->latitude;
+ double lon = pos->longitude;
+ GeoclueAccuracy *pos_acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_DETAILED, 0.0, 0.0);;
+ OsmHandleData *data = g_new0 (OsmHandleData, 1);
+ data->addr_cb = callback;
+ data->userdata = userdata;
+ geoclue_reverse_geocode_position_to_address_async (osm->rev_geocoder,
+ lat, lon, pos_acc,
+ address_cb, data);
+ geoclue_accuracy_free (pos_acc);
+
+ return LOCATION_ERROR_NONE;
+}
+
+
+
+
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCATION_OSM_GEOCODE_H__
+#define __LOCATION_OSM_GEOCODE_H__
+
+
+
+#include "location-osm.h"
+
+int osm_get_geocode (OsmHandle *osm, const LocationAddress *addr, GList **pos_list, GList **acc_list);
+
+int osm_get_geocode_async (OsmHandle *osm, const LocationAddress * addr, LocationPositionCB callback, gpointer userdata);
+
+int osm_get_geocode_freetext(OsmHandle *osm, const const gchar* addr, GList **pos_list, GList **acc_list);
+
+int osm_get_geocode_freetext_async (OsmHandle *osm, const gchar* addr, LocationPositionCB callback, gpointer userdata);
+
+int osm_get_reverse_geocode(OsmHandle *osm, const LocationPosition *pos, LocationAddress **addr, LocationAccuracy **acc);
+
+int osm_get_reverse_geocode_async (OsmHandle *osm, const LocationPosition *pos, LocationAddressCB callback, gpointer userdata);
+
+
+#endif /* __LOCATION_OSM_GEOCODE_H__ */
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <vconf.h>
+#include <location.h>
+#include <location-map-service.h>
+#include <location-map-service-ext.h>
+#include <geoclue/geoclue-poi.h>
+#include <geoclue/geoclue-landmark.h>
+#include "log.h"
+#include "location-osm.h"
+#include "location-osm-poi.h"
+
+static int g_req_id = 0;
+
+static void
+_get_lang (gchar country_code[3], gchar lang_code[3])
+{
+ if (!country_code || !lang_code) return;
+ gchar* langset = vconf_get_str(VCONFKEY_LANGSET);
+ MOD_LOGW("getenv: %s", langset);
+
+ if(langset == NULL){
+ lang_code[0] = 'E';
+ lang_code[1] = 'N';
+ lang_code[2] = '\0';
+ country_code[0] = 'U';
+ country_code[1] = 'S';
+ country_code[2] = '\0';
+ }else{
+ gchar* langset_upper = g_ascii_strup(langset, -1);
+ lang_code[0] = langset_upper[0];
+ lang_code[1] = langset_upper[1];
+ lang_code[2] = '\0';
+ country_code[0] = langset_upper[3];
+ country_code[1] = langset_upper[4];
+ country_code[2] = '\0';
+ g_free(langset_upper);
+ }
+ MOD_LOGW("Language: %s, Country: %s", lang_code, country_code);
+}
+
+static void
+_free_landmark(gpointer data)
+{
+ g_return_if_fail (data);
+
+ LocationLandmark *landmark = (LocationLandmark *)data;
+ location_landmark_free(landmark);
+}
+
+
+static void
+_poi_callback(GeocluePoi *poi, int count, GPtrArray *landmark, GError *error, gpointer userdata)
+{
+ OsmHandleData *data = (OsmHandleData *)userdata;
+
+ g_return_if_fail(data);
+ g_return_if_fail(data->poi_cb);
+
+ int req_id = data->req_id;
+ int err = LOCATION_ERROR_NONE;
+ GValueArray *vals = NULL;
+ GList *landmark_list = NULL;
+ LocationLandmark *land = NULL;
+ GeoclueLandmark landmark_data = {0, };
+ LocationBoundary *bounding_box = NULL;
+ LocationPosition *left_top = NULL;
+ LocationPosition *right_bottom = NULL;
+
+ int idx = 0;
+ if (!landmark || error) {
+ MOD_LOGE("Landmark[%p] is NULL or Error occurs", landmark);
+ err = LOCATION_ERROR_UNKNOWN;
+ }
+ else {
+ MOD_LOGE("Count [%d]", count);
+ for (; idx < count; idx++) {
+ vals = (GValueArray *) g_ptr_array_index(landmark, idx);
+ if (!vals) {
+ break;
+ }
+
+ landmark_data.id = g_value_get_int (g_value_array_get_nth(vals, 0));
+ landmark_data.rank = g_value_get_int (g_value_array_get_nth(vals, 1));
+ landmark_data.lat = g_value_get_double (g_value_array_get_nth(vals, 2));
+ landmark_data.lon = g_value_get_double (g_value_array_get_nth(vals, 3));
+ landmark_data.boundary_left = g_value_get_double (g_value_array_get_nth(vals, 4));
+ landmark_data.boundary_top = g_value_get_double (g_value_array_get_nth(vals, 5));
+ landmark_data.boundary_right = g_value_get_double (g_value_array_get_nth(vals, 6));
+ landmark_data.boundary_bottom = g_value_get_double (g_value_array_get_nth(vals, 7));
+ landmark_data.name = g_value_dup_string (g_value_array_get_nth(vals, 8));
+ landmark_data.icon = g_value_dup_string (g_value_array_get_nth(vals, 9));
+ landmark_data.house = g_value_dup_string (g_value_array_get_nth(vals, 10));
+ landmark_data.road = g_value_dup_string (g_value_array_get_nth(vals, 11));
+ landmark_data.village = g_value_dup_string (g_value_array_get_nth(vals, 12));
+ landmark_data.suburb = g_value_dup_string (g_value_array_get_nth(vals, 13));
+ landmark_data.postcode = g_value_dup_string (g_value_array_get_nth(vals, 14));
+ landmark_data.city = g_value_dup_string (g_value_array_get_nth(vals, 15));
+ landmark_data.county = g_value_dup_string (g_value_array_get_nth(vals, 16));
+ landmark_data.country = g_value_dup_string (g_value_array_get_nth(vals, 17));
+ landmark_data.country_code = g_value_dup_string (g_value_array_get_nth(vals, 18));
+
+ land = location_landmark_new();
+
+ location_landmark_set_id (land, (guint)landmark_data.id);
+ location_landmark_set_priority(land, (guint)landmark_data.rank);
+ location_landmark_set_position (land, location_position_new (0, landmark_data.lat, landmark_data.lon, 0.0, LOCATION_STATUS_2D_FIX));
+
+ location_landmark_set_name (land, landmark_data.name);
+ location_landmark_set_address (land, location_address_new (NULL, landmark_data.house, landmark_data.village, landmark_data.city, landmark_data.county, NULL, landmark_data.postcode, NULL, landmark_data.country_code, NULL));
+ location_landmark_set_property (land, "ICON", landmark_data.icon);
+
+ if (!landmark_data.boundary_left || landmark_data.boundary_top || landmark_data.boundary_right || landmark_data.boundary_bottom) {
+ left_top = location_position_new (0, landmark_data.boundary_left, landmark_data.boundary_top, 0.0, LOCATION_STATUS_2D_FIX);
+ right_bottom = location_position_new (0, landmark_data.boundary_right, landmark_data.boundary_bottom, 0.0, LOCATION_STATUS_2D_FIX);
+ bounding_box = location_boundary_new_for_rect (left_top, right_bottom);
+ if (bounding_box) {
+ location_landmark_set_bounding_box (land, bounding_box);
+ location_boundary_free(bounding_box);
+ }
+
+ if (left_top) location_position_free (left_top);
+ if (right_bottom) location_position_free (right_bottom);
+
+ left_top = NULL;
+ right_bottom = NULL;
+ bounding_box = NULL;
+ }
+
+
+ landmark_list = g_list_append (landmark_list, land);
+ }
+ }
+
+ MOD_LOGW ("Calling LocationPOICB");
+ data->poi_cb (err, req_id, landmark_list, NULL, NULL, data->userdata);
+
+ g_list_free_full (landmark_list, _free_landmark);
+}
+
+int
+osm_search_poi_by_position(OsmHandle *osm,
+ const LocationPOIFilter *filter,
+ const LocationPosition *position,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb,
+ const gpointer user_data,
+ guint *req_id)
+{
+ int left = 0.0, top = 0.0, right = 0.0, bottom = 0.0;
+ *req_id = ++g_req_id;
+
+ OsmHandleData *data = g_new0 (OsmHandleData, 1);
+ data->req_id = *req_id;
+ data->poi_cb = cb;
+ data->userdata = user_data;
+
+ gchar *keyword = NULL, *lang = NULL, *country_code = NULL;
+ int max_result = 0;
+
+ keyword = location_poi_filter_get(filter, "KEYWORD");
+ if (!keyword) {
+ MOD_LOGW("OSM supports only keyword filter.");
+ return LOCATION_ERROR_PARAMETER;
+
+ }
+
+ lang = location_map_pref_get_language (svc_pref);
+ country_code = location_map_pref_get_country(svc_pref);
+ max_result = location_poi_pref_get_max_result(pref);
+
+ geoclue_poi_search_by_position_async (osm->poi, keyword, lang, country_code, max_result, left, top, right, bottom, _poi_callback, data);
+
+ return LOCATION_ERROR_NONE;
+}
+
+int
+osm_search_poi_by_area(OsmHandle *osm,
+ const LocationPOIFilter *filter,
+ const LocationBoundary *boundary,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb,
+ const gpointer user_data,
+ guint *req_id)
+{
+ *req_id = ++g_req_id;
+
+ OsmHandleData *data = g_new0 (OsmHandleData, 1);
+
+ gchar sys_country[3] = {0, }, sys_lang[3] = {0, };
+ gchar *keyword = NULL, *lang = NULL, *country_code = NULL;
+ int max_result = 0;
+ gdouble left = 0.0, top = 0.0, right = 0.0, bottom = 0.0;
+
+ data->req_id = *req_id;
+ data->poi_cb = cb;
+ data->userdata = user_data;
+
+ _get_lang (sys_country, sys_lang);
+ keyword = location_poi_filter_get(filter, "KEYWORD");
+ if (!keyword) {
+ MOD_LOGW("OSM supports only keyword filter.");
+ return LOCATION_ERROR_PARAMETER;
+
+ }
+
+ lang = location_map_pref_get_language (svc_pref);
+// if (!lang) lang = sys_lang;
+
+ country_code = location_map_pref_get_country(svc_pref);
+// if (!country_code) country_code = sys_country;
+
+ max_result = location_poi_pref_get_max_result(pref);
+
+ LocationPosition *left_top = boundary->rect.left_top;
+ LocationPosition *right_bottom = boundary->rect.right_bottom;
+
+ left = left_top->latitude;
+ top = left_top->longitude;
+ right = right_bottom->latitude;
+ bottom = right_bottom->longitude;
+
+ geoclue_poi_search_by_position_async (osm->poi, keyword, lang, country_code, max_result, left, top, right, bottom, _poi_callback, data);
+
+ return LOCATION_ERROR_NONE;
+}
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCATION_OSM_POI_H__
+#define __LOCATION_OSM_POI_H__
+
+#include <glib.h>
+#include <location-map-types.h>
+
+int osm_search_poi_by_position(OsmHandle *osm,
+ const LocationPOIFilter *filter,
+ const LocationPosition *position,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb,
+ const gpointer user_data,
+ guint *req_id);
+
+int osm_search_poi_by_area(OsmHandle *osm,
+ const LocationPOIFilter *filter,
+ const LocationBoundary *boundary,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb,
+ const gpointer user_data,
+ guint *req_id);
+
+#endif /* __LOCATION_OSM_ROUTE_H__ */
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <json-glib.h>
+#include <stdlib.h>
+
+#include <location.h>
+#include <location-map-service.h>
+#include <location-map-service-ext.h>
+#include "log.h"
+#include "osm-route-yours.h"
+#include "location-osm-route.h"
+#include "osm-http.h"
+
+static char *
+_create_route_url (const LocationPosition *origin, const LocationPosition *destination, const GList *waypoint, const LocationMapPref *svc_pref, const LocationRoutePreference *pref)
+{
+ gdouble flon = 0.0, flat = 0.0, tlon = 0.0, tlat = 0.0;
+ GList *ways = NULL;
+ char *mode = "motorcar";
+
+
+ flon = origin->longitude;
+ flat = origin->latitude;
+ tlon = destination->longitude;
+ tlat = destination->latitude;
+
+#if 0
+ if (waypoint)
+#endif
+
+ return yournavi_create_url (flat, flon, tlat, tlon, ways, 1, mode, 1);
+ //yournavi_create_url (gdouble flon, gdouble flat, gdouble tlon, gdouble tlat, const GList *ways, int type, char *mode, int instruction);
+
+}
+
+static void
+_position_foreach_cb (gpointer data, gpointer user_data)
+{
+ if (!data) return ;
+
+ osm_data_t *ndata = (osm_data_t *)user_data;
+
+ LocationPosition *pos = (LocationPosition*) data;
+ LocationPosition *duplicated = location_position_copy (pos);
+
+ ndata->waypoint = g_list_append(ndata->waypoint, duplicated);
+
+}
+
+#if 0
+static void
+_position_destory_cb (gpointer data)
+{
+ if (!data) return;
+
+ LocationPosition *pos = (LocationPosition *)data;
+
+ location_position_free (pos);
+}
+#endif
+
+static void
+_get_position_from_coordinates (JsonArray *_array, guint index, JsonNode *element, gpointer user_data)
+{
+ GList **pos_list = (GList **)user_data;
+ gdouble lat = 0.0, lon = 0.0;
+
+ JsonArray *array = json_node_get_array(element);
+ if (array) {
+ lon = json_array_get_double_element (array, 0);
+ lat = json_array_get_double_element (array, 1);
+ *pos_list = g_list_append(*pos_list, location_position_new(0, lat, lon, 0.0, LOCATION_STATUS_2D_FIX));
+ }
+
+}
+
+int
+convert_data_to_location_service (const char *result, int result_len, LocationPosition *origin, LocationPosition *dest, GList **route_list)
+{
+ gboolean ret = FALSE;
+ GError *err = NULL;
+ JsonParser* parser = json_parser_new ();
+ JsonNode* node = NULL;
+ JsonObject *obj = NULL;
+ JsonObject *properties = NULL;
+ JsonArray *positions = NULL;
+// gchar *instructions = NULL;
+
+ GList *pos_list = NULL;
+ LocationRoute *route = NULL;
+ gchar *str_distance = NULL, *str_duration = NULL;
+ gdouble distance = 0.0;
+ glong duration = 0;
+
+ if (!result) return -1;
+
+ ret = json_parser_load_from_data(parser, result, result_len, &err);
+ if (ret == FALSE) {
+ MOD_LOGW("Fail to parser data");
+ return -1;
+ }
+
+ node = json_parser_get_root(parser);
+ if (!node) {
+ MOD_LOGW("Fail to parser data");
+ return -1;
+ }
+
+ obj = json_node_get_object(node);
+ if (!obj) {
+ MOD_LOGW("Fail to parser data");
+ return -1;
+ }
+
+ positions = json_object_get_array_member(obj, "coordinates");
+ if (positions) {
+ json_array_foreach_element (positions, _get_position_from_coordinates, &pos_list);
+ MOD_LOGW("foreach");
+ }
+
+ properties = json_object_get_object_member(obj, "properties");
+ if (properties) {
+ str_distance = (gchar *)json_object_get_string_member(properties, "distance");
+ MOD_LOGW("distance [%s]", str_distance);
+ // instructions = json_object_get_string_member (properties, "description");
+ str_duration = (gchar *)json_object_get_string_member (properties, "traveltime");
+ MOD_LOGW("time [%s]", str_duration);
+
+ if (str_distance) {
+ distance = atof (str_distance);
+ MOD_LOGW("converted distance [%f]", distance);
+ g_free(str_distance);
+ }
+
+ if (str_duration) {
+ duration = atol (str_duration);
+ MOD_LOGW("converted duration [%ld]", duration);
+ g_free( str_duration);
+ }
+ }
+ else {
+ MOD_LOGW("property NULL");
+ }
+
+ LocationRouteStep *step = location_route_step_new ();
+
+ location_route_step_set_start_point (step, location_position_copy (origin));
+ location_route_step_set_end_point (step, location_position_copy (dest));
+
+
+ if (pos_list) {
+ location_route_step_set_geometry (step, pos_list);
+ }
+ GList *step_list = NULL;
+ step_list = g_list_append (step_list, step);
+
+
+ // Route == RouteSegment
+ LocationRouteSegment *segment = location_route_segment_new();
+ location_route_segment_set_start_point (segment, location_position_copy (origin));
+ location_route_segment_set_end_point (segment, location_position_copy (dest));
+ location_route_segment_set_distance (segment, distance);
+ location_route_segment_set_duration (segment, duration);
+ location_route_segment_set_route_step (segment, step_list);
+
+ GList *seg_list = NULL;
+ seg_list = g_list_append (seg_list, segment);
+
+
+ route = location_route_new ();
+ location_route_set_origin(route, origin);
+ location_route_set_destination(route, dest);
+ location_route_set_total_distance(route, distance);
+ location_route_set_distance_unit(route, "M");
+ location_route_set_total_duration(route, duration);
+ location_route_set_route_segment(route, seg_list);
+
+ *route_list = g_list_append(*route_list, route);
+
+ return 0;
+}
+
+int
+osm_request_route (const LocationPosition *origin,
+ const LocationPosition *destination,
+ GList *waypoint,
+ const LocationMapPref *svc_pref,
+ const LocationRoutePreference *pref,
+ LocationRouteCB cb,
+ const gpointer user_data,
+ guint *req_id)
+{
+ osm_data_t *ndata = g_new0(osm_data_t, 1);
+
+ ndata->route_cb = cb;
+ ndata->user_data = (gpointer)user_data;
+ ndata->origin = location_position_copy(origin);
+ ndata->dest = location_position_copy(destination);
+ if (waypoint) g_list_foreach(waypoint, _position_foreach_cb, ndata);
+
+ char *url = _create_route_url (origin, destination, waypoint, svc_pref, pref);
+ if (!url) {
+ g_free(ndata);
+ return LOCATION_ERROR_UNKNOWN;
+ }
+
+ int ret = curl_request_route_async(url, ndata, req_id);
+ if (ret != 0) {
+ g_free(ndata);
+ g_free(url);
+ return LOCATION_ERROR_UNKNOWN;
+ }
+
+ g_free(ndata);
+ g_free(url);
+ return LOCATION_ERROR_NONE;
+}
+
+int
+osm_cancel_route_request (guint req_id)
+{
+ return curl_cancel_route_request (req_id);
+}
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCATION_OSM_ROUTE_H__
+#define __LOCATION_OSM_ROUTE_H__
+
+#include <glib.h>
+#include <location-map-types.h>
+
+int osm_request_route (const LocationPosition *origin,
+ const LocationPosition *destination,
+ GList *waypoint,
+ const LocationMapPref *svc_pref,
+ const LocationRoutePreference *pref,
+ LocationRouteCB cb,
+ const gpointer user_data,
+ guint *req_id);
+
+int osm_cancel_route_request (guint req_id);
+
+int convert_data_to_location_service (const char *result, int result_len, LocationPosition *origin, LocationPosition *dest, GList **route);
+
+#endif /* __LOCATION_OSM_ROUTE_H__ */
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+
+#include <location.h>
+#include <location-map-service.h>
+#include "location-osm-geocode.h"
+#include "location-osm-route.h"
+#include "location-osm-poi.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "log.h"
+
+static void
+_unref_geoclue(OsmHandle* handle)
+{
+ if (handle->geocoder) {
+ g_object_unref (handle->geocoder);
+ handle->geocoder = NULL;
+ }
+ if (handle->rev_geocoder) {
+ g_object_unref (handle->rev_geocoder);
+ handle->rev_geocoder = NULL;
+ }
+ if (handle->poi) {
+ g_object_unref (handle->poi);
+ handle->poi = NULL;
+ }
+}
+
+static gboolean
+_ref_geoclue(OsmHandle* handle)
+{
+ gchar *service, *path;
+ service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.Nominatim");
+ path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/Nominatim");
+
+ if (!handle->geocoder) handle->geocoder = geoclue_geocode_new (service, path);
+ if (!handle->rev_geocoder) handle->rev_geocoder = geoclue_reverse_geocode_new (service, path);
+ if (!handle->poi) handle->poi = geoclue_poi_new (service, path);
+
+ if(!handle->geocoder || !handle->rev_geocoder || !handle->poi){
+ MOD_LOGW ("Error while creating Geoclue object.");
+ _unref_geoclue(handle);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int
+get_geocode (gpointer handle,
+ const LocationAddress *addr,
+ const LocationMapPref *svc_pref,
+ GList **pos_list,
+ GList **acc_list)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(pos_list, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(acc_list, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_geocode(osm, addr, pos_list, acc_list);
+}
+
+
+static int
+get_geocode_async (gpointer handle,
+ const LocationAddress *addr,
+ const LocationMapPref *svc_pref,
+ LocationPositionCB callback,
+ gpointer userdata)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_geocode_async(osm, addr, callback, userdata);
+}
+
+static int
+get_geocode_freetext(gpointer handle,
+ const gchar *addr,
+ const LocationMapPref *svc_pref,
+ GList **pos_list,
+ GList **acc_list)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(pos_list, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(acc_list, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_geocode_freetext(osm, addr, pos_list, acc_list);
+}
+
+
+static int
+get_geocode_freetext_async (gpointer handle,
+ const gchar* addr,
+ const LocationMapPref *svc_pref,
+ LocationPositionCB callback,
+ gpointer userdata)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_geocode_freetext_async(osm, addr, callback, userdata);
+}
+
+static int
+get_reverse_geocode(gpointer handle,
+ const LocationPosition *pos,
+ const LocationMapPref *svc_pref,
+ LocationAddress **addr,
+ LocationAccuracy **acc)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(acc, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_reverse_geocode(osm, pos, addr, acc);
+}
+
+static int
+get_reverse_geocode_async (gpointer handle,
+ const LocationPosition *pos,
+ const LocationMapPref *svc_pref,
+ LocationAddressCB callback,
+ gpointer userdata)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER);
+
+ return osm_get_reverse_geocode_async(osm, pos, callback, userdata);
+}
+
+static int
+search_poi (gpointer handle,
+ const LocationPOIFilter *filter,
+ const LocationPosition *position,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb, const gpointer user_data, guint * req_id)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(filter, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(pref, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(cb, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(req_id, LOCATION_ERROR_PARAMETER);
+
+
+ return osm_search_poi_by_position(osm, filter, position, svc_pref, pref, cb, user_data, req_id);
+}
+
+static int
+search_poi_by_area (gpointer handle,
+ const LocationPOIFilter *filter,
+ const LocationBoundary *boundary,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb, const gpointer user_data, guint * req_id)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(filter, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(boundary, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(pref, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(cb, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(req_id, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(boundary->type == LOCATION_BOUNDARY_RECT, LOCATION_ERROR_NOT_SUPPORTED);
+
+ return osm_search_poi_by_area(osm, filter, boundary, svc_pref, pref, cb, user_data, req_id);;
+}
+
+static int
+search_poi_by_address (gpointer handle,
+ const LocationPOIFilter *filter,
+ const LocationAddress *address,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb, const gpointer user_data, guint * req_id)
+{
+ return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int
+search_poi_by_freeform (gpointer handle,
+ const LocationPOIFilter * filter,
+ const gchar *freeform,
+ const LocationMapPref *svc_pref,
+ const LocationPOIPreference *pref,
+ LocationPOICB cb, const gpointer user_data, guint *req_id)
+{
+ return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int
+cancel_poi_request (gpointer handle, guint req_id)
+{
+ return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int
+request_route (gpointer handle,
+ const LocationPosition *origin,
+ const LocationPosition *destination,
+ GList *waypoint,
+ const LocationMapPref *svc_pref,
+ const LocationRoutePreference *pref,
+ LocationRouteCB cb, const gpointer user_data, guint * req_id)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+
+ return osm_request_route(origin, destination, waypoint, svc_pref, pref, cb, user_data, req_id);
+}
+
+static int
+cancel_route_request (gpointer handle, guint req_id)
+{
+ OsmHandle *osm = (OsmHandle *) handle;
+ g_return_val_if_fail (osm, LOCATION_ERROR_NOT_AVAILABLE);
+
+ return osm_cancel_route_request (req_id);
+}
+
+static gboolean
+is_supported_provider_capability (gpointer handle,
+ LocationMapServiceType type)
+{
+ return FALSE;
+}
+
+static int
+get_provider_capability_key (gpointer handle,
+ LocationMapServiceType type, GList **key)
+{
+ g_return_val_if_fail (key, LOCATION_ERROR_PARAMETER);
+ *key = NULL;
+ return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int
+get_service_name (gpointer handle,
+ gchar **service_name)
+{
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_return_val_if_fail(osm, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail (service_name, LOCATION_ERROR_PARAMETER);
+ *service_name = g_strdup (osm->service_name);
+ return LOCATION_ERROR_NONE;
+}
+
+LOCATION_MODULE_API gpointer
+init (LocModServiceOps* ops)
+{
+ MOD_LOGD("init");
+ g_return_val_if_fail(ops, NULL);
+ OsmHandle *handle = g_new0 (OsmHandle, 1);
+ if (!_ref_geoclue(handle)) {
+ g_free (handle);
+ return NULL;
+ }
+ handle->service_name = g_strdup ("osm");
+ ops->get_service_name = get_service_name;
+ ops->get_geocode = get_geocode;
+ ops->get_geocode_freetext = get_geocode_freetext;
+ ops->get_reverse_geocode = get_reverse_geocode;
+ ops->get_geocode_async = get_geocode_async;
+ ops->get_geocode_freetext_async = get_geocode_freetext_async;
+ ops->get_reverse_geocode_async = get_reverse_geocode_async;
+ ops->search_poi = search_poi;
+ ops->search_poi_by_area = search_poi_by_area;
+ ops->search_poi_by_address = search_poi_by_address;
+ ops->search_poi_by_freeform = search_poi_by_freeform;
+ ops->cancel_poi_request = cancel_poi_request;
+ ops->request_route = request_route;
+ ops->cancel_route_request = cancel_route_request;
+ ops->is_supported_provider_capability = is_supported_provider_capability;
+ ops->get_provider_capability_key = get_provider_capability_key;
+
+ return (gpointer)handle;
+}
+
+LOCATION_MODULE_API void
+shutdown (gpointer handle)
+{
+ MOD_LOGD("shutdown");
+ g_return_if_fail(handle);
+ OsmHandle *osm = (OsmHandle *)handle;
+ g_free (osm->service_name);
+ _unref_geoclue(osm);
+ g_free (osm);
+}
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCATION_OSM_H__
+#define __LOCATION_OSM_H__
+
+#include <geoclue/geoclue-geocode.h>
+#include <geoclue/geoclue-reverse-geocode.h>
+#include <geoclue/geoclue-provider.h>
+#include <geoclue/geoclue-poi.h>
+#include <location-module.h>
+
+typedef struct {
+ char* service_name;
+ GeoclueGeocode* geocoder;
+ GeoclueReverseGeocode* rev_geocoder;
+ GeocluePoi *poi;
+} OsmHandle;
+
+typedef struct {
+ int req_id;
+ LocationPositionCB pos_cb;
+ LocationAddressCB addr_cb;
+ LocationPOICB poi_cb;
+ gpointer userdata;
+} OsmHandleData;
+
+#endif /* __LOCATION_OSM_H__ */
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <curl/curl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include "log.h"
+#include "location-osm-route.h"
+#include "osm-http.h"
+
+//http://www.yournavigation.org/api/1.0/gosmore.php?format=geojson&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik
+
+
+#define YOUR_NAVIGATION_SERVER "http://www.yournavigation.org/api/1.0/gosmore.php?"
+#define YOUR_NAVIGATION_FORMAT "format="
+
+#define KML_FORMAT "kml"
+#define GEOJSON_FORMAT "geojson"
+
+static CURLM *g_multi_handle;
+static pthread_t g_http_thread;
+static GHashTable *g_req_table;
+
+pthread_mutex_t curl_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+typedef int (*curl_async_cb) (int req_id, int error, const char *result, int result_len, void *user_data);
+
+typedef struct {
+ guint req_id;
+ CURL *ctx;
+ curl_async_cb cb;
+ void *user_data;
+
+ int result_len;
+ char *result;
+} curl_item_t;
+
+CURL*
+curl_create_session (guint *req_id)
+{
+ static guint session_id = 0;
+
+ CURL_MUTEX_LOCK(&curl_mutex);
+ if (!g_multi_handle)
+ g_multi_handle = curl_multi_init();
+ CURL_MUTEX_UNLOCK(&curl_mutex);
+
+ CURL* ctx = curl_easy_init();
+ if (!ctx) {
+ MOD_LOGW("Unable to initialize cURL interface\n");
+ return NULL;
+ }
+
+ *req_id = ++session_id;
+
+ MOD_LOGW ("req_id [%d]", *req_id);
+
+ return ctx;
+}
+
+int
+curl_destroy_session (CURL* ctx)
+{
+ if (!ctx) return -1;
+
+ curl_easy_cleanup(ctx);
+
+ return 0;
+}
+
+static gboolean
+_compare_ctx (gpointer key, gpointer value, gpointer userdata)
+{
+ if (!key || !value || !userdata) return FALSE;
+
+ curl_item_t * item = (curl_item_t*) value;
+ CURL *ctx = (CURL*) userdata;
+
+ if (item->ctx == ctx) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int
+_send_resp (curl_item_t *item)
+{
+ MOD_LOGW ("Send response [%p]", item);
+ if (!item) return -1;
+ MOD_LOGW("Result [%s]", item->result);
+
+ if (item->cb)
+ item->cb (item->req_id, 0, item->result, item->result_len, item->user_data);
+
+ if (item->user_data) {
+ g_free(item->user_data);
+ item->user_data = NULL;
+ }
+
+ if (item->result) {
+ g_free(item->result);
+ item->result = NULL;
+ }
+
+ return 0;
+}
+
+static void *
+_create_http_thread(void *data)
+{
+ MOD_LOGW ("Create Thread");
+ CURLMsg *msg = NULL;
+ int msgs_left = 0;
+ int still_running = 1;
+ int rc = 0;
+ int ret = 0;
+ struct timeval timeout;
+
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ while(still_running) {
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexecp;
+ int maxfd = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexecp);
+
+ if (g_req_table)
+ curl_multi_fdset (g_multi_handle, &fdread, &fdwrite, &fdexecp, &maxfd);
+ else {
+ MOD_LOGW ("Hash table is NULL");
+ break;
+ }
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexecp, &timeout);
+ MOD_LOGW ("run loop [%d]", still_running);
+ switch (rc) {
+ case -1:
+ break;
+ case 0:
+ default:
+ /* Timeout or readable / writable sockets */
+ curl_multi_perform(g_multi_handle, &still_running);
+ if (ret != CURLM_OK) {
+ MOD_LOGW ("curl_multi_perform error [%d]", ret);
+ break;
+ }
+
+ msg = curl_multi_info_read(g_multi_handle, &msgs_left);
+ if (msg && msg->msg == CURLMSG_DONE) {
+ curl_item_t *item = g_hash_table_find (g_req_table, _compare_ctx, msg->easy_handle);
+ if (item) {
+ MOD_LOGW ("Found Item ID[%d]", item->req_id);
+ int ret = _send_resp(item);
+ if (ret) {
+ MOD_LOGW ("Fail to send response [%d]", ret);
+ g_http_thread = 0;
+ return NULL;
+ }
+
+ g_hash_table_remove (g_req_table, (gpointer) &item->req_id);
+
+ curl_destroy_session(item->ctx);
+ if (item) {
+ g_free(item);
+ item = NULL;
+ }
+
+ }
+ }
+ else {
+ sleep(1);
+ }
+ break;
+ }
+ }
+
+ CURL_MUTEX_LOCK (&curl_mutex);
+ if (g_multi_handle) {
+ curl_multi_cleanup(g_multi_handle);
+ g_multi_handle = NULL;
+ }
+ CURL_MUTEX_UNLOCK (&curl_mutex);
+
+ MOD_LOGW("End Thread");
+ g_http_thread = 0;
+
+ return NULL;
+}
+
+static size_t
+_osm_route_cb (char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ curl_item_t *item = (curl_item_t*)userdata;
+
+ MOD_LOGW("size[%d], nmemb [%d]", size, nmemb);
+ int reallo_len = size * nmemb;
+
+ item->result = realloc (item->result, item->result_len + reallo_len + 1);
+ if (item->result == NULL) {
+ /* out of memory! */
+ MOD_LOGW("not enough memory (realloc returned NULL)\n");
+ return 0;
+ }
+
+ memcpy(&(item->result[item->result_len]), ptr, reallo_len);
+ item->result_len += reallo_len;
+ item->result[item->result_len] = 0;
+
+ return reallo_len;
+}
+
+static int
+_route_cb (int req_id, int error, const char *result, int result_len, void *user_data)
+{
+ GList *route = NULL;
+ char *error_code = NULL;
+ char *error_msg = NULL;
+
+ osm_data_t *ndata = (osm_data_t *) user_data;
+ if (result && result_len > 0) {
+ // parsing
+ }
+
+ convert_data_to_location_service (result, result_len, ndata->origin, ndata->dest, &route);
+
+
+ ndata->route_cb(error, req_id, route, error_code, error_msg, ndata->user_data);
+
+ return 0;
+}
+
+int
+curl_request_route_async(const char *url, osm_data_t *data, guint *req_id)
+{
+ curl_item_t *item = g_new0(curl_item_t, 1);
+ if (!item) return -999;
+
+ int stillrunning = 0;
+
+
+ CURL *ctx = curl_create_session (req_id);
+ if (!ctx) {
+ *req_id = -1;
+ return -1;
+ }
+
+
+ CURLMcode err = 0;
+ int ret = 0;
+
+ item->req_id = *req_id;
+ item->user_data = data;
+ item->ctx = ctx;
+ item->cb = _route_cb;
+
+ curl_easy_setopt (ctx, CURLOPT_URL, url);
+// curl_easy_setopt (ctx, CURLOPT_NOPROGRESS , 0L);
+// curl_easy_setopt( ctx , CURLOPT_WRITEHEADER , stderr);
+ curl_easy_setopt( ctx, CURLOPT_WRITEFUNCTION, _osm_route_cb);
+ curl_easy_setopt( ctx , CURLOPT_WRITEDATA, item);
+
+ CURL_MUTEX_LOCK (&curl_mutex);
+ curl_multi_add_handle(g_multi_handle, ctx);
+
+ if (!g_req_table) {
+ g_req_table = g_hash_table_new (g_int_hash, g_int_equal);
+ }
+
+ g_hash_table_insert(g_req_table, req_id, item);
+
+ MOD_LOGW ("ReqID: %u", *req_id);
+
+ err = curl_multi_perform(g_multi_handle, &stillrunning);
+ CURL_MUTEX_UNLOCK (&curl_mutex);
+ if (CURLM_OK != err) {
+ MOD_LOGW ("curl_multi_perform error[%d]", err);
+ if (item) {
+ g_free(item);
+ item = NULL;
+ }
+
+ curl_destroy_session(ctx);
+ return -1;
+ }
+
+ if (!g_http_thread) { //TODO
+ ret = pthread_create(&g_http_thread, NULL, _create_http_thread, NULL);
+
+ if (ret) {
+ // return error
+ MOD_LOGW ("Fail to create thread [%d", ret);
+ if (item) {
+ g_free(item);
+ item = NULL;
+ }
+
+ curl_destroy_session(ctx);
+ return -1;
+ }
+ MOD_LOGW ("End loop");
+ pthread_detach(g_http_thread);
+ }
+ else {
+ MOD_LOGW ("Thread is alive");
+ }
+
+ return 0;
+}
+
+int
+curl_cancel_route_request (guint req_id)
+{
+ curl_item_t* item = NULL;
+
+ if (!g_req_table) {
+ return LOCATION_ERROR_NOT_FOUND;
+ }
+
+ item = (curl_item_t *)g_hash_table_lookup (g_req_table, (void* )&req_id);
+ if (!item) {
+ return LOCATION_ERROR_NOT_FOUND;
+ }
+
+
+ if (g_multi_handle) {
+ curl_multi_remove_handle (g_multi_handle, item->ctx);
+ }
+
+ if( item->user_data) {
+ g_free (item->user_data);
+ item->user_data = NULL;
+ }
+
+ if (item->result) {
+ g_free (item->result);
+ item->result = NULL;
+ }
+ if (item) {
+ g_free (item);
+ item = NULL;
+ }
+
+ gboolean ret = g_hash_table_remove(g_req_table, (void *)&req_id);
+ if (!ret) {
+ return LOCATION_ERROR_NOT_FOUND;
+ }
+ if (g_hash_table_size(g_req_table) == 0) {
+ MOD_LOGW ("Hash table is NULL");
+ g_hash_table_destroy(g_req_table);
+ g_req_table = NULL;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __OSM_HTTP_H__
+#define __OSM_HTTP_H__
+
+#include <location-map-types.h>
+
+typedef struct {
+ gpointer handle;
+ LocationPosition *origin;
+ LocationPosition *dest;
+ GList *waypoint;
+ LocationRouteCB route_cb;
+ gpointer user_data;
+} osm_data_t;
+
+#define CURL_MUTEX_LOCK(x) MOD_LOGW ("Try to lock mutex[%p]", x); \
+ pthread_mutex_lock (x);
+
+#define CURL_MUTEX_UNLOCK(x) MOD_LOGW ("Try to unlock mutex[%p]", x); \
+ pthread_mutex_unlock (x);
+
+int curl_request_route_async(const char *url, osm_data_t *data, guint *req_id);
+
+int curl_cancel_route_request (guint req_id);
+
+#endif /* __OSM_HTTP_H__ */
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//http://www.yournavigation.org/api/1.0/gosmore.php?format=geojson&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik
+//http://www.yournavigation.org/api/1.0/gosmore.php?formats=geojson/&flat=52.215676&flot=5.963946&tlat=52.257300&tlon=6.179900&v=carmotor&fast=1&instructions=1&layer=mapnik
+//http://www.yournavigation.org/api/1.0/gosmore.php?format=geojson&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.179900&v=motorcar&fast=1&instructions=1&layer=mapnik
+
+#include <location.h>
+#include <string.h>
+#include <stdio.h>
+#include "log.h"
+
+const char *YOURS_SERVER = "http://www.yournavigation.org/api/1.0/gosmore.php?";
+const char *YOURS_FORMAT = "format=";
+const char *YOURS_INSTRUCTIONS = "instructions=";
+const char *YOURS_TYPE = "v=";
+const char *YOURS_FAST = "fast=";
+const char *YOURS_END = "layer=mapnik";
+
+const char *YOURS_FORMAT_KML = "kml";
+const char *YOURS_FORMAT_GEOJSON = "geojson";
+
+const char *YOURS_SET_ON = "1";
+const char *YOURS_SET_OFF = "0";
+
+const char delimeter = '&';
+
+static int _add_option (char *buf, const char *key, const char *option)
+{
+ if (!buf || !option) return -1;
+
+ if (strlen(buf) == 0) { //create
+ strncpy(buf, YOURS_SERVER, strlen (YOURS_SERVER));
+
+ if (key) strncat(buf, key, strlen (key));
+ strncat(buf, option, strlen (option));
+
+ } else {
+ strncat(buf, &delimeter, 1);
+ if (key) strncat(buf, key, strlen (key));
+ strncat(buf, option, strlen (option));
+ }
+
+ return 0;
+}
+
+char* yournavi_create_url (gdouble flat, gdouble flon, gdouble tlat, gdouble tlon, GList *way, int type, char *mode ,int instruction)
+{
+ char url[1024] = {0, };
+ char pos_str[64] = {0, };
+
+ //TODO WAYPOINT : Not supported
+
+
+#if 0 // kml
+ _add_option(url, YOURS_FORMAT, YOURS_FORMAT_KML);
+#else
+ _add_option(url, YOURS_FORMAT, YOURS_FORMAT_GEOJSON);
+#endif
+
+ snprintf(pos_str, 64, "flat=%f&flot=%f&tlat=%f&tlon=%f", flat, flon, tlat, tlon);
+ _add_option (url, NULL, pos_str);
+
+ _add_option (url, YOURS_TYPE, mode);
+
+ if (type)
+ _add_option (url, YOURS_FAST, YOURS_SET_ON);
+ else
+ _add_option (url, YOURS_FAST, YOURS_SET_OFF);
+
+ if (instruction)
+ _add_option (url, YOURS_INSTRUCTIONS, YOURS_SET_ON);
+
+ _add_option (url, NULL, YOURS_END);
+
+ MOD_LOGW ("URL[%s]", url);
+
+ return g_strdup(url);
+}
+
--- /dev/null
+/*
+ * location-module
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __OSM_ROUTE_YOURS_H__
+#define __OSM_ROUTE_YOURS_H__
+
+char* yournavi_create_url (gdouble flat, gdouble flon, gdouble tlat, gdouble tlon, GList *way, int type, char *mode ,int instruction);
+
+#endif /* __OSM_ROUTE_YOURS_H__ */
Name: location-module
Summary: Location module
-Version: 0.1.12
-Release: 5
-Group: TO_BE/FILLED_IN
-License: TO_BE/FILLED_IN
+Version: 0.1.21
+Release: 1
+Group: System/Libraries
+License: Apache Licensc, Version 2.0
Source0: %{name}-%{version}.tar.gz
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gmodule-2.0)
BuildRequires: pkgconfig(location)
BuildRequires: pkgconfig(geoclue)
BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libcurl)
+BuildRequires: pkgconfig(json-glib-1.0)
+
%description
%package -n location-geoclue-nominatim
-Summary: geoclue-nominatim geocode module for location
+Summary: geoclue-nominatim map-service module for location
Group: TO_BE/FILLED_IN
%description -n location-geoclue-nominatim
-geoclue-nominatim geocode module for location
+geoclue-nominatim map-service module for location
%prep
%setup -q
%build
./autogen.sh
-%configure --prefix=$(PREFIX) --enable-dlog --enable-debug
+%configure --prefix=%{_prefix} --enable-dlog --enable-debug
make %{?jobs:-j%jobs}
%make_install
%files -n location-geoclue-nominatim
+%manifest location-geoclue-nominatim.manifest
%defattr(-,root,root,-)
-%{_libdir}/location/module/libgeocode0.so
-%{_libdir}/location/module/libgeocode0.so.*
+%{_libdir}/location/module/libmap-service-osm*