4 * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7 * Genie Kim <daejins.kim@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 #include "location-osm.h"
26 _get_geoclue_addr_from_location_addr (const LocationAddress *address)
28 if (!address) return NULL;
30 GHashTable *geoclue_addr = geoclue_address_details_new();
31 if (address->street) {
32 if (address->building_number) {
33 char *street_addr = g_strdup_printf ("%s %s", address->building_number, address->street);
34 geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET, street_addr);
36 } else geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET, address->street);
38 if (address->district) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_AREA, address->district);
39 if (address->city) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_LOCALITY, address->city);
40 if (address->state) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_REGION, address->state);
41 if (address->country_code) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_COUNTRY, address->country_code);
42 if (address->postal_code) geoclue_address_details_insert (geoclue_addr, GEOCLUE_ADDRESS_KEY_POSTALCODE, address->postal_code);
47 static LocationAddress*
48 _get_location_addr_from_geoclue_addr (GHashTable *geoclue_addr)
50 if (!geoclue_addr) return NULL;
52 LocationAddress *addr = NULL;
54 gchar *country, *region, *locality, *postalcode, *area, *street;
56 country = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_COUNTRY);
57 region = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_REGION);
58 locality = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_LOCALITY);
59 area = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_AREA);
60 postalcode = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_POSTALCODE);
61 street = g_hash_table_lookup (geoclue_addr, GEOCLUE_ADDRESS_KEY_STREET);
63 addr = location_address_new (NULL, street, area, locality, region, NULL, postalcode, NULL, country, NULL);
68 static LocationAccuracy *
69 _get_location_acc_from_geoclue_acc (GeoclueAccuracy *acc)
71 if (!acc) return NULL;
73 LocationAccuracy *accuracy = NULL;
74 GeoclueAccuracyLevel level;
77 geoclue_accuracy_get_details (acc, &level, &horiz_acc, &vert_acc);
79 if (level == GEOCLUE_ACCURACY_LEVEL_DETAILED) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
80 else if (level == GEOCLUE_ACCURACY_LEVEL_STREET) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, horiz_acc, vert_acc);
81 else if (level == GEOCLUE_ACCURACY_LEVEL_POSTALCODE) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, horiz_acc, vert_acc);
82 else if (level == GEOCLUE_ACCURACY_LEVEL_LOCALITY) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, horiz_acc, vert_acc);
83 else if (level == GEOCLUE_ACCURACY_LEVEL_REGION) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, horiz_acc, vert_acc);
84 else if (level == GEOCLUE_ACCURACY_LEVEL_COUNTRY) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, horiz_acc, vert_acc);
85 else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
91 address_cb (GeoclueReverseGeocode *revgeocode,
93 GeoclueAccuracy *accuracy,
97 OsmHandleData* data = (OsmHandleData*)userdata;
98 g_return_if_fail(data->addr_cb);
100 LocationAddress *addr = NULL;
101 LocationAccuracy *acc = NULL;
102 LocationError err = LOCATION_ERROR_NONE;
105 MOD_LOGW ("Error getting reverse geocode: %s", error->message);
106 err = LOCATION_ERROR_NOT_AVAILABLE;
108 if (accuracy) acc = _get_location_acc_from_geoclue_acc (accuracy);
109 else acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
111 if (details) addr = _get_location_addr_from_geoclue_addr (details);
114 data->addr_cb (err, addr, acc, data->userdata);
115 if (addr) location_address_free (addr);
116 if (acc) location_accuracy_free (acc);
121 _free_pos_list_item(gpointer data)
123 g_return_if_fail(data);
125 LocationPosition *position = (LocationPosition *)data;
126 location_position_free(position);
130 _free_acc_list_item(gpointer data)
132 g_return_if_fail(data);
134 LocationAccuracy *accuracy = (LocationAccuracy *)data;
135 location_accuracy_free(accuracy);
139 position_cb (GeoclueGeocode *geocode,
140 GeocluePositionFields fields,
144 GeoclueAccuracy *accuracy,
148 OsmHandleData* data = (OsmHandleData*)userdata;
149 GList *pos_list = NULL;
150 GList *acc_list = NULL;
152 g_return_if_fail(data->pos_cb);
154 LocationPosition *pos = NULL;
155 LocationAccuracy *acc = NULL;
156 LocationError err = LOCATION_ERROR_NONE;
159 MOD_LOGW ("Error getting geocode: %s", error->message);
160 err = LOCATION_ERROR_NOT_AVAILABLE;
162 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
163 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
164 if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
165 else pos = location_position_new (0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
167 pos_list = g_list_append(pos_list, pos);
169 err = LOCATION_ERROR_NOT_FOUND;
173 acc = _get_location_acc_from_geoclue_acc (accuracy);
174 acc_list = g_list_append(acc_list, acc);
177 data->pos_cb (err, pos_list, acc_list, data->userdata);
179 if (pos_list) g_list_free_full(pos_list, _free_pos_list_item);
180 if (acc_list) g_list_free_full(acc_list, _free_acc_list_item);
187 osm_get_geocode (OsmHandle *osm,
188 const LocationAddress *addr,
192 double lat, lon, alt;
193 GeoclueAccuracy *geoclue_acc = NULL;
194 GError *error = NULL;
195 LocationPosition *pos = NULL;
196 LocationAccuracy *acc = NULL;
197 LocationError err = LOCATION_ERROR_NONE;
199 GHashTable* geoclue_addr = _get_geoclue_addr_from_location_addr (addr);
200 GeocluePositionFields fields = geoclue_geocode_address_to_position (osm->geocoder, geoclue_addr,
202 &geoclue_acc, &error);
203 g_hash_table_destroy (geoclue_addr);
206 MOD_LOGW ("Error getting geocode: %s", error->message);
207 g_error_free (error);
208 return LOCATION_ERROR_NOT_AVAILABLE;
211 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
212 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
213 if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, lat, lon, alt, LOCATION_STATUS_3D_FIX);
214 else pos = location_position_new (0, lat, lon, 0, LOCATION_STATUS_2D_FIX);
216 *pos_list = g_list_append(*pos_list, pos);
219 err = LOCATION_ERROR_NOT_FOUND;
223 acc = _get_location_acc_from_geoclue_acc (geoclue_acc);
224 geoclue_accuracy_free (geoclue_acc);
226 *acc_list = g_list_append(*acc_list, acc);
229 if (pos) location_position_free (pos);
230 if (acc) location_accuracy_free (acc);
236 osm_get_geocode_async (OsmHandle *osm,
237 const LocationAddress * addr,
238 LocationPositionCB callback,
241 GHashTable* geoclue_addr = _get_geoclue_addr_from_location_addr (addr);
242 OsmHandleData *data = g_new0 (OsmHandleData, 1);
243 data->pos_cb = callback;
244 data->userdata = userdata;
245 geoclue_geocode_address_to_position_async (osm->geocoder, geoclue_addr, position_cb, data);
246 g_hash_table_destroy (geoclue_addr);
248 return LOCATION_ERROR_NONE;
252 osm_get_geocode_freetext(OsmHandle *osm,
253 const const gchar* addr,
257 double lat, lon, alt;
258 GeoclueAccuracy *geoclue_acc = NULL;
259 GError *error = NULL;
260 LocationPosition *pos = NULL;
261 LocationAccuracy *acc = NULL;
262 LocationError err = LOCATION_ERROR_NONE;
264 GeocluePositionFields fields = geoclue_geocode_freeform_address_to_position (osm->geocoder, addr,
266 &geoclue_acc, &error);
268 MOD_LOGW ("Error getting geocode: %s", error->message);
269 g_error_free (error);
270 return LOCATION_ERROR_NOT_AVAILABLE;
273 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
274 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
275 if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) pos = location_position_new (0, lat, lon, alt, LOCATION_STATUS_3D_FIX);
276 else pos = location_position_new (0, lat, lon, 0, LOCATION_STATUS_2D_FIX);
277 *pos_list = g_list_append(*pos_list, pos);
280 err = LOCATION_ERROR_NOT_FOUND;
284 acc = _get_location_acc_from_geoclue_acc (geoclue_acc);
285 geoclue_accuracy_free (geoclue_acc);
286 *acc_list = g_list_append(*acc_list, acc);
289 if (pos) location_position_free (pos);
290 if (acc) location_accuracy_free (acc);
295 osm_get_geocode_freetext_async (OsmHandle *osm,
297 LocationPositionCB callback,
300 OsmHandleData *data = g_new0 (OsmHandleData, 1);
301 data->pos_cb = callback;
302 data->userdata = userdata;
303 geoclue_geocode_freeform_address_to_position_async (osm->geocoder, addr, position_cb, data);
305 return LOCATION_ERROR_NONE;
309 osm_get_reverse_geocode(OsmHandle *osm,
310 const LocationPosition *pos,
311 LocationAddress **addr,
312 LocationAccuracy **acc)
314 GeoclueAccuracy *addr_acc = NULL;
315 GError *error = NULL;
316 GHashTable* geoclue_addr = NULL;
318 double lat = pos->latitude;
319 double lon = pos->longitude;
320 GeoclueAccuracy *pos_acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_DETAILED, 0.0, 0.0);
322 gboolean success = geoclue_reverse_geocode_position_to_address (osm->rev_geocoder, lat, lon,
323 pos_acc, &geoclue_addr,
325 geoclue_accuracy_free (pos_acc);
327 if (!success || error) {
328 MOD_LOGW ("Error getting reverse geocode: %s", error->message);
329 g_error_free (error);
330 return LOCATION_ERROR_NOT_AVAILABLE;
334 *acc = _get_location_acc_from_geoclue_acc (addr_acc);
335 geoclue_accuracy_free (addr_acc);
336 } else *acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
338 *addr = _get_location_addr_from_geoclue_addr (geoclue_addr);
339 g_hash_table_destroy (geoclue_addr);
342 return LOCATION_ERROR_NONE;
346 osm_get_reverse_geocode_async (OsmHandle *osm,
347 const LocationPosition *pos,
348 LocationAddressCB callback,
351 double lat = pos->latitude;
352 double lon = pos->longitude;
353 GeoclueAccuracy *pos_acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_DETAILED, 0.0, 0.0);;
354 OsmHandleData *data = g_new0 (OsmHandleData, 1);
355 data->addr_cb = callback;
356 data->userdata = userdata;
357 geoclue_reverse_geocode_position_to_address_async (osm->rev_geocoder,
360 geoclue_accuracy_free (pos_acc);
362 return LOCATION_ERROR_NONE;