Update change log and spec for wrt-plugins-tizen_0.2.72
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Geocoder / DefaultGeocoderProvider.cpp
1 /*
2  * Copyright (c) 2011 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 <dlog.h>
18 #include <location_preference.h>
19 #include <glib.h>
20 #include "GeoAddress.h"
21 #include "DefaultGeocoderProvider.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "TIZEN_W_GEOCODER"
25
26 using namespace std;
27
28 namespace TizenApis {
29 namespace Tizen1_0 {
30 namespace LBS {
31
32 typedef struct 
33 {
34         int ret;
35         void *user_data;
36         setOptionCb callback;
37 }callback_data;
38
39 typedef struct 
40 {
41         void *user_data;
42         GeocodeResultArrayCallback callback;
43         GeocodeOptions option;  
44         std::vector<double> list;
45 }geocoder_geocode_cb_data;
46
47 typedef struct 
48 {
49         void *user_data;
50         ReverseGeocodeResultArrayCallback callback;
51         ReverseGeocodeOptions option;   
52         std::vector<std::string> strAddrList;   
53         std::vector<GeoAddress> geoAddrList;    
54 }geocoder_reverse_geocode_cb_data;
55
56 bool DefaultGeocoderProvider::preference_init_cb(const char *key, void *user_data)
57 {
58         int ret;
59         DefaultGeocoderProvider *obj = (DefaultGeocoderProvider *)user_data;
60         string pref(key);
61         char* value_str = NULL;
62         ret = location_preference_get(obj->nativeHandle, key, &value_str);
63         if( ret == LOCATION_PREFERENCE_ERROR_NONE && value_str != NULL )
64         {
65                 string value(value_str);
66                 obj->metadata.push_back(make_pair(pref,value));
67         }
68         obj->supportedOptions.push_back(pref);
69         return TRUE;
70 }
71
72 int DefaultGeocoderProvider::setOption_cb(void* user_data)
73 {
74         callback_data *data = (callback_data*)user_data;
75         if( data == NULL)
76                 return false;
77
78         data->callback( data->ret , data->user_data);
79         
80         if( data != NULL)
81                 delete data;
82         return false;
83 }
84
85 DefaultGeocoderProvider::DefaultGeocoderProvider():GeocoderProvider("default"), nativeHandle(NULL)
86 {
87         int ret = geocoder_create(&nativeHandle);
88         if( ret != GEOCODER_ERROR_NONE )
89         {
90                 LOGE("Error create Geocoder");
91                 return;
92         }
93
94         char *provider_name = NULL;
95         ret = location_preference_get_provider (GET_LOCATION_SERVICE(nativeHandle) , &provider_name);
96         if( ret == LOCATION_PREFERENCE_ERROR_NONE && provider_name != NULL)
97         {
98                 string providerName(provider_name);
99                 setName(providerName);  
100                 free(provider_name);
101         }
102
103         metadata.clear();
104         supportedOptions.clear();
105         location_preference_foreach_available_property_keys(GET_LOCATION_SERVICE(nativeHandle) , preference_init_cb,this);
106 }
107
108 DefaultGeocoderProvider::~DefaultGeocoderProvider()
109 {
110         LOGD("%s - Destroy the DefaultGeocoderProvider",__func__);
111         if(!nativeHandle)
112                 geocoder_destroy(nativeHandle);
113 }
114
115
116 vector<string> DefaultGeocoderProvider::getSupportedOptions()
117 {
118         return supportedOptions;
119 }
120
121
122 vector<pair<string, string>> DefaultGeocoderProvider::getMetadata()
123 {
124         return metadata;
125 }
126
127 int DefaultGeocoderProvider::setOption( std::vector<std::pair<std::string, std::string>> options, setOptionCb callback, void *user_data, LBSPending **pending)
128 {
129         std::vector<std::pair<std::string, std::string>>::iterator pos;
130         for( pos = options.begin() ; pos != options.end() ; ++pos)
131         {
132                 vector<string>::iterator check;
133                 bool isvalid = false;
134                 for ( check = supportedOptions.begin() ; check != supportedOptions.end() ; ++check )
135                 {
136                         if( *check == pos->first )
137                                 isvalid = true;
138                 }
139                 if( isvalid == false )
140                         return -1;
141         }
142
143         for( pos = options.begin() ; pos != options.end() ; ++pos)
144         {
145                 std::vector<std::pair<std::string, std::string>>::iterator target;
146                 int find = false;
147                 for( target = metadata.begin() ; target != metadata.end() ; ++target)
148                 {
149                         if ( target->first == pos->first )
150                         {
151                                 find = true;
152                                 target->second = pos->second;
153                         }
154                 }
155                 if( !find )
156                 {
157                         metadata.push_back(*pos);
158                 }
159         }
160
161         vector<pair<string, string>>::iterator key;
162         vector<pair<string, string>> newMetadata;
163         for( key = metadata.begin(); key != metadata.end() ; ++key)
164         {
165                 if( 0 == location_preference_set(nativeHandle, key->first.c_str() , key->second.c_str()))
166                         newMetadata.push_back(*key);
167         }
168         metadata = newMetadata;
169
170         callback_data *data = new callback_data();
171         data->user_data = user_data;
172         data->callback = callback;
173         data->ret = 0;
174     g_idle_add_full(G_PRIORITY_HIGH_IDLE, setOption_cb, data, NULL);
175         return 0;
176 }
177
178
179 string DefaultGeocoderProvider::getConnectivity()
180 {
181         return string("ONLINE");
182 }
183
184 bool DefaultGeocoderProvider::isUsedExternalNetwork()
185 {
186         return true;
187 }
188
189 bool DefaultGeocoderProvider::get_position_cb(geocoder_error_e result, double latitude, double longitude, void *user_data)
190 {
191         LOGE("%s - start", __func__);
192         geocoder_geocode_cb_data *calldata = (geocoder_geocode_cb_data*)user_data;
193         if( calldata == NULL )
194                 return FALSE;
195
196         if( result != GEOCODER_ERROR_NONE )
197         {
198                 int ret;
199                 switch(result)
200                 {
201                 case GEOCODER_ERROR_NETWORK_FAILED:
202                         ret = GEOCODER_ERROR::NETWORK_FAILED;
203                         break;
204                 case GEOCODER_ERROR_TIMED_OUT:
205                         ret = GEOCODER_ERROR::TIMEOUT;
206                         break;
207                 case GEOCODER_ERROR_NOT_FOUND:
208                         ret =GEOCODER_ERROR::NONE;
209                         break;
210                 case GEOCODER_ERROR_SERVICE_NOT_AVAILABLE:
211                 default:
212                         ret = GEOCODER_ERROR::SERVICE_NOT_AVAILABLE;
213                         break;
214                 }
215                 calldata->callback( ret, calldata->list,  calldata->user_data );
216                 delete calldata;
217                 return FALSE;
218         }
219
220         //TODO: option check
221         //calldata->option.maxResult 
222         LOGE("%s - latitude : %lf, longitude : %lf",__func__, latitude, longitude);
223
224         calldata->list.push_back(latitude);
225         calldata->list.push_back(longitude);
226
227         //TODO: Only for last result
228         if(1)
229         {
230                 calldata->callback(0 , calldata->list,  calldata->user_data);
231                 delete calldata;
232         }
233
234         LOGE("%s - end", __func__);
235         //TODO: Need to consider multiple result
236         return FALSE;
237 }
238
239 void    DefaultGeocoderProvider::get_address_cb(geocoder_error_e result, const char *building_number, const char *postal_code, const char *street, const char *city, const char *district, const char *state, const char *country_code, void *user_data)
240 {
241         LOGE("%s - start", __func__);
242         geocoder_reverse_geocode_cb_data *calldata = (geocoder_reverse_geocode_cb_data*)user_data;
243         if( calldata == NULL )
244                 return;
245
246         if( result != GEOCODER_ERROR_NONE )
247         {
248                 int ret;
249                 switch(result)
250                 {
251                 case GEOCODER_ERROR_NETWORK_FAILED:
252                         ret = GEOCODER_ERROR::NETWORK_FAILED;
253                         break;
254                 case GEOCODER_ERROR_TIMED_OUT:
255                         ret = GEOCODER_ERROR::TIMEOUT;
256                         break;
257                 case GEOCODER_ERROR_SERVICE_NOT_AVAILABLE:
258                 default:
259                         ret = GEOCODER_ERROR::SERVICE_NOT_AVAILABLE;
260                         break;
261                 }
262                 calldata->callback( ret, calldata->strAddrList, calldata->geoAddrList,  calldata->user_data);
263                 delete calldata;
264                 return;
265         }
266
267         if (calldata->option.addressType == ReverseGeocodeOptions::AddressType::FORMATTED)
268         {
269                 LOGE("AddressType::FORMATTED");
270                 std::string simpleAddr;
271                 if(building_number)
272                 {
273                         simpleAddr+=building_number;
274                         simpleAddr+=    " ";
275                 }
276                 if(postal_code)
277                 {
278                         simpleAddr+=postal_code;
279                         simpleAddr+=    " ";
280                 }
281                 if(street)
282                 {
283                         simpleAddr+=street;
284                         simpleAddr+=    " ";
285                 }
286                 if(city)
287                 {
288                         simpleAddr+=city;
289                         simpleAddr+=    " ";
290                 }
291                 if(district)
292                 {
293                         simpleAddr+=district;
294                         simpleAddr+=    " ";
295                 }
296                 if(state)
297                 {
298                         simpleAddr+=state;
299                         simpleAddr+=    " ";
300                 }
301                 if(country_code)
302                         simpleAddr+=country_code;
303
304                 LOGE("%s - AddressType::FORMATTED - Address: %s", __func__,simpleAddr.c_str());
305                 calldata->strAddrList.push_back(simpleAddr);
306         }
307         else // for ReverseGeocodeOptions::AddressType::STRUCTURED
308         {
309                 LOGE("AddressType::STRUCTURED");
310                 GeoAddress structedAddress;
311                 if(country_code)
312                         structedAddress.country = string(country_code);
313                 if(state)
314                         structedAddress.region = string(state);
315                 if(district)
316                         structedAddress.county = string(district);
317                 if(city)
318                         structedAddress.city = string(city);
319                 if(street)
320                         structedAddress.street = string(street);
321                 if(building_number)
322                         structedAddress.premises = string(building_number);
323                 if(postal_code)
324                         structedAddress.postalCode = string(postal_code);
325
326                 LOGE("%s - AddressType::STRUCTURED - contry_code:%s, state:%s, district:%s, city:%s, street:%s , premises:%s , postalCode:%s ", __func__,country_code, state, district, city, street, building_number, postal_code);
327                 calldata->geoAddrList.push_back(structedAddress);
328         }
329         calldata->callback(0 , calldata->strAddrList, calldata->geoAddrList,  calldata->user_data);
330         LOGE("%s - end", __func__);
331         delete calldata;
332 }
333
334 int DefaultGeocoderProvider::geocode(GeoAddress address, GeocodeOptions& option, GeocodeResultArrayCallback callback, void *user_data)
335 {
336         LOGE("%s - geocode with GeoAddress", __func__);
337
338         geocoder_geocode_cb_data * calldata = NULL;     
339         int retval = GEOCODER_ERROR::NONE;
340         int ret = GEOCODER_ERROR_NONE;
341
342         //TODO: Geocoder Preference 
343         //if( option.maxResult != 0 )
344         //      geocoder_preference_set_max_result(preference, option.maxResult);
345         //if( option.sortAttributeName != "" )
346         //{
347         //      geocoder_preference_set_sort(preference , option.sortAttributeName.c_str(), option.sortOrder == RequestOptions::SortOrder::ASC ? GEOCODER_SORTORDER_ASC : GEOCODER_SORTORDER_DESC);
348         //}
349
350         calldata = new geocoder_geocode_cb_data();
351         if (calldata ==NULL)
352         {
353                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
354                 goto destroy;
355         }
356
357         calldata->user_data = user_data;
358         calldata->callback = callback;
359         calldata->option = option;
360
361         ret = geocoder_foreach_positions_from_address(nativeHandle, address.toSimpleAddress().c_str(), get_position_cb, calldata);
362
363         switch(ret)
364         {
365         case GEOCODER_ERROR_NONE:
366                 calldata = NULL;
367                 break;
368         case GEOCODER_ERROR_OUT_OF_MEMORY:
369                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
370                 break;
371         case GEOCODER_ERROR_INVALID_PARAMETER:
372                 retval = GEOCODER_ERROR::INVALID_PARAMETER;
373                 break;
374         case GEOCODER_ERROR_NETWORK_FAILED :
375                 retval = GEOCODER_ERROR::NETWORK_FAILED;
376                 break;
377         case GEOCODER_ERROR_TIMED_OUT:
378                 retval = GEOCODER_ERROR::TIMEOUT;
379                 break;
380         case GEOCODER_ERROR_SERVICE_NOT_AVAILABLE :
381         default:
382                 retval = GEOCODER_ERROR::SERVICE_NOT_AVAILABLE;
383                 break;
384         }
385         
386 destroy:                
387         if( calldata)
388                 delete calldata;        
389         return retval;          
390 }
391
392 int DefaultGeocoderProvider::geocode(std::string& address, GeocodeOptions & option, GeocodeResultArrayCallback callback, void *user_data)
393 {
394         LOGE("%s - geocode with Freeformed address", __func__);
395
396         geocoder_geocode_cb_data * calldata = NULL;     
397         int retval = GEOCODER_ERROR::NONE;
398         int ret = GEOCODER_ERROR_NONE;
399
400         //TODO: Geocoder Preference 
401         //if( option.maxResult != 0 )
402         //      geocoder_preference_set_max_result(preference, option.maxResult);
403         //if( option.sortAttributeName != "" )
404         //{
405         //      geocoder_preference_set_sort(preference , option.sortAttributeName.c_str(), option.sortOrder == RequestOptions::SortOrder::ASC ? GEOCODER_SORTORDER_ASC : GEOCODER_SORTORDER_DESC);
406         //}
407
408         calldata = new geocoder_geocode_cb_data();
409         if (calldata ==NULL)
410         {
411                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
412                 goto destroy;
413         }
414
415         calldata->user_data = user_data;
416         calldata->callback = callback;
417         calldata->option = option;
418
419         ret = geocoder_foreach_positions_from_address(nativeHandle, address.c_str(), get_position_cb, calldata);
420
421         switch(ret)
422         {
423         case GEOCODER_ERROR_NONE:
424                 calldata = NULL;
425                 break;
426         case GEOCODER_ERROR_OUT_OF_MEMORY:
427                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
428                 break;
429         case GEOCODER_ERROR_INVALID_PARAMETER:
430                 retval = GEOCODER_ERROR::INVALID_PARAMETER;
431                 break;
432         case GEOCODER_ERROR_NETWORK_FAILED :
433                 retval = GEOCODER_ERROR::NETWORK_FAILED;
434                 break;
435         case GEOCODER_ERROR_TIMED_OUT:
436                 retval = GEOCODER_ERROR::TIMEOUT;
437                 break;
438         case GEOCODER_ERROR_SERVICE_NOT_AVAILABLE :
439         default:
440                 retval = GEOCODER_ERROR::SERVICE_NOT_AVAILABLE;
441                 break;
442         }
443         
444 destroy:                
445         if( calldata)
446                 delete calldata;        
447         return retval;          
448 }
449
450
451 int DefaultGeocoderProvider::reverseGeocode(double latitude, double longitude, ReverseGeocodeOptions& option, ReverseGeocodeResultArrayCallback callback, void *user_data)
452 {
453         LOGE("%s - reverseGeocode", __func__);
454
455         geocoder_reverse_geocode_cb_data * calldata = NULL;     
456         int retval = 0;
457         int ret = GEOCODER_ERROR_NONE;
458
459         //TODO: Geocoder Preference 
460         //if( option.maxResult != 0 )
461         //      geocoder_preference_set_max_result(preference, option.maxResult);
462         //if( option.sortAttributeName != "" )
463         //{
464         //      geocoder_preference_set_sort(preference , option.sortAttributeName.c_str(), option.sortOrder == RequestOptions::SortOrder::ASC ? GEOCODER_SORTORDER_ASC : GEOCODER_SORTORDER_DESC);
465         //}
466         
467         calldata = new geocoder_reverse_geocode_cb_data();
468         if( calldata == NULL)
469         {
470                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
471                 goto destroy;
472         }
473
474         calldata->user_data = user_data;
475         calldata->callback = callback;
476         calldata->option = option;
477
478         ret = geocoder_get_address_from_position(nativeHandle, latitude, longitude, get_address_cb, calldata);
479
480         switch(ret)
481         {
482         case GEOCODER_ERROR_NONE:
483                 calldata = NULL;
484                 break;
485         case GEOCODER_ERROR_OUT_OF_MEMORY:
486                 retval = GEOCODER_ERROR::OUT_OF_MEMORY;
487                 break;
488         case GEOCODER_ERROR_INVALID_PARAMETER:
489                 retval = GEOCODER_ERROR::INVALID_PARAMETER;
490                 break;
491         case GEOCODER_ERROR_NETWORK_FAILED :
492                 retval = GEOCODER_ERROR::NETWORK_FAILED;
493                 break;
494         case GEOCODER_ERROR_TIMED_OUT:
495                 retval = GEOCODER_ERROR::TIMEOUT;
496                 break;
497         case GEOCODER_ERROR_SERVICE_NOT_AVAILABLE :
498         default:
499                 retval = GEOCODER_ERROR::SERVICE_NOT_AVAILABLE;
500                 break;
501         }
502         
503 destroy:                
504         if( calldata)
505                 delete calldata;        
506         return retval;          
507 }
508         
509 } //LBS
510 } //Tizen1_0
511 } // TizenApis
512