Tizen 2.0 Release
[framework/api/geocoder.git] / src / geocoder.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <geocoder_private.h>
21
22 /*
23 * Internal Implementation
24 */
25
26 typedef struct {
27         void *data;
28         geocoder_get_address_cb callback;
29 }__addr_callback_data;
30
31 typedef struct {
32         void *data;
33         geocoder_get_position_cb callback;
34 }__pos_callback_data;
35
36 static int __convert_error_code(int code)
37 {
38         int ret;
39         char* msg = "GEOCODER_ERROR_NONE";
40         switch(code)
41         {
42                 case LOCATION_ERROR_NONE:
43                         ret = GEOCODER_ERROR_NONE;
44                         msg = "GEOCODER_ERROR_NONE";
45                         break;
46                 case LOCATION_ERROR_NETWORK_FAILED:
47                 case LOCATION_ERROR_NETWORK_NOT_CONNECTED:
48                         ret = GEOCODER_ERROR_NETWORK_FAILED;
49                         msg = "GEOCODER_ERROR_NETWORK_FAILED";
50                         break;
51                 case LOCATION_ERROR_PARAMETER:
52                         ret = GEOCODER_ERROR_INVALID_PARAMETER;
53                         msg = "GEOCODER_ERROR_INVALID_PARAMETER";
54                         break;
55                 case LOCATION_ERROR_NOT_FOUND:
56                         ret = GEOCODER_ERROR_NOT_FOUND;
57                         msg = "GEOCODER_ERROR_NOT_FOUND";
58                         break;
59                 case LOCATION_ERROR_NOT_ALLOWED:
60                 case LOCATION_ERROR_NOT_AVAILABLE:
61                 case LOCATION_ERROR_CONFIGURATION:
62                 case LOCATION_ERROR_UNKNOWN:
63                 default:
64                         msg = "GEOCODER_ERROR_SERVICE_NOT_AVAILABLE";
65                         ret = GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
66         }
67         GEOCODER_LOGE("%s(0x%08x) : core fw error(0x%x)", msg, ret, code);
68         return ret;
69 }
70
71 static void __cb_address_from_position (LocationError error, LocationAddress *addr, LocationAccuracy *acc, gpointer userdata)
72 {
73         __addr_callback_data * callback = (__addr_callback_data*)userdata;
74         if( callback == NULL || callback->callback == NULL)
75         {
76                 GEOCODER_LOGI("callback is NULL )");
77                 return ;
78         }
79
80         if(error != LOCATION_ERROR_NONE || addr == NULL)
81         {
82                 callback->callback(__convert_error_code(error), NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, callback->data);
83         }
84         else
85         {
86                 GEOCODER_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);
87                 callback->callback(GEOCODER_ERROR_NONE, addr->building_number, addr->postal_code, addr->street, addr->city, addr->district, addr->state, addr->country_code, callback->data);
88         }
89         free(callback);
90 }
91
92 static void __cb_position_from_address (LocationError error, GList *position_list, GList *accuracy_list, gpointer userdata)
93 {
94         __pos_callback_data * callback = (__pos_callback_data*)userdata;
95         if( callback == NULL || callback->callback == NULL)
96         {
97                 GEOCODER_LOGI("callback is NULL )");
98                 return ;
99         }
100
101         if(error != LOCATION_ERROR_NONE || position_list == NULL || position_list->data ==NULL || accuracy_list==NULL )
102         {
103                 callback->callback(__convert_error_code(error), 0, 0, callback->data);
104         }
105         else
106         {
107                 while(position_list)
108                 {
109                         LocationPosition *pos = position_list->data;
110                         if ( callback->callback(GEOCODER_ERROR_NONE, pos->latitude, pos->longitude, callback->data) != TRUE )
111                         {
112                                 GEOCODER_LOGI("[%s] User quit the loop ");
113                                 break;
114                         }
115                         position_list = g_list_next(position_list);
116                 }
117         }
118         free(callback);
119 }
120
121 /*
122 * Public Implementation
123 */
124 int     geocoder_create(geocoder_h* geocoder)
125 {
126         GEOCODER_NULL_ARG_CHECK(geocoder);
127         if(location_init()!=LOCATION_ERROR_NONE)
128         {
129                 GEOCODER_LOGE("GEOCODER_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_init", GEOCODER_ERROR_SERVICE_NOT_AVAILABLE);
130                 return GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
131         }
132
133         geocoder_s *handle = (geocoder_s*)malloc(sizeof(geocoder_s));
134         if(handle==NULL)
135         {
136                 GEOCODER_LOGE("OUT_OF_MEMORY(0x%08x)", GEOCODER_ERROR_OUT_OF_MEMORY);
137                 return GEOCODER_ERROR_OUT_OF_MEMORY;
138         }
139
140         memset(handle, 0 , sizeof(geocoder_s));
141
142         handle->object = location_map_new(NULL);
143         if(handle->object  == NULL)
144         {
145                 free(handle);
146                 GEOCODER_LOGE("GEOCODER_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_map_new", GEOCODER_ERROR_SERVICE_NOT_AVAILABLE);
147                 return GEOCODER_ERROR_SERVICE_NOT_AVAILABLE;
148         }
149
150         *geocoder = (geocoder_h)handle;
151         return GEOCODER_ERROR_NONE;
152 }
153
154 int     geocoder_destroy(geocoder_h geocoder)
155 {
156         GEOCODER_NULL_ARG_CHECK(geocoder);
157         geocoder_s *handle = (geocoder_s*)geocoder;
158
159         int ret = location_map_free(handle->object);
160         if(ret!=GEOCODER_ERROR_NONE)
161         {
162                 return __convert_error_code(ret);
163         }
164         free(handle);
165         return GEOCODER_ERROR_NONE;
166 }
167
168 int     geocoder_get_address_from_position(geocoder_h geocoder, double latitude, double longitude, geocoder_get_address_cb callback, void *user_data)
169 {
170         GEOCODER_NULL_ARG_CHECK(geocoder);
171         GEOCODER_NULL_ARG_CHECK(callback);
172         GEOCODER_CHECK_CONDITION(latitude>=-90 && latitude<=90 ,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
173         GEOCODER_CHECK_CONDITION(longitude>=-180 && longitude<=180,GEOCODER_ERROR_INVALID_PARAMETER,"GEOCODER_ERROR_INVALID_PARAMETER");
174
175         geocoder_s *handle = (geocoder_s*)geocoder;
176         int ret;
177         LocationPosition *pos = NULL;
178         pos = location_position_new (0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
179
180         __addr_callback_data * calldata = (__addr_callback_data *)malloc(sizeof(__addr_callback_data));
181         if( calldata == NULL)
182         {
183                 GEOCODER_LOGE("GEOCODER_ERROR_OUT_OF_MEMORY(0x%08x) : fail to create callback data", GEOCODER_ERROR_OUT_OF_MEMORY);
184                 return GEOCODER_ERROR_OUT_OF_MEMORY;
185         }
186         calldata->callback = callback;
187         calldata->data = user_data;
188
189         ret = location_map_get_address_from_position_async(handle->object, pos, __cb_address_from_position, calldata);
190         location_position_free(pos);
191         if( ret != LOCATION_ERROR_NONE)
192         {
193                 free(calldata);
194                 return __convert_error_code(ret);
195         }
196         return GEOCODER_ERROR_NONE;
197 }
198
199 int      geocoder_foreach_positions_from_address(geocoder_h geocoder,const char* address, geocoder_get_position_cb callback, void *user_data)
200 {
201         GEOCODER_NULL_ARG_CHECK(geocoder);
202         GEOCODER_NULL_ARG_CHECK(address);
203         GEOCODER_NULL_ARG_CHECK(callback);
204         geocoder_s *handle = (geocoder_s*)geocoder;
205
206         char* addr_str = g_strdup(address);
207
208         __pos_callback_data * calldata = (__pos_callback_data *)malloc(sizeof(__pos_callback_data));
209         if( calldata == NULL)
210         {
211                 GEOCODER_LOGE("GEOCODER_ERROR_OUT_OF_MEMORY(0x%08x) : fail to create callback data", GEOCODER_ERROR_OUT_OF_MEMORY);
212                 return GEOCODER_ERROR_OUT_OF_MEMORY;
213         }
214         calldata->callback = callback;
215         calldata->data = user_data;
216
217         int ret;
218         ret = location_map_get_position_from_freeformed_address_async(handle->object, addr_str,__cb_position_from_address, calldata);
219         g_free(addr_str);
220         if( ret != LOCATION_ERROR_NONE)
221         {
222                 return __convert_error_code(ret);
223         }
224         return GEOCODER_ERROR_NONE;
225 }