2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <geocoder_private.h>
26 #define LOG_TAG "TIZEN_N_GEOCODER"
31 #define GEOCODER_CHECK_CONDITION(condition,error,msg) \
32 if(condition) {} else \
33 { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \
35 #define GEOCODER_NULL_ARG_CHECK(arg) \
36 GEOCODER_CHECK_CONDITION(arg != NULL,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER")
39 * Internal Implementation
42 static int __convert_error_code(int code, char* func_name)
45 char* msg = "GEOCODER_ERROR_NONE";
48 case LOCATION_ERROR_NONE:
49 ret = GEOCODER_ERROR_NONE;
50 msg = "GEOCODER_ERROR_NONE";
52 case LOCATION_ERROR_NETWORK_FAILED:
53 case LOCATION_ERROR_NETWORK_NOT_CONNECTED:
54 ret = GEOCODER_ERROR_NETWORK_FAILED;
55 msg = "GEOCODER_ERROR_NETWORK_FAILED";
57 case LOCATION_ERROR_PARAMETER:
58 ret = GEOCODER_ERROR_INVALID_PARAMETER;
59 msg = "GEOCODER_ERROR_INVALID_PARAMETER";
61 case LOCATION_ERROR_NOT_ALLOWED:
62 case LOCATION_ERROR_NOT_AVAILABLE:
63 case LOCATION_ERROR_CONFIGURATION:
64 case LOCATION_ERROR_UNKNOWN:
66 msg = "GEOCODER_ERROR_SERVICE_NOT_AVAILABLE";
67 ret = GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
69 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
73 static void __cb_address_from_position (LocationError error, LocationAddress *addr, LocationAccuracy *acc, gpointer userdata)
75 geocoder_s * handle = (geocoder_s*)userdata;
76 if(handle->user_cb[_GEOCODER_CB_ADDRESS_FROM_POSITION])
78 if(error != LOCATION_ERROR_NONE || addr == NULL)
80 __convert_error_code(error,(char*)__FUNCTION__);
81 ((geocoder_get_address_cb)handle->user_cb[_GEOCODER_CB_ADDRESS_FROM_POSITION])(NULL, NULL, NULL, NULL, NULL, NULL, NULL, handle->user_data[_GEOCODER_CB_ADDRESS_FROM_POSITION]);
85 LOGI("[%s] Address - building number: %s, postal code: %s, street: %s, city: %s, district: %s, state: %s, country code: %s", __FUNCTION__ , addr->building_number, addr->postal_code, addr->street, addr->city, addr->district, addr->state, addr->country_code);
86 ((geocoder_get_address_cb)handle->user_cb[_GEOCODER_CB_ADDRESS_FROM_POSITION])(addr->building_number, addr->postal_code, addr->street, addr->city, addr->district, addr->state, addr->country_code, handle->user_data[_GEOCODER_CB_ADDRESS_FROM_POSITION]);
91 LOGI("[%s] callback is NULL )",__FUNCTION__);
95 static void __cb_position_from_address (LocationError error, GList *position_list, GList *accuracy_list, gpointer userdata)
97 geocoder_s * handle = (geocoder_s*)userdata;
98 if(handle->user_cb[_GEOCODER_CB_POSITION_FROM_ADDRESS])
100 if(error != LOCATION_ERROR_NONE || position_list == NULL || position_list->data ==NULL || accuracy_list==NULL )
102 __convert_error_code(error,(char*)__FUNCTION__);
108 LocationPosition *pos = position_list->data;
109 if ( ((geocoder_get_position_cb)handle->user_cb[_GEOCODER_CB_POSITION_FROM_ADDRESS])(pos->latitude, pos->longitude, handle->user_data[_GEOCODER_CB_POSITION_FROM_ADDRESS]) != TRUE )
111 LOGI("[%s] User quit the loop ", __FUNCTION__);
114 position_list = g_list_next(position_list);
120 LOGI("[%s] callback is NULL )",__FUNCTION__);
125 * Public Implementation
127 int geocoder_create(geocoder_h* geocoder)
129 GEOCODER_NULL_ARG_CHECK(geocoder);
130 if(location_init()!=LOCATION_ERROR_NONE)
132 LOGE("[%s] GEOCODER_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_init", __FUNCTION__, GEOCODER_ERROR_SERVICE_NOT_AVAILABLE);
133 return GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
136 geocoder_s *handle = (geocoder_s*)malloc(sizeof(geocoder_s));
139 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, GEOCODER_ERROR_OUT_OF_MEMORY);
140 return GEOCODER_ERROR_OUT_OF_MEMORY;
143 memset(handle, 0 , sizeof(geocoder_s));
145 handle->object = location_new(LOCATION_METHOD_HYBRID);
146 if(handle->object == NULL)
149 LOGE("[%s] GEOCODER_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_new", __FUNCTION__, GEOCODER_ERROR_SERVICE_NOT_AVAILABLE);
150 return GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
153 *geocoder = (geocoder_h)handle;
154 return GEOCODER_ERROR_NONE;
157 int geocoder_destroy(geocoder_h geocoder)
159 GEOCODER_NULL_ARG_CHECK(geocoder);
160 geocoder_s *handle = (geocoder_s*)geocoder;
162 int ret = location_free(handle->object);
163 if(ret!=GEOCODER_ERROR_NONE)
165 return __convert_error_code(ret,(char*)__FUNCTION__);
168 return GEOCODER_ERROR_NONE;
171 int geocoder_get_address_from_position(geocoder_h geocoder, double latitude, double longitude, geocoder_get_address_cb callback, void *user_data)
173 GEOCODER_NULL_ARG_CHECK(geocoder);
174 GEOCODER_NULL_ARG_CHECK(callback);
175 GEOCODER_CHECK_CONDITION(latitude>=-90 && latitude<=90 ,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
176 GEOCODER_CHECK_CONDITION(longitude>=-180 && longitude<=180,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
178 geocoder_s *handle = (geocoder_s*)geocoder;
180 LocationPosition *pos = NULL;
181 pos = location_position_new (0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
183 handle->user_cb[_GEOCODER_CB_ADDRESS_FROM_POSITION] = callback;
184 handle->user_data[_GEOCODER_CB_ADDRESS_FROM_POSITION] = user_data;
186 ret = location_get_address_from_position_async(handle->object, pos, __cb_address_from_position, handle);
187 if( ret != LOCATION_ERROR_NONE)
189 return __convert_error_code(ret,(char*)__FUNCTION__);
191 location_position_free(pos);
192 return GEOCODER_ERROR_NONE;
195 int geocoder_get_address_from_position_sync(geocoder_h geocoder, double latitude, double longitude, char **building_number, char **postal_code, char **street, char **city, char **district, char **state, char **country_code)
197 GEOCODER_NULL_ARG_CHECK(geocoder);
198 GEOCODER_CHECK_CONDITION(latitude>=-90 && latitude<=90 ,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
199 GEOCODER_CHECK_CONDITION(longitude>=-180 && longitude<=180,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
201 geocoder_s *handle = (geocoder_s*)geocoder;
203 LocationAddress *addr = NULL;
204 LocationPosition *pos = NULL;
205 LocationAccuracy *acc = NULL;
207 pos = location_position_new (0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
208 ret = location_get_address_from_position(handle->object, pos, &addr, &acc);
209 if( ret != LOCATION_ERROR_NONE)
211 return __convert_error_code(ret,(char*)__FUNCTION__);
216 *building_number = NULL;
217 if(addr->building_number)
218 *building_number = strdup(addr->building_number);
224 if(addr->postal_code)
225 *postal_code = strdup(addr->postal_code);
232 *street = strdup(addr->street);
239 *city = strdup(addr->city);
246 *state = strdup(addr->state);
253 *district = strdup(addr->district);
258 *country_code = NULL;
259 if(addr->country_code)
260 *country_code = strdup(addr->country_code);
263 location_address_free(addr);
264 location_position_free(pos);
265 location_accuracy_free(acc);
266 return GEOCODER_ERROR_NONE;
271 int geocoder_foreach_positions_from_address(geocoder_h geocoder,const char* address, geocoder_get_position_cb callback, void *user_data)
273 GEOCODER_NULL_ARG_CHECK(geocoder);
274 GEOCODER_NULL_ARG_CHECK(address);
275 GEOCODER_NULL_ARG_CHECK(callback);
276 geocoder_s *handle = (geocoder_s*)geocoder;
278 char* addr_str = g_strdup(address);
279 handle->user_cb[_GEOCODER_CB_POSITION_FROM_ADDRESS] = callback;
280 handle->user_data[_GEOCODER_CB_POSITION_FROM_ADDRESS] = user_data;
283 ret = location_get_position_from_freeformed_address_async(handle->object, addr_str,__cb_position_from_address, handle);
284 if( ret != LOCATION_ERROR_NONE)
287 return __convert_error_code(ret,(char*)__FUNCTION__);
289 return GEOCODER_ERROR_NONE;
292 int geocoder_foreach_positions_from_address_sync(geocoder_h geocoder,const char* address, geocoder_get_position_cb callback, void *user_data)
294 GEOCODER_NULL_ARG_CHECK(geocoder);
295 GEOCODER_NULL_ARG_CHECK(address);
296 GEOCODER_NULL_ARG_CHECK(callback);
297 geocoder_s *handle = (geocoder_s*)geocoder;
300 GList *pos_list = NULL;
301 GList *acc_list = NULL;
302 char* addr_str = g_strdup(address);
305 ret = location_get_position_from_freeformed_address(handle->object, addr_str, &pos_list, &acc_list);
307 if( ret != LOCATION_ERROR_NONE)
310 return __convert_error_code(ret,(char*)__FUNCTION__);
315 LocationPosition *pos = pos_list->data;
316 if ( callback(pos->latitude, pos->longitude, user_data) != TRUE )
318 LOGI("[%s] User quit the loop ", __FUNCTION__);
321 pos_list = g_list_next(pos_list);
325 g_list_free (pos_list);
326 g_list_free (acc_list);
327 return GEOCODER_ERROR_NONE;