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 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 ret = GEOCODER_ERROR_NETWORK_FAILED;
54 msg = "GEOCODER_ERROR_NETWORK_FAILED";
56 case LOCATION_ERROR_PARAMETER:
57 ret = GEOCODER_ERROR_INVALID_PARAMETER;
58 msg = "GEOCODER_ERROR_INVALID_PARAMETER";
60 case LOCATION_ERROR_NOT_ALLOWED:
61 case LOCATION_ERROR_NOT_AVAILABLE:
62 case LOCATION_ERROR_CONFIGURATION:
63 case LOCATION_ERROR_UNKNOWN:
65 msg = "GEOCODER_ERROR_SERVICE_NOT_AVAILABLE";
66 ret = GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
68 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
72 static void cb_address_from_position (LocationError error, LocationAddress *addr, LocationAccuracy *acc, gpointer userdata)
74 geocoder_s * handle = (geocoder_s*)userdata;
75 if(handle->user_cb[_GEOCODER_CB_ADDRESS_FROM_POSITION])
77 if(error != LOCATION_ERROR_NONE || addr == NULL)
79 _convert_error_code(error,(char*)__FUNCTION__);
80 ((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]);
84 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);
85 ((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]);
90 LOGI("[%s] callback is NULL )",__FUNCTION__);
94 static void cb_position_from_address (LocationError error, LocationPosition *pos, LocationAccuracy *acc, gpointer userdata)
96 geocoder_s * handle = (geocoder_s*)userdata;
97 if(handle->user_cb[_GEOCODER_CB_POSITION_FROM_ADDRESS])
99 if(error != LOCATION_ERROR_NONE || pos == NULL)
101 _convert_error_code(error,(char*)__FUNCTION__);
107 for( i=0 ; i < temp_max ; i++)
109 LOGI("[%s] Position[%d] - time: %d, lat: %f, long: %f, alt: %f, status: %d", __FUNCTION__, (i+1), pos->timestamp, pos->latitude, pos->longitude, pos->altitude, pos->status);
110 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 )
112 LOGI("[%s] User quit the loop [count : %d]", __FUNCTION__, (i+1));
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 LocationPosition *pos = NULL;
301 LocationAccuracy *acc = NULL;
302 char* addr_str = g_strdup(address);
304 ret = location_get_position_from_freeformed_address(handle->object, addr_str, &pos, &acc);
305 if( ret != LOCATION_ERROR_NONE)
308 return _convert_error_code(ret,(char*)__FUNCTION__);
313 for( i=0 ; i < temp_max ; i++)
315 if ( callback(pos->latitude, pos->longitude, user_data) != TRUE )
317 LOGI("[%s] User quit the loop [count : %d]", __FUNCTION__, (i+1));
322 location_position_free(pos);
323 location_accuracy_free(acc);
324 return GEOCODER_ERROR_NONE;