Fixed svace defects
[platform/core/location/maps-plugin-mapquest.git] / src / mapquest_plugin.c
1 /*
2  * Copyright (c) 2014 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 "mapquest_plugin.h"
20 #include "mapquest_plugin_internal.h"
21 #include "mapquest_api.h"
22 #include "mapquest_util.h"
23 #include <maps_error.h>
24 #include <maps_route_plugin.h>
25 #include <maps_route_segment_plugin.h>
26 #include <maps_route_maneuver_plugin.h>
27 #include <maps_place_plugin.h>
28 #include <maps_place_category.h>
29 #include <maps_place_image_plugin.h>
30 #include <maps_place_rating_plugin.h>
31
32 #define DEFAULT_NUM_RESULTS     10
33 #define _PROVIDER_KEY_MAX_SIZE 1024
34
35 static const double LATITUDE_RANGE = 85.05113;
36 static const double LONGITUDE_RANGE = 180.0;
37
38 static int __request_id = 0;
39 static maps_plugin_h __plugin = NULL;
40 static char __provider_key[_PROVIDER_KEY_MAX_SIZE] = { 0 };
41
42 static maps_item_hashtable_h preference_plugin = NULL;
43
44 int __maps_service_instance_count = 0;
45
46 static int __convert_to_maps_error(int ret)
47 {
48         switch (ret) {
49         case MAPQUEST_ERROR_NONE:
50                 return MAPS_ERROR_NONE;
51         case MAPQUEST_ERROR_PERMISSION_DENIED:
52                 return MAPS_ERROR_PERMISSION_DENIED;
53         case MAPQUEST_ERROR_OUT_OF_MEMORY:
54                 return MAPS_ERROR_OUT_OF_MEMORY;
55         case MAPQUEST_ERROR_INVALID_PARAMETER:
56                 return MAPS_ERROR_INVALID_PARAMETER;
57         case MAPQUEST_ERROR_NOT_SUPPORTED:
58                 return MAPS_ERROR_NOT_SUPPORTED;
59         case MAPQUEST_ERROR_CONNECTION_TIMED_OUT:
60                 return MAPS_ERROR_CONNECTION_TIME_OUT;
61         case MAPQUEST_ERROR_NETWORK_UNREACHABLE:
62                 return MAPS_ERROR_NETWORK_UNREACHABLE;
63         case MAPQUEST_ERROR_INVALID_OPERATION:
64                 return MAPS_ERROR_INVALID_OPERATION;
65         case MAPQUEST_ERROR_KEY_NOT_AVAILABLE:
66                 return MAPS_ERROR_KEY_NOT_AVAILABLE;
67         case MAPQUEST_ERROR_RESOURCE_BUSY:
68                 return MAPS_ERROR_RESOURCE_BUSY;
69         case MAPQUEST_ERROR_CANCELED:
70                 return MAPS_ERROR_CANCELED;
71         case MAPQUEST_ERROR_UNKNOWN:
72                 return MAPS_ERROR_UNKNOWN;
73         case MAPQUEST_ERROR_SERVICE_NOT_AVAILABLE:
74                 return MAPS_ERROR_SERVICE_NOT_AVAILABLE;
75         case MAPQUEST_ERROR_NOT_FOUND:
76                 return MAPS_ERROR_NOT_FOUND;
77         default:
78                 return MAPS_ERROR_UNKNOWN;
79         }
80 }
81
82 static maps_route_turn_type_e __convert_route_turn_type(int index)
83 {
84         maps_route_turn_type_e type = MAPS_ROUTE_TURN_TYPE_NONE;
85
86         if (index == 0)
87                 type = MAPS_ROUTE_TURN_TYPE_STRAIGHT;
88         else if (index == 1)
89                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT;
90         else if (index == 2)
91                 type = MAPS_ROUTE_TURN_TYPE_RIGHT;
92         else if (index == 3)
93                 type = MAPS_ROUTE_TURN_TYPE_HARD_RIGHT;
94         else if (index == 5)
95                 type = MAPS_ROUTE_TURN_TYPE_HARD_LEFT;
96         else if (index == 6)
97                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
98         else if (index == 7)
99                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
100         else if (index == 8)
101                 type = MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT;
102         else if (index == 9)
103                 type = MAPS_ROUTE_TURN_TYPE_UTURN_LEFT;
104         else if (index == 16)
105                 type = MAPS_ROUTE_TURN_TYPE_RIGHT_FORK;
106         else if (index == 17)
107                 type = MAPS_ROUTE_TURN_TYPE_LEFT_FORK;
108         else if (index == 18)
109                 type = MAPS_ROUTE_TURN_TYPE_STRAIGHT_FORK;
110         else
111                 type = MAPS_ROUTE_TURN_TYPE_NONE;
112
113         return type;
114 }
115
116 static bool __replace_space(char *place_name, char **modified_place_name)
117 {
118         if (!place_name) return false;
119
120         int new_str_len = 0;
121         char *ch;
122         for (ch = place_name; *ch != '\0'; ch++) {
123                 if (*ch == ' ')
124                         new_str_len += 2;
125                 new_str_len++;
126         }
127
128         if (strlen(place_name) < new_str_len) {
129                 *modified_place_name = (char *)g_malloc((new_str_len + 1) * sizeof(char));
130                 if (*modified_place_name) {
131                         char *ch1, *ch2;
132                         for (ch1 = place_name, ch2 = *modified_place_name; *ch1 != '\0'; ch1++) {
133                                 if (*ch1 == ' ') {
134                                         ch2[0] = '%';
135                                         ch2[1] = '2';
136                                         ch2[2] = '0';
137                                         ch2 += 3;
138                                 } else {
139                                         *ch2 = *ch1;
140                                         ch2++;
141                                 }
142                         }
143                         *ch2 = '\0';
144
145                         return true;
146                 }
147         }
148         return false;
149 }
150
151 EXPORT_API int maps_plugin_init(maps_plugin_h *plugin)
152 {
153         if (!plugin)
154                 return MAPS_ERROR_INVALID_PARAMETER;
155
156         int ret = MAPS_ERROR_NONE;
157         if (!__plugin) {
158                 ret = mapquest_init();
159         }
160
161         if (ret == MAPS_ERROR_NONE) {
162                 __maps_service_instance_count++;
163                 __plugin = plugin;
164         }
165
166         return __convert_to_maps_error(ret);
167 }
168
169 EXPORT_API int maps_plugin_shutdown(maps_plugin_h plugin)
170 {
171         MAPS_LOGD("PLUGIN SHUTDOWN");
172         if (!plugin)
173                 return MAPS_ERROR_INVALID_PARAMETER;
174
175         __maps_service_instance_count--;
176
177         int ret = MAPS_ERROR_NONE;
178         if (__maps_service_instance_count == 0) {
179                 ret = mapquest_shutdown();
180                 __plugin = NULL;
181         }
182
183         return __convert_to_maps_error(ret);
184 }
185
186 EXPORT_API int maps_plugin_is_service_supported(maps_service_e service, bool *supported)
187 {
188         if (!supported)
189                 return MAPS_ERROR_INVALID_PARAMETER;
190
191         switch (service) {
192         case MAPS_SERVICE_GEOCODE:
193         case MAPS_SERVICE_GEOCODE_INSIDE_AREA:
194         case MAPS_SERVICE_GEOCODE_BY_STRUCTURED_ADDRESS:
195         case MAPS_SERVICE_REVERSE_GEOCODE:
196         case MAPS_SERVICE_SEARCH_PLACE:
197         case MAPS_SERVICE_SEARCH_PLACE_BY_AREA:
198         case MAPS_SERVICE_SEARCH_PLACE_BY_ADDRESS:
199         case MAPS_SERVICE_SEARCH_ROUTE:
200         case MAPS_SERVICE_SEARCH_ROUTE_WAYPOINTS:
201         case MAPS_SERVICE_CANCEL_REQUEST:
202                 *supported = true;
203                 return MAPS_ERROR_NONE;
204         default:
205                 *supported = false;
206                 return MAPS_ERROR_NOT_SUPPORTED;
207         }
208 }
209
210 EXPORT_API int maps_plugin_is_data_supported(maps_service_data_e data, bool *supported)
211 {
212         if (!supported)
213                 return MAPS_ERROR_INVALID_PARAMETER;
214
215         switch (data) {
216         case MAPS_PLACE_ADDRESS:
217         case MAPS_PLACE_CATEGORIES:
218         case MAPS_PLACE_IMAGE:
219                 /* unsupported */
220                 /* case MAPS_PLACE_RATING: */
221                 /* case MAPS_PLACE_ATTRIBUTES: */
222                 /* case MAPS_PLACE_CONTACTS: */
223                 /* case MAPS_PLACE_EDITORIALS: */
224                 /* case MAPS_PLACE_REVIEWS: */
225                 /* case MAPS_PLACE_SUPPLIER: */
226                 /* case MAPS_PLACE_RELATED: */
227
228         case MAPS_ROUTE_PATH:
229         case MAPS_ROUTE_SEGMENTS_PATH:
230         case MAPS_ROUTE_SEGMENTS_MANEUVERS:
231                 *supported = true;
232                 return MAPS_ERROR_NONE;
233         default:
234                 *supported = false;
235                 return MAPS_ERROR_NOT_SUPPORTED;
236         }
237 }
238
239 EXPORT_API int maps_plugin_get_info(maps_plugin_info_h *info)
240 {
241         if (!info)
242                 return MAPS_ERROR_INVALID_PARAMETER;
243
244         maps_plugin_info_create(info);
245         maps_plugin_info_set_provider_name(*info, "MAPQUEST");
246
247         return MAPS_ERROR_NONE;
248 }
249
250 EXPORT_API int maps_plugin_set_provider_key(const char *provider_key)
251 {
252         if (!provider_key)
253                 return MAPS_ERROR_INVALID_PARAMETER;
254
255         g_snprintf(__provider_key, _PROVIDER_KEY_MAX_SIZE, "%s", provider_key);
256
257         return MAPS_ERROR_NONE;
258 }
259
260 EXPORT_API int maps_plugin_get_provider_key(char **provider_key)
261 {
262         if (!provider_key)
263                 return MAPS_ERROR_INVALID_PARAMETER;
264
265         *provider_key = g_strndup(__provider_key, _PROVIDER_KEY_MAX_SIZE);
266
267         return MAPS_ERROR_NONE;
268 }
269
270 EXPORT_API int maps_plugin_set_preference(maps_item_hashtable_h preference)
271 {
272         if (!preference)
273                 return MAPS_ERROR_INVALID_PARAMETER;
274
275         maps_item_hashtable_clone(preference, &preference_plugin);
276         return MAPS_ERROR_NONE;
277 }
278
279 EXPORT_API int maps_plugin_get_preference(maps_item_hashtable_h *preference)
280 {
281         if (!preference)
282                 return MAPS_ERROR_INVALID_PARAMETER;
283
284         maps_item_hashtable_clone(preference_plugin, preference);
285         return MAPS_ERROR_NONE;
286 }
287
288 static void __mapquest_geocode_cb(mapquest_error_e result, int request_id, GList *co_ordinates, void *user_data)
289 {
290         MAPS_LOGD("Got GEOCODE callback from ENGINE");
291
292         callback_info_geocode *calldata_geocode = (callback_info_geocode *) user_data;
293
294         if ((result != MAPQUEST_ERROR_NONE) || (co_ordinates == NULL)) {
295                 MAPS_LOGD(">>>>> Invalid GEOCODE result <<<<<");
296                 calldata_geocode->callback((maps_error_e)__convert_to_maps_error(result), calldata_geocode->reqID, 0, 0, NULL, calldata_geocode->data);
297         } else {
298                 int total_count = (int) g_list_length(co_ordinates);
299                 int index = 0;
300
301                 GList *coords = NULL;
302                 coords = g_list_first(co_ordinates);
303
304                 while (coords) {
305                         MAPS_LOGD("coordinate %d", index);
306                         coords_s *data = (coords_s *) coords->data;
307
308                         if (data != NULL) {
309                                 maps_coordinates_h resultCoords;
310                                 maps_coordinates_create(data->latitude, data->longitude, &resultCoords);
311                                 bool b = calldata_geocode->callback(MAPS_ERROR_NONE, calldata_geocode->reqID, index, total_count, resultCoords, calldata_geocode->data);
312                                 if (!b)
313                                         return;
314                         }
315                         index++;
316                         coords = coords->next;
317                 }
318         }
319 }
320
321 EXPORT_API int maps_plugin_geocode(const char *address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
322 {
323         if (!address || !callback || !request_id)
324                 return MAPS_ERROR_INVALID_PARAMETER;
325
326         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
327         if (calldata_geocode == NULL)
328                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
329
330         calldata_geocode->callback = callback;
331         calldata_geocode->data = user_data;
332
333         mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
334         if (geocode_req == NULL) {
335                 g_free(calldata_geocode);
336                 calldata_geocode = NULL;
337                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
338         }
339
340         char *modified_address = NULL;
341         bool b_isAddress_modified = false;
342         b_isAddress_modified = __replace_space((char *)address, &modified_address);
343
344         if (b_isAddress_modified)
345                 geocode_req->address = g_strdup((gchar *) modified_address);
346         else
347                 geocode_req->address = g_strdup((gchar *) address);
348
349         if (modified_address) {
350                 g_free(modified_address);
351                 modified_address = NULL;
352         }
353
354         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
355         geocode_req->boundary = NULL;
356
357         int max_result = 0;
358         maps_preference_get_max_results(preference, &max_result);
359
360         if (max_result <= 0)
361                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
362         else
363                 geocode_req->num_res = max_result;
364
365         *request_id = ++__request_id;
366         calldata_geocode->reqID = __request_id;
367
368         int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
369
370         return __convert_to_maps_error(ret);
371 }
372
373 EXPORT_API int maps_plugin_geocode_inside_area(const char *address, const maps_area_h bounds, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
374 {
375         if (!bounds || !address || !callback || !request_id)
376                 return MAPS_ERROR_INVALID_PARAMETER;
377
378         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
379         if (calldata_geocode == NULL)
380                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
381
382         calldata_geocode->callback = callback;
383         calldata_geocode->data = user_data;
384
385         mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
386         if (geocode_req == NULL) {
387                 free(calldata_geocode);
388                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
389         }
390
391         char *modified_address = NULL;
392         bool b_isAddress_modified = false;
393         b_isAddress_modified = __replace_space((char *)address, &modified_address);
394
395         if (b_isAddress_modified)
396                 geocode_req->address = g_strdup((gchar *) modified_address);
397         else
398                 geocode_req->address = g_strdup((gchar *) address);
399
400         if (modified_address) {
401                 g_free(modified_address);
402                 modified_address = NULL;
403         }
404
405         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
406
407         int max_result = 0;
408         maps_preference_get_max_results(preference, &max_result);
409
410         if (max_result <= 0)
411                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
412         else
413                 geocode_req->num_res = max_result;
414
415         geocode_req->boundary = NULL;
416         geocode_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
417
418         maps_area_s *area = (maps_area_s *) bounds;
419
420         if (area && geocode_req->boundary) {
421                 if (area->type == MAPS_AREA_RECTANGLE) {
422                         geocode_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
423                         geocode_req->boundary->rect.top_left.latitude = area->rect.top_left.latitude;
424                         geocode_req->boundary->rect.top_left.longitude = area->rect.top_left.longitude;
425                         geocode_req->boundary->rect.bottom_right.latitude = area->rect.bottom_right.latitude;
426                         geocode_req->boundary->rect.bottom_right.longitude = area->rect.bottom_right.longitude;
427                 } else if (area->type == MAPS_AREA_CIRCLE) {
428                         geocode_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
429                         geocode_req->boundary->circle.center.latitude = area->circle.center.latitude;
430                         geocode_req->boundary->circle.center.longitude = area->circle.center.longitude;
431                         geocode_req->boundary->circle.radius = area->circle.radius;
432                 }
433         }
434
435         *request_id = ++__request_id;
436         calldata_geocode->reqID = __request_id;
437
438         int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
439
440         return __convert_to_maps_error(ret);
441 }
442
443 EXPORT_API int maps_plugin_geocode_by_structured_address(const maps_address_h address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
444 {
445         if (!address || !callback || !request_id)
446                 return MAPS_ERROR_INVALID_PARAMETER;
447
448         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
449         if (calldata_geocode == NULL)
450                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
451
452         calldata_geocode->callback = callback;
453         calldata_geocode->data = user_data;
454
455         mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
456         if (geocode_req == NULL) {
457                 free(calldata_geocode);
458                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
459         }
460
461         char resultAddressQuery[1024] = "";
462
463         char *street = NULL;
464         maps_address_get_street(address, &street);
465         if (street != NULL)
466                 STRCAT(resultAddressQuery, street);
467
468         char *city = NULL;
469         maps_address_get_city(address, &city);
470         if ((strlen(resultAddressQuery) > 0) && (city != NULL)) {
471                 STRCAT(resultAddressQuery, ",");
472                 STRCAT(resultAddressQuery, city);
473         } else if (city != NULL) {
474                 STRCAT(resultAddressQuery, city);
475         }
476
477         char *state = NULL;
478         maps_address_get_state(address, &state);
479         if ((strlen(resultAddressQuery) > 0) && (state != NULL)) {
480                 STRCAT(resultAddressQuery, ",");
481                 STRCAT(resultAddressQuery, state);
482         } else if (state != NULL) {
483                 STRCAT(resultAddressQuery, state);
484         }
485
486 #if 0
487         char *district = NULL;
488         maps_address_get_district(address, &district);
489         if ((strlen(resultAddressQuery) > 0) && (district != NULL)) {
490                 STRCAT(resultAddressQuery, ", ");
491                 STRCAT(resultAddressQuery, district);
492         }
493
494         char *country = NULL;
495         maps_address_get_country(address, &country);
496         if ((strlen(resultAddressQuery) > 0) && (country != NULL)) {
497                 STRCAT(resultAddressQuery, ", ");
498                 STRCAT(resultAddressQuery, country);
499         }
500
501         char *country_code = NULL;
502         maps_address_get_country_code(address, &country_code);
503         if ((strlen(resultAddressQuery) > 0) && (country_code != NULL)) {
504                 STRCAT(resultAddressQuery, ", ");
505                 STRCAT(resultAddressQuery, country_code);
506         } else if (country_code != NULL) {
507                 STRCAT(resultAddressQuery, country_code);
508         }
509
510         char *county = NULL;
511         maps_address_get_county(address, &county);
512         if ((strlen(resultAddressQuery) > 0) && (county != NULL)) {
513                 STRCAT(resultAddressQuery, ", ");
514                 STRCAT(resultAddressQuery, county);
515         }
516 #endif
517
518         char *postal_code = NULL;
519         maps_address_get_postal_code(address, &postal_code);
520         if ((strlen(resultAddressQuery) > 0) && (postal_code != NULL)) {
521                 STRCAT(resultAddressQuery, ",");
522                 STRCAT(resultAddressQuery, postal_code);
523         } else if (postal_code != NULL) {
524                 STRCAT(resultAddressQuery, postal_code);
525         }
526
527         char *modified_address = NULL;
528         bool b_isAddress_modified = false;
529         b_isAddress_modified = __replace_space(resultAddressQuery, &modified_address);
530
531         if (b_isAddress_modified)
532                 geocode_req->address = g_strdup((gchar *) modified_address);
533         else
534                 geocode_req->address = g_strdup((gchar *) resultAddressQuery);
535
536         if (modified_address) {
537                 g_free(modified_address);
538                 modified_address = NULL;
539         }
540
541         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
542         geocode_req->boundary = NULL;
543
544         int max_result = 0;
545         maps_preference_get_max_results(preference, &max_result);
546
547         if (max_result <= 0)
548                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
549         else
550                 geocode_req->num_res = max_result;
551
552         *request_id = ++__request_id;
553         calldata_geocode->reqID = __request_id;
554
555         int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
556
557         return __convert_to_maps_error(ret);
558 }
559
560 static void __mapquest_reverse_geocode_cb(mapquest_error_e result, int request_id, mapquest_address_resp_s *address, void *user_data)
561 {
562         MAPS_LOGD("Got REV GEOCODE callback from ENGINE");
563         callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *) user_data;
564         if (result != MAPQUEST_ERROR_NONE || address == NULL) {
565                 calldata_reverse_geocode->callback((maps_error_e) __convert_to_maps_error(result), calldata_reverse_geocode->reqID, 0, 0, NULL, calldata_reverse_geocode->data);
566         } else {
567                 int total_count = 1;
568                 int index = 0;
569
570                 maps_address_h addr = NULL;
571                 maps_address_create(&addr);
572
573                 maps_address_set_street(addr, address->street_add);
574                 maps_address_set_city(addr, address->city);
575                 maps_address_set_county(addr, address->county);
576                 maps_address_set_state(addr, address->state);
577                 maps_address_set_country(addr, address->country);
578                 maps_address_set_country_code(addr, address->country_code);
579                 maps_address_set_postal_code(addr, address->postal_code);
580
581                 calldata_reverse_geocode->callback(MAPS_ERROR_NONE, calldata_reverse_geocode->reqID, index, total_count, addr, calldata_reverse_geocode->data);
582         }
583 }
584
585 EXPORT_API int maps_plugin_reverse_geocode(double latitude, double longitude, const maps_preference_h preference, maps_service_reverse_geocode_cb callback, void *user_data, int *request_id)
586 {
587         if (!callback || !request_id)
588                 return MAPS_ERROR_INVALID_PARAMETER;
589
590         if (latitude > LATITUDE_RANGE || latitude < -LATITUDE_RANGE)
591                 return MAPS_ERROR_INVALID_PARAMETER;
592
593         if (longitude > LONGITUDE_RANGE || longitude < -LONGITUDE_RANGE)
594                 return MAPS_ERROR_INVALID_PARAMETER;
595
596         callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *)g_malloc0(sizeof(callback_info_reverse_geocode));
597         if (calldata_reverse_geocode == NULL)
598                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
599
600         calldata_reverse_geocode->callback = callback;
601         calldata_reverse_geocode->data = user_data;
602
603         mapquest_revgeocode_req_s *reverse_geocode_req = (mapquest_revgeocode_req_s *)g_malloc0(sizeof(mapquest_revgeocode_req_s));
604         if (reverse_geocode_req == NULL) {
605                 g_free(calldata_reverse_geocode);
606                 calldata_reverse_geocode = NULL;
607                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
608         }
609
610         reverse_geocode_req->maps_key = g_strdup((gchar *) __provider_key);
611         reverse_geocode_req->coordinates.latitude = latitude;
612         reverse_geocode_req->coordinates.longitude = longitude;
613
614         *request_id = ++__request_id;
615         calldata_reverse_geocode->reqID = __request_id;
616
617         int ret = mapquest_reverse_geocode(reverse_geocode_req, __mapquest_reverse_geocode_cb, __request_id, (void *) calldata_reverse_geocode);
618
619         return __convert_to_maps_error(ret);
620 }
621
622 static void __mapquest_route_cb(mapquest_error_e result, int request_id, mapquest_route_resp_s *route_info, void *user_data)
623 {
624         MAPS_LOGD("__mapquest_route_cb");
625         callback_info_route *calldata_route = (callback_info_route *) user_data;
626
627         if (route_info) {
628                 maps_route_h route;
629                 maps_route_create(&route);
630
631                 maps_coordinates_h top_left;
632                 maps_coordinates_create(route_info->bounding_box.top_left.latitude, route_info->bounding_box.top_left.longitude, &top_left);
633
634                 maps_coordinates_h bottom_right;
635                 maps_coordinates_create(route_info->bounding_box.bottom_right.latitude, route_info->bounding_box.bottom_right.longitude, &bottom_right);
636
637                 maps_area_h bounds = NULL;
638                 maps_area_create_rectangle(top_left, bottom_right, &bounds);
639                 maps_route_set_bounding_box(route, bounds);
640                 maps_area_destroy(bounds);
641
642                 maps_coordinates_destroy(top_left);
643                 maps_coordinates_destroy(bottom_right);
644
645                 maps_distance_unit_e unit = MAPS_DISTANCE_UNIT_M;
646
647                 switch (route_info->distance_unit) {
648                 case ROUTE_UNIT_M:
649                         unit = MAPS_DISTANCE_UNIT_M;
650                         break;
651                 case ROUTE_UNIT_KM:
652                         unit = MAPS_DISTANCE_UNIT_KM;
653                         break;
654                 case ROUTE_UNIT_FT:
655                         unit = MAPS_DISTANCE_UNIT_FT;
656                         break;
657                 case ROUTE_UNIT_YD:
658                         unit = MAPS_DISTANCE_UNIT_YD;
659                         break;
660                 }
661
662                 maps_route_set_distance_unit(route, unit);
663                 maps_route_set_total_distance(route, route_info->distance);
664                 maps_route_set_total_duration(route, (long) route_info->time);
665                 if (route_info->type == ROUTE_TYPE_FASTEST)
666                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
667                 else if (route_info->type == ROUTE_TYPE_PEDESTRIAN)
668                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN);
669                 else if (route_info->type == ROUTE_TYPE_BICYCLE)
670                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_BICYCLE);
671                 else if (route_info->type == ROUTE_TYPE_MULTIMODAL)
672                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT);
673                 else
674                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
675
676                 maps_item_list_h segment_list = NULL;
677                 maps_item_list_create(&segment_list);
678
679                 GList *maneuver_data = NULL;
680                 maneuver_data = g_list_first(route_info->maneuvers);
681
682                 while (maneuver_data) {
683                         maps_route_segment_h segment = NULL;
684                         maps_route_segment_create(&segment);
685
686                         maps_route_maneuver_h man = NULL;
687                         maps_route_maneuver_create(&man);
688                         mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *) maneuver_data->data;
689
690                         /* Segment Origin and Destination */
691                         maps_coordinates_h segmentStartPoint;
692                         maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &segmentStartPoint);
693                         maps_route_segment_set_origin(segment, segmentStartPoint);      /* origin */
694                         maps_coordinates_destroy(segmentStartPoint);
695
696                         maps_coordinates_h segmentEndPoint;
697                         maps_coordinates_create(maneuver->end_point.latitude, maneuver->end_point.longitude, &segmentEndPoint);
698
699                         MAPS_LOGD(">>> Segment start : %f, %f <<<", maneuver->start_point.latitude, maneuver->start_point.longitude);
700                         MAPS_LOGD(">>> Segment end : %f, %f <<<", maneuver->end_point.latitude, maneuver->end_point.longitude);
701
702                         maps_route_segment_set_destination(segment, segmentEndPoint);   /* destination */
703                         maps_coordinates_destroy(segmentEndPoint);
704
705                         /* Segment distance */
706                         maps_route_segment_set_distance(segment, maneuver->distance);
707                         maps_route_segment_set_duration(segment, maneuver->time);
708
709                         /* Maneuver distance */
710                         maps_route_maneuver_set_distance_to_next_instruction(man, maneuver->distance);
711                         maps_route_maneuver_set_time_to_next_instruction(man, maneuver->time);
712
713                         maps_route_maneuver_set_turn_type(man, __convert_route_turn_type(maneuver->turn_type));
714
715                         /* maneuver_set_traffic_direction(man, (traffic_direction_e)action_id); */
716
717                         /* Maneuver Instruction */
718                         if (maneuver->instruction)
719                                 maps_route_maneuver_set_instruction_text(man, (char *) maneuver->instruction);
720
721                         /* Maneuver Street Name */
722                         if (maneuver->street_name) {
723                                 MAPS_LOGD("Street Name >>>> %s", maneuver->street_name);
724                                 maps_route_maneuver_set_road_name(man, (char *) maneuver->street_name);
725                         } else {
726                                 MAPS_LOGD("Street Name >>>> NIL");
727                         }
728
729                         /* Maneuver start position */
730                         maps_coordinates_h coord;
731                         maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &coord);
732
733                         maps_route_maneuver_set_position(man, coord);
734                         maps_coordinates_destroy(coord);
735
736                         maps_item_list_h maneuver_list = NULL;
737                         maps_item_list_create(&maneuver_list);
738                         maps_item_list_append(maneuver_list, (gpointer) man, maps_route_maneuver_clone);
739                         maps_route_segment_set_maneuvers(segment, maneuver_list);
740
741                         maps_item_list_destroy(maneuver_list);
742                         maps_route_maneuver_destroy(man);
743
744                         maps_item_list_append(segment_list, (gpointer) segment, maps_route_segment_clone);
745                         maps_route_segment_destroy(segment);
746
747                         /* Fetching the next item from Maneuver/Segment list */
748                         maneuver_data = g_list_next(maneuver_data);
749                 }
750                 maps_route_set_segments(route, segment_list);
751                 maps_item_list_destroy(segment_list);
752
753                 /* Shape points - path */
754                 maps_item_list_h path_list = NULL;
755                 maps_item_list_create(&path_list);
756
757                 GList *shapePoints = NULL;
758                 shapePoints = g_list_first(route_info->shapePoints);
759
760                 while (shapePoints) {
761                         coords_s *data = (coords_s *) shapePoints->data;
762
763                         maps_coordinates_h shapeCoords;
764                         maps_coordinates_create(data->latitude, data->longitude, &shapeCoords);
765
766                         maps_item_list_append(path_list, (gpointer) shapeCoords, maps_coordinates_clone);
767
768                         maps_coordinates_destroy(shapeCoords);
769
770                         shapePoints = g_list_next(shapePoints);
771                 }
772                 maps_route_set_path(route, path_list);
773                 maps_item_list_destroy(path_list);
774
775                 bool b = calldata_route->callback((maps_error_e)__convert_to_maps_error(result), calldata_route->reqID, 0, 1, route, calldata_route->data);
776                 if (!b)
777                         return;
778         } else {
779                 calldata_route->callback((maps_error_e)__convert_to_maps_error(result), calldata_route->reqID, 0, 0, NULL, calldata_route->data);
780         }
781 }
782
783 EXPORT_API int maps_plugin_search_route(const maps_coordinates_h origin, const maps_coordinates_h destination, maps_preference_h preference,    maps_service_search_route_cb callback, void *user_data, int *request_id)
784 {
785         if (!origin || !destination || !callback || !request_id)
786                 return MAPS_ERROR_INVALID_PARAMETER;
787
788         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
789         if (calldata_route == NULL)
790                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
791
792         calldata_route->callback = callback;
793         calldata_route->data = user_data;
794
795         mapquest_route_req_s *route_req = (mapquest_route_req_s *)g_malloc0(sizeof(mapquest_route_req_s));
796         if (route_req == NULL) {
797                 g_free(calldata_route);
798                 calldata_route = NULL;
799                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
800         }
801
802         route_req->maps_key = g_strdup((gchar *) __provider_key);
803
804         double origin_lat, origin_lon;
805         double dest_lat, dest_lon;
806
807         maps_coordinates_get_latitude(origin, &origin_lat);
808         maps_coordinates_get_longitude(origin, &origin_lon);
809
810         maps_coordinates_get_latitude(destination, &dest_lat);
811         maps_coordinates_get_longitude(destination, &dest_lon);
812
813         route_req->from.latitude = origin_lat;
814         route_req->from.longitude = origin_lon;
815
816         route_req->to.latitude = dest_lat;
817         route_req->to.longitude = dest_lon;
818
819         MAPS_LOGD("getting transport mode..");
820         maps_route_transport_mode_e transport_mode;
821         maps_preference_get_route_transport_mode(preference, &transport_mode);
822
823         if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
824                 route_req->type = ROUTE_TYPE_FASTEST;
825         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
826                 route_req->type = ROUTE_TYPE_PEDESTRIAN;
827         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
828                 route_req->type = ROUTE_TYPE_BICYCLE;
829         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
830                 route_req->type = ROUTE_TYPE_MULTIMODAL;
831         else
832                 route_req->type = ROUTE_TYPE_FASTEST;   /* Keeping it as default */
833
834         route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
835
836         /* Unit */
837         maps_distance_unit_e unit;
838         maps_preference_get_distance_unit(preference, &unit);
839
840         switch (unit) {
841         case MAPS_DISTANCE_UNIT_M:
842                 route_req->unit = ROUTE_UNIT_M;
843                 break;
844         case MAPS_DISTANCE_UNIT_KM:
845                 route_req->unit = ROUTE_UNIT_KM;
846                 break;
847         case MAPS_DISTANCE_UNIT_FT:
848                 route_req->unit = ROUTE_UNIT_FT;
849                 break;
850         case MAPS_DISTANCE_UNIT_YD:
851                 route_req->unit = ROUTE_UNIT_YD;
852                 break;
853         }
854
855         route_req->avoids = ROUTE_AVOID_NONE;
856         maps_route_feature_weight_e routeWeight;
857         maps_preference_get_route_feature_weight(preference, &routeWeight);
858
859         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
860                 maps_route_feature_e routeFeature;
861                 maps_preference_get_route_feature(preference, &routeFeature);
862
863                 if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
864                         route_req->avoids = ROUTE_AVOID_TOLL_ROAD;
865                 else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
866                         route_req->avoids = ROUTE_AVOID_LIMITED_ACCESS;
867                 else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
868                         route_req->avoids = ROUTE_AVOID_FERRY;
869                 else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
870                         route_req->avoids = ROUTE_AVOID_UNPAVED;
871                 else
872                         route_req->avoids = ROUTE_AVOID_NONE;
873         }
874
875         route_req->way_points = NULL;
876
877         *request_id = ++__request_id;
878         calldata_route->reqID = __request_id;
879
880         int ret = mapquest_start_route(route_req, __mapquest_route_cb, __request_id, (void *)calldata_route);
881
882         return __convert_to_maps_error(ret);
883 }
884
885 EXPORT_API int maps_plugin_search_route_waypoints(const maps_coordinates_h *waypoint_list, int waypoint_num, maps_preference_h preference, maps_service_search_route_cb callback, void *user_data, int *request_id)
886 {
887         if (!waypoint_list || waypoint_num < 2 || !callback || !request_id)
888                 return MAPS_ERROR_INVALID_PARAMETER;
889
890         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
891         if (calldata_route == NULL)
892                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
893
894         calldata_route->callback = callback;
895         calldata_route->data = user_data;
896
897         mapquest_route_req_s *route_req = (mapquest_route_req_s *)g_malloc0(sizeof(mapquest_route_req_s));
898         if (route_req == NULL) {
899                 g_free(calldata_route);
900                 calldata_route = NULL;
901                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
902         }
903
904         route_req->maps_key = g_strdup((gchar *) __provider_key);
905
906         route_req->from.latitude = 0.0;
907         route_req->from.longitude = 0.0;
908
909         route_req->to.latitude = 0.0;
910         route_req->to.longitude = 0.0;
911
912         MAPS_LOGD("getting transport mode..");
913         maps_route_transport_mode_e transport_mode;
914         maps_preference_get_route_transport_mode(preference, &transport_mode);
915
916         if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
917                 route_req->type = ROUTE_TYPE_FASTEST;
918         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
919                 route_req->type = ROUTE_TYPE_PEDESTRIAN;
920         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
921                 route_req->type = ROUTE_TYPE_BICYCLE;
922         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
923                 route_req->type = ROUTE_TYPE_MULTIMODAL;
924         else
925                 route_req->type = ROUTE_TYPE_FASTEST;   /* Keeping it as default */
926
927         route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
928
929         /* Unit */
930         maps_distance_unit_e unit;
931         maps_preference_get_distance_unit(preference, &unit);
932
933         switch (unit) {
934         case MAPS_DISTANCE_UNIT_M:
935                 route_req->unit = ROUTE_UNIT_M;
936                 break;
937         case MAPS_DISTANCE_UNIT_KM:
938                 route_req->unit = ROUTE_UNIT_KM;
939                 break;
940         case MAPS_DISTANCE_UNIT_FT:
941                 route_req->unit = ROUTE_UNIT_FT;
942                 break;
943         case MAPS_DISTANCE_UNIT_YD:
944                 route_req->unit = ROUTE_UNIT_YD;
945                 break;
946         }
947
948         route_req->avoids = ROUTE_AVOID_NONE;
949         maps_route_feature_weight_e routeWeight;
950         maps_preference_get_route_feature_weight(preference, &routeWeight);
951
952         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
953                 maps_route_feature_e routeFeature;
954                 maps_preference_get_route_feature(preference, &routeFeature);
955
956                 if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
957                         route_req->avoids = ROUTE_AVOID_TOLL_ROAD;
958                 else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
959                         route_req->avoids = ROUTE_AVOID_LIMITED_ACCESS;
960                 else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
961                         route_req->avoids = ROUTE_AVOID_FERRY;
962                 else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
963                         route_req->avoids = ROUTE_AVOID_UNPAVED;
964                 else
965                         route_req->avoids = ROUTE_AVOID_NONE;
966         }
967
968         /* Waypoints */
969         route_req->way_points = NULL;
970         if (waypoint_num != 0) {
971                 int index = 0;
972                 double latitude = 0.0, longitude = 0.0;
973                 for (index = 0; index < waypoint_num; index++) {
974                         if (waypoint_list[index] != NULL) {
975                                 maps_coordinates_get_latitude(waypoint_list[index], &latitude);
976                                 maps_coordinates_get_longitude(waypoint_list[index], &longitude);
977
978                                 coords_s *data = (coords_s *)g_malloc0(sizeof(coords_s));
979                                 if (data) {
980                                         data->latitude = latitude;
981                                         data->longitude = longitude;
982
983                                         if (route_req->way_points == NULL)
984                                                 route_req->way_points = g_list_append(route_req->way_points, (gpointer) data);
985                                         else
986                                                 route_req->way_points = g_list_insert_before(route_req->way_points, NULL, (gpointer) data);
987                                 }
988                         }
989                 }
990         }
991
992         *request_id = ++__request_id;
993         calldata_route->reqID = __request_id;
994
995         int ret = mapquest_start_route(route_req, __mapquest_route_cb, __request_id, (void *)calldata_route);
996
997         return __convert_to_maps_error(ret);
998 }
999
1000 static void __mapquest_place_search_cb(mapquest_error_e result, int request_id, GList *places, void *user_data)
1001 {
1002         MAPS_LOGD("Got places result from ENGINE...");
1003
1004         callback_info_place *calldata_place = (callback_info_place *) user_data;
1005
1006         if (result != MAPQUEST_ERROR_NONE || places == NULL) {
1007                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1008                 calldata_place->callback((maps_error_e) __convert_to_maps_error(result), calldata_place->reqID, 0, 0, NULL, calldata_place->data);
1009         } else {
1010                 guint total_count = 0;
1011                 int index = 0;
1012                 total_count = g_list_length(places);
1013                 if (total_count > 0) {
1014                         maps_place_h place = NULL;
1015                         MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
1016
1017                         GList *temp_place = NULL;
1018                         temp_place = g_list_first(places);
1019
1020                         while (temp_place) {
1021                                 maps_place_create(&place);
1022                                 mapquest_place_resp_s *mapquest_place = (mapquest_place_resp_s *) temp_place->data;
1023                                 maps_place_set_id(place, mapquest_place->place_id);
1024                                 maps_place_set_name(place, mapquest_place->display_name);
1025
1026                                 MAPS_LOGD("Before address..");
1027                                 /* Address */
1028                                 if (mapquest_place->address) {
1029                                         maps_address_h addr = NULL;
1030                                         maps_address_create(&addr);
1031
1032                                         maps_address_set_street(addr, mapquest_place->address->street_add);
1033                                         maps_address_set_building_number(addr, mapquest_place->address->building_number);
1034                                         maps_address_set_city(addr, mapquest_place->address->city);
1035                                         maps_address_set_county(addr, mapquest_place->address->county);
1036                                         maps_address_set_state(addr, mapquest_place->address->state);
1037                                         maps_address_set_country(addr, mapquest_place->address->country);
1038                                         maps_address_set_country_code(addr, mapquest_place->address->country_code);
1039                                         maps_address_set_postal_code(addr, mapquest_place->address->postal_code);
1040                                         maps_address_set_freetext(addr, mapquest_place->display_name);
1041
1042                                         maps_place_set_address(place, addr);
1043                                         maps_address_destroy(addr);
1044                                 } else {
1045                                         maps_place_set_address(place, NULL);
1046                                 }
1047
1048                                 maps_coordinates_h coord;
1049                                 maps_coordinates_create(mapquest_place->coordinates.latitude, mapquest_place->coordinates.longitude, &coord);
1050
1051                                 maps_place_set_location(place, coord);
1052                                 maps_coordinates_destroy(coord);
1053
1054                                 maps_place_category_h place_cat;
1055                                 maps_place_category_create(&place_cat);
1056                                 maps_place_category_set_name(place_cat, mapquest_place->category);
1057
1058                                 maps_item_list_h cat_list;
1059                                 maps_item_list_create(&cat_list);
1060                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1061                                 maps_place_set_categories(place, cat_list);
1062
1063                                 maps_place_category_destroy(place_cat);
1064                                 maps_item_list_destroy(cat_list);
1065
1066                                 maps_place_image_h place_image;
1067                                 maps_place_image_create(&place_image);
1068                                 maps_place_image_set_url(place_image, mapquest_place->icon_url);
1069                                 maps_item_list_h image_list;
1070                                 maps_item_list_create(&image_list);
1071                                 maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone);
1072                                 maps_place_set_images(place, image_list);
1073
1074                                 maps_place_image_destroy(place_image);
1075                                 maps_item_list_destroy(image_list);
1076
1077                                 bool b = calldata_place->callback((maps_error_e)__convert_to_maps_error(result), calldata_place->reqID, index, total_count, place, calldata_place->data);
1078                                 if (!b)
1079                                         return;
1080
1081                                 index++;
1082
1083                                 temp_place = temp_place->next;
1084                         }
1085                 } else {
1086                         calldata_place->callback((maps_error_e)__convert_to_maps_error(result), calldata_place->reqID, index, total_count, NULL, calldata_place->data);
1087                 }
1088         }
1089 }
1090
1091 EXPORT_API int maps_plugin_search_place(const maps_coordinates_h position, int distance, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
1092 {
1093         if (!position || !filter || !callback || !request_id)
1094                 return MAPS_ERROR_INVALID_PARAMETER;
1095         if (distance <= 0)
1096                 return MAPS_ERROR_INVALID_PARAMETER;
1097
1098         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1099         if (calldata_place == NULL)
1100                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1101
1102         calldata_place->callback = callback;
1103         calldata_place->data = user_data;
1104
1105         mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
1106         if (place_req == NULL) {
1107                 g_free(calldata_place);
1108                 calldata_place = NULL;
1109                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1110         }
1111
1112         place_req->maps_key = g_strdup((gchar *) __provider_key);
1113
1114         int max_result;
1115         maps_preference_get_max_results(preference, &max_result);
1116
1117         if (max_result == 0)
1118                 place_req->num_res = DEFAULT_NUM_RESULTS;
1119         else
1120                 place_req->num_res = max_result;
1121
1122         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1123
1124         char *categoryName = NULL;
1125         char *place_name = NULL;
1126
1127         maps_place_category_h category = NULL;
1128         maps_place_filter_get_category(filter, &category);
1129
1130         if (category)
1131                 maps_place_category_get_name(category, &categoryName);
1132
1133         maps_place_filter_get_place_name(filter, &place_name);
1134
1135         char *modified_place_name = NULL;
1136         bool b_isPlaceName_modified = false;
1137         if (place_name)
1138                 b_isPlaceName_modified = __replace_space(place_name, &modified_place_name);
1139
1140         MAPS_LOGD("Modified Place String.. ");
1141         MAPS_LOGD(" >>>> %s", modified_place_name);
1142
1143         if (categoryName && place_name) {
1144                 if (b_isPlaceName_modified)
1145                         place_req->search_string = g_strdup_printf("%s[%s]", modified_place_name, categoryName);
1146                 else
1147                         place_req->search_string = g_strdup_printf("%s[%s]", place_name, categoryName);
1148         } else if (categoryName) {
1149                 place_req->search_string = g_strdup_printf("[%s]", categoryName);
1150         } else if (place_name) {
1151                 if (b_isPlaceName_modified)
1152                         place_req->search_string = g_strdup_printf("%s", modified_place_name);
1153                 else
1154                         place_req->search_string = g_strdup_printf("%s", place_name);
1155         } else {
1156                 g_free(calldata_place);
1157                 calldata_place = NULL;
1158                 g_free(place_req);
1159                 place_req = NULL;
1160                 return MAPS_ERROR_INVALID_PARAMETER;
1161         }
1162
1163         if (modified_place_name) {
1164                 g_free(modified_place_name);
1165                 modified_place_name = NULL;
1166         }
1167
1168         MAPS_LOGD(">>>>>>>> Place search string :: %s <<<<<<<<<", place_req->search_string);
1169
1170         place_req->boundary = NULL;
1171         place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
1172
1173         if (place_req->boundary) {
1174                 place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
1175                 double lat, lon;
1176                 maps_coordinates_get_latitude(position, &lat);
1177                 maps_coordinates_get_longitude(position, &lon);
1178                 place_req->boundary->circle.center.latitude = lat;
1179                 place_req->boundary->circle.center.longitude = lon;
1180                 place_req->boundary->circle.radius = distance;
1181         }
1182
1183         *request_id = ++__request_id;
1184         calldata_place->reqID = __request_id;
1185
1186         int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
1187
1188         return __convert_to_maps_error(ret);
1189 }
1190
1191 EXPORT_API int maps_plugin_search_place_by_area(const maps_area_h boundary, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
1192 {
1193         if (!boundary || !filter || !callback || !request_id)
1194                 return MAPS_ERROR_INVALID_PARAMETER;
1195
1196         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1197         if (calldata_place == NULL)
1198                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1199
1200         calldata_place->callback = callback;
1201         calldata_place->data = user_data;
1202
1203         mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
1204         if (place_req == NULL) {
1205                 g_free(calldata_place);
1206                 calldata_place = NULL;
1207                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1208         }
1209
1210         place_req->maps_key = g_strdup((gchar *) __provider_key);
1211
1212         int max_result;
1213         maps_preference_get_max_results(preference, &max_result);
1214
1215         if (max_result == 0)
1216                 place_req->num_res = DEFAULT_NUM_RESULTS;
1217         else
1218                 place_req->num_res = max_result;
1219
1220         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1221
1222         char *categoryName = NULL;
1223         char *place_name = NULL;
1224
1225         maps_place_category_h category = NULL;
1226         maps_place_filter_get_category(filter, &category);
1227
1228         if (category)
1229                 maps_place_category_get_name(category, &categoryName);
1230
1231         maps_place_filter_get_place_name(filter, &place_name);
1232
1233         char *modified_place_name = NULL;
1234         bool b_isPlaceName_modified = false;
1235         if (place_name)
1236                 b_isPlaceName_modified = __replace_space(place_name, &modified_place_name);
1237
1238         if (categoryName && place_name) {
1239                 if (b_isPlaceName_modified)
1240                         place_req->search_string = g_strdup_printf("%s[%s]", modified_place_name, categoryName);
1241                 else
1242                         place_req->search_string = g_strdup_printf("%s[%s]", place_name, categoryName);
1243         } else if (categoryName) {
1244                 place_req->search_string = g_strdup_printf("[%s]", categoryName);
1245         } else if (place_name) {
1246                 if (b_isPlaceName_modified)
1247                         place_req->search_string = g_strdup_printf("%s", modified_place_name);
1248                 else
1249                         place_req->search_string = g_strdup_printf("%s", place_name);
1250         } else {
1251                 g_free(calldata_place);
1252                 calldata_place = NULL;
1253                 g_free(place_req);
1254                 place_req = NULL;
1255                 return MAPS_ERROR_INVALID_PARAMETER;
1256         }
1257
1258         if (modified_place_name) {
1259                 g_free(modified_place_name);
1260                 modified_place_name = NULL;
1261         }
1262
1263         MAPS_LOGD(">>>>>>>> Place search string :: %s <<<<<<<<<", place_req->search_string);
1264         place_req->boundary = NULL;
1265         maps_area_s *bound = (maps_area_s *) boundary;
1266
1267         if (bound->type != MAPS_AREA_NONE) {
1268                 place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
1269
1270                 if (place_req->boundary != NULL) {
1271                         if (bound->type == MAPS_AREA_CIRCLE) {
1272                                 place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
1273                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1274                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1275                                 place_req->boundary->circle.radius = bound->circle.radius;
1276                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1277                                 place_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
1278                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1279                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1280                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1281                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1282                         }
1283                 }
1284         }
1285
1286         *request_id = ++__request_id;
1287         calldata_place->reqID = __request_id;
1288
1289         int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
1290
1291         return __convert_to_maps_error(ret);
1292 }
1293
1294 EXPORT_API int maps_plugin_search_place_by_address(const char *address, const maps_area_h boundary, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
1295 {
1296         if (!address || !boundary || !filter || !callback || !request_id)
1297                 return MAPS_ERROR_INVALID_PARAMETER;
1298
1299         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1300         if (calldata_place == NULL)
1301                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1302
1303         calldata_place->callback = callback;
1304         calldata_place->data = user_data;
1305
1306         mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
1307         if (place_req == NULL) {
1308                 g_free(calldata_place);
1309                 calldata_place = NULL;
1310                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1311         }
1312
1313         place_req->maps_key = g_strdup((gchar *) __provider_key);
1314
1315         int max_result;
1316         maps_preference_get_max_results(preference, &max_result);
1317
1318         if (max_result == 0)
1319                 place_req->num_res = DEFAULT_NUM_RESULTS;
1320         else
1321                 place_req->num_res = max_result;
1322
1323         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1324
1325         char *categoryName = NULL;
1326
1327         maps_place_category_h category = NULL;
1328         maps_place_filter_get_category(filter, &category);
1329
1330         if (category)
1331                 maps_place_category_get_name(category, &categoryName);
1332
1333         char *modified_address = NULL;
1334         bool b_isAddress_modified = false;
1335         if (address)
1336                 b_isAddress_modified = __replace_space((char *) address, &modified_address);
1337
1338         if (categoryName) {
1339                 if (b_isAddress_modified)
1340                         place_req->search_string = g_strdup_printf("%s[%s]", modified_address, categoryName);
1341                 else
1342                         place_req->search_string = g_strdup_printf("%s[%s]", address, categoryName);
1343         } else {
1344                 if (b_isAddress_modified)
1345                         place_req->search_string = g_strdup_printf("%s", modified_address);
1346                 else
1347                         place_req->search_string = g_strdup_printf("%s", address);
1348         }
1349
1350         if (modified_address) {
1351                 g_free(modified_address);
1352                 modified_address = NULL;
1353         }
1354
1355         place_req->boundary = NULL;
1356         maps_area_s *bound = (maps_area_s *) boundary;
1357
1358         if (bound->type != MAPS_AREA_NONE) {
1359                 place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
1360
1361                 if (place_req->boundary != NULL) {
1362                         if (bound->type == MAPS_AREA_CIRCLE) {
1363                                 place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
1364                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1365                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1366                                 place_req->boundary->circle.radius = bound->circle.radius;
1367                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1368                                 place_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
1369                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1370                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1371                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1372                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1373                         }
1374                 }
1375         }
1376
1377         *request_id = ++__request_id;
1378         calldata_place->reqID = __request_id;
1379
1380         int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
1381
1382         return __convert_to_maps_error(ret);
1383 }
1384
1385 EXPORT_API int maps_plugin_cancel_request(int request_id)
1386 {
1387         MAPS_LOGD("Plugin_Cancel_Request...");
1388         if (request_id < 0)
1389                 return MAPS_ERROR_INVALID_PARAMETER;
1390
1391         int ret = mapquest_cancel_request(request_id);
1392
1393         return __convert_to_maps_error(ret);
1394 }