Added capability to process mapzen route reponse
[platform/core/location/maps-plugin-mapzen.git] / src / mapzen_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 "mapzen_plugin.h"
20 #include "mapzen_plugin_internal.h"
21 #include "mapzen_api.hpp"
22 #include "mapzen_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 /*
47 static maps_route_turn_type_e __convert_route_turn_type(int index)
48 {
49         maps_route_turn_type_e type = MAPS_ROUTE_TURN_TYPE_NONE;
50
51         if (index == 0)
52                 type = MAPS_ROUTE_TURN_TYPE_STRAIGHT;
53         else if (index == 1)
54                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT;
55         else if (index == 2)
56                 type = MAPS_ROUTE_TURN_TYPE_RIGHT;
57         else if (index == 3)
58                 type = MAPS_ROUTE_TURN_TYPE_HARD_RIGHT;
59         else if (index == 5)
60                 type = MAPS_ROUTE_TURN_TYPE_HARD_LEFT;
61         else if (index == 6)
62                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
63         else if (index == 7)
64                 type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
65         else if (index == 8)
66                 type = MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT;
67         else if (index == 9)
68                 type = MAPS_ROUTE_TURN_TYPE_UTURN_LEFT;
69         else if (index == 16)
70                 type = MAPS_ROUTE_TURN_TYPE_RIGHT_FORK;
71         else if (index == 17)
72                 type = MAPS_ROUTE_TURN_TYPE_LEFT_FORK;
73         else if (index == 18)
74                 type = MAPS_ROUTE_TURN_TYPE_STRAIGHT_FORK;
75         else
76                 type = MAPS_ROUTE_TURN_TYPE_NONE;
77
78         return type;
79 }*/
80
81 EXPORT_API int maps_plugin_multi_reverse_geocode(const maps_coordinates_list_h geocode_list,
82         const maps_preference_h preference, maps_service_multi_reverse_geocode_cb callback,
83         void *user_data, int *request_id)
84 {
85         return  MAPS_ERROR_NOT_SUPPORTED ;
86
87 }
88
89 EXPORT_API int maps_plugin_create_map_view(maps_view_h hView, maps_plugin_map_view_ready_cb pCbFunc)
90 {
91         int ret = mapzen_create_map_view(hView, pCbFunc);
92         return convert_mapzen_error_to_maps_error(ret);
93 }
94
95 EXPORT_API int maps_plugin_destroy_map_view(maps_view_h hView)
96 {
97         int ret = mapzen_destroy_map_view(hView);
98         return convert_mapzen_error_to_maps_error(ret);
99 }
100
101 EXPORT_API int maps_plugin_render_map(maps_view_h hView,
102         const maps_coordinates_h coordinates, double zoom_factor, double rotation_angle)
103 {
104         int ret = mapzen_render_map(hView, coordinates, zoom_factor, rotation_angle);
105         return convert_mapzen_error_to_maps_error(ret);
106 }
107
108 EXPORT_API int maps_plugin_move_center(maps_view_h hView, int delta_x, int delta_y)
109 {
110         int ret = mapzen_move_center(hView, delta_x, delta_y);
111         return convert_mapzen_error_to_maps_error(ret);
112 }
113
114 EXPORT_API int maps_plugin_set_scalebar(maps_view_h hView, bool enable)
115 {
116
117         return MAPS_ERROR_NOT_SUPPORTED;
118 }
119
120 EXPORT_API int maps_plugin_get_scalebar(maps_view_h hView, bool *enabled)
121 {
122         return MAPS_ERROR_NOT_SUPPORTED;
123 }
124
125 EXPORT_API int maps_plugin_on_object(maps_view_h hView, const maps_view_object_h object, maps_view_object_operation_e operation)
126 {
127         return MAPS_ERROR_NOT_SUPPORTED;
128 }
129
130 EXPORT_API int maps_plugin_screen_to_geography(maps_view_h hView, int x, int y, maps_coordinates_h *mapsCoord)
131 {
132         int ret = mapzen_screen_to_geography(hView, x, y, mapsCoord);
133         return convert_mapzen_error_to_maps_error(ret);
134 }
135
136 EXPORT_API int maps_plugin_geography_to_screen(maps_view_h hView, const maps_coordinates_h mapsCoord, int *x, int *y)
137 {
138         int ret = mapzen_geography_to_screen(hView, mapsCoord, x, y);
139         return convert_mapzen_error_to_maps_error(ret);
140 }
141
142 EXPORT_API int maps_plugin_get_min_zoom_level(maps_view_h hView, int *min_zoom_level)
143 {
144         int ret = mapzen_get_min_zoom_level(hView, min_zoom_level);
145         return convert_mapzen_error_to_maps_error(ret);
146 }
147
148 EXPORT_API int maps_plugin_get_max_zoom_level(maps_view_h hView, int *max_zoom_level)
149 {
150         int ret = mapzen_get_max_zoom_level(hView, max_zoom_level);
151         return convert_mapzen_error_to_maps_error(ret);
152 }
153
154 EXPORT_API int maps_plugin_get_center(maps_view_h view, maps_coordinates_h *center)
155 {
156         int ret = mapzen_get_center(view, center);
157         return convert_mapzen_error_to_maps_error(ret);
158 }
159
160 EXPORT_API int maps_plugin_capture_snapshot(maps_view_h view, void **data, int *width, int *height, maps_view_colorspace_type_e *cs)
161 {
162         int ret = mapzen_capture_snapshot(view, data, width, height, cs);
163         return convert_mapzen_error_to_maps_error(ret);
164 }
165
166 EXPORT_API int maps_plugin_init_module(maps_plugin_h *plugin, const char* module)
167 {
168         if (!plugin)
169                 return MAPS_ERROR_INVALID_PARAMETER;
170
171         int ret = MAPS_ERROR_NONE;
172         if (!__plugin)
173                 ret = mapzen_init();
174
175         if (ret == MAPS_ERROR_NONE) {
176                 __maps_service_instance_count++;
177                 __plugin = plugin;
178         }
179
180         return convert_mapzen_error_to_maps_error(ret);
181 }
182
183 EXPORT_API int maps_plugin_init(maps_plugin_h *plugin)
184 {
185         return maps_plugin_init_module(plugin, NULL);
186 }
187
188 EXPORT_API int maps_plugin_shutdown(maps_plugin_h plugin)
189 {
190         MAPS_LOGD("PLUGIN SHUTDOWN");
191         if (!plugin)
192                 return MAPS_ERROR_INVALID_PARAMETER;
193
194         __maps_service_instance_count--;
195
196         int ret = MAPS_ERROR_NONE;
197         if (__maps_service_instance_count == 0) {
198                 ret = mapzen_shutdown();
199                 __plugin = NULL;
200         }
201
202         return convert_mapzen_error_to_maps_error(ret);
203 }
204
205 EXPORT_API int maps_plugin_is_service_supported(maps_service_e service, bool *supported)
206 {
207
208         if (!supported)
209                 return MAPS_ERROR_INVALID_PARAMETER;
210
211         switch (service) {
212         case MAPS_SERVICE_GEOCODE:
213         case MAPS_SERVICE_GEOCODE_INSIDE_AREA:
214         case MAPS_SERVICE_GEOCODE_BY_STRUCTURED_ADDRESS:
215         case MAPS_SERVICE_REVERSE_GEOCODE:
216         case MAPS_SERVICE_SEARCH_PLACE:
217         case MAPS_SERVICE_SEARCH_PLACE_LIST:
218         case MAPS_SERVICE_SEARCH_PLACE_BY_AREA:
219         case MAPS_SERVICE_SEARCH_PLACE_BY_ADDRESS:
220         case MAPS_SERVICE_SEARCH_GET_PLACE_DETAILS:
221         case MAPS_SERVICE_SEARCH_ROUTE:
222         case MAPS_SERVICE_SEARCH_ROUTE_WAYPOINTS:
223         case MAPS_SERVICE_CANCEL_REQUEST:
224         case MAPS_SERVICE_VIEW:
225                 *supported = true;
226                 return MAPS_ERROR_NONE;
227         default:
228                 *supported = false;
229                 return MAPS_ERROR_NOT_SUPPORTED;
230         }
231
232
233 }
234
235 EXPORT_API int maps_plugin_is_data_supported(maps_service_data_e data, bool *supported)
236 {
237         if (!supported)
238                 return MAPS_ERROR_INVALID_PARAMETER;
239
240         switch (data) {
241         case MAPS_PLACE_ADDRESS:
242         case MAPS_PLACE_CATEGORIES:
243         case MAPS_PLACE_IMAGE:
244                 /* unsupported */
245                 /* case MAPS_PLACE_RATING: */
246                 /* case MAPS_PLACE_ATTRIBUTES: */
247                 /* case MAPS_PLACE_CONTACTS: */
248                 /* case MAPS_PLACE_EDITORIALS: */
249                 /* case MAPS_PLACE_REVIEWS: */
250                 /* case MAPS_PLACE_SUPPLIER: */
251                 /* case MAPS_PLACE_RELATED: */
252
253         case MAPS_ROUTE_PATH:
254         case MAPS_ROUTE_SEGMENTS_PATH:
255         case MAPS_ROUTE_SEGMENTS_MANEUVERS:
256                 *supported = true;
257                 return MAPS_ERROR_NONE;
258         default:
259                 *supported = false;
260                 return MAPS_ERROR_NOT_SUPPORTED;
261         }
262 }
263
264 EXPORT_API int maps_plugin_get_info(maps_plugin_info_h *info)
265 {
266         if (!info)
267                 return MAPS_ERROR_INVALID_PARAMETER;
268
269         maps_plugin_info_create(info);
270         maps_plugin_info_set_provider_name(*info, "MAPZEN");
271
272         return MAPS_ERROR_NONE;
273 }
274
275 EXPORT_API int maps_plugin_set_provider_key(const char *provider_key)
276 {
277         if (!provider_key)
278                 return MAPS_ERROR_INVALID_PARAMETER;
279
280         g_snprintf(__provider_key, _PROVIDER_KEY_MAX_SIZE, "%s", provider_key);
281
282         return MAPS_ERROR_NONE;
283 }
284
285 EXPORT_API int maps_plugin_get_provider_key(char **provider_key)
286 {
287         if (!provider_key)
288                 return MAPS_ERROR_INVALID_PARAMETER;
289
290         *provider_key = g_strndup(__provider_key, _PROVIDER_KEY_MAX_SIZE);
291
292         return MAPS_ERROR_NONE;
293 }
294
295 EXPORT_API int maps_plugin_set_preference(maps_item_hashtable_h preference)
296 {
297         if (!preference)
298                 return MAPS_ERROR_INVALID_PARAMETER;
299
300         maps_item_hashtable_clone(preference, &preference_plugin);
301         return MAPS_ERROR_NONE;
302 }
303
304 EXPORT_API int maps_plugin_get_preference(maps_item_hashtable_h *preference)
305 {
306         if (!preference)
307                 return MAPS_ERROR_INVALID_PARAMETER;
308
309         maps_item_hashtable_clone(preference_plugin, preference);
310         return MAPS_ERROR_NONE;
311 }
312
313 static void __mapzen_geocode_cb(mapzen_error_e result, int request_id, GList *co_ordinates, void *user_data)
314 {
315         MAPS_LOGD("Got GEOCODE callback from ENGINE");
316
317         callback_info_geocode *calldata_geocode = (callback_info_geocode *) user_data;
318
319         if ((result != MAPZEN_ERROR_NONE) || (co_ordinates == NULL)) {
320                 MAPS_LOGD(">>>>> Invalid GEOCODE result <<<<<");
321                 calldata_geocode->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_geocode->reqID, 0, 0, NULL, calldata_geocode->data);
322         } else {
323                 int total_count = (int) g_list_length(co_ordinates);
324                 int index = 0;
325
326                 GList *coords = NULL;
327                 coords = g_list_first(co_ordinates);
328
329                 while (coords) {
330                         MAPS_LOGD("coordinate %d", index);
331                         coords_s *data = (coords_s *) coords->data;
332
333                         if (data != NULL) {
334                                 maps_coordinates_h resultCoords;
335                                 maps_coordinates_create(data->latitude, data->longitude, &resultCoords);
336                                 bool b = calldata_geocode->callback(MAPS_ERROR_NONE, calldata_geocode->reqID, index, total_count, resultCoords, calldata_geocode->data);
337                                 if (!b)
338                                         return;
339                         }
340                         index++;
341                         coords = coords->next;
342                 }
343         }
344 }
345
346 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)
347 {
348         if (!address || !callback || !request_id)
349                 return MAPS_ERROR_INVALID_PARAMETER;
350
351         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
352         if (calldata_geocode == NULL)
353                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
354
355         calldata_geocode->callback = callback;
356         calldata_geocode->data = user_data;
357
358         mapzen_geocode_req_s *geocode_req = (mapzen_geocode_req_s *)g_malloc0(sizeof(mapzen_geocode_req_s));
359         if (geocode_req == NULL) {
360                 g_free(calldata_geocode);
361                 calldata_geocode = NULL;
362                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
363         }
364
365         geocode_req->address = g_strdup((gchar *) address);
366         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
367         geocode_req->boundary = NULL;
368
369         int max_result = 0;
370         maps_preference_get_max_results(preference, &max_result);
371
372         if (max_result <= 0)
373                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
374         else
375                 geocode_req->num_res = max_result;
376
377         *request_id = ++__request_id;
378         calldata_geocode->reqID = __request_id;
379
380         int ret = mapzen_geocode(geocode_req, __mapzen_geocode_cb, __request_id, (void *) calldata_geocode);
381
382         return convert_mapzen_error_to_maps_error(ret);
383 }
384
385 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)
386 {
387         if (!bounds || !address || !callback || !request_id)
388                 return MAPS_ERROR_INVALID_PARAMETER;
389
390         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
391         if (calldata_geocode == NULL)
392                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
393
394         calldata_geocode->callback = callback;
395         calldata_geocode->data = user_data;
396
397         mapzen_geocode_req_s *geocode_req = (mapzen_geocode_req_s *)g_malloc0(sizeof(mapzen_geocode_req_s));
398         if (geocode_req == NULL) {
399                 free(calldata_geocode);
400                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
401         }
402
403         geocode_req->address = g_strdup((gchar *) address);
404         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
405
406         int max_result = 0;
407         maps_preference_get_max_results(preference, &max_result);
408
409         if (max_result <= 0)
410                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
411         else
412                 geocode_req->num_res = max_result;
413
414         geocode_req->boundary = NULL;
415         geocode_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
416
417         maps_area_s *area = (maps_area_s *) bounds;
418
419         if (area && geocode_req->boundary) {
420                 if (area->type == MAPS_AREA_RECTANGLE) {
421                         geocode_req->boundary->type = MAPZEN_BOUNDARY_RECT;
422                         geocode_req->boundary->rect.top_left.latitude = area->rect.top_left.latitude;
423                         geocode_req->boundary->rect.top_left.longitude = area->rect.top_left.longitude;
424                         geocode_req->boundary->rect.bottom_right.latitude = area->rect.bottom_right.latitude;
425                         geocode_req->boundary->rect.bottom_right.longitude = area->rect.bottom_right.longitude;
426                 } else if (area->type == MAPS_AREA_CIRCLE) {
427                         geocode_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
428                         geocode_req->boundary->circle.center.latitude = area->circle.center.latitude;
429                         geocode_req->boundary->circle.center.longitude = area->circle.center.longitude;
430                         geocode_req->boundary->circle.radius = area->circle.radius;
431                 }
432         }
433
434         *request_id = ++__request_id;
435         calldata_geocode->reqID = __request_id;
436
437         int ret = mapzen_geocode(geocode_req, __mapzen_geocode_cb, __request_id, (void *) calldata_geocode);
438
439         return convert_mapzen_error_to_maps_error(ret);
440 }
441
442 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)
443 {
444         if (!address || !callback || !request_id)
445                 return MAPS_ERROR_INVALID_PARAMETER;
446
447         callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
448         if (calldata_geocode == NULL)
449                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
450
451         calldata_geocode->callback = callback;
452         calldata_geocode->data = user_data;
453
454         mapzen_geocode_req_s *geocode_req = (mapzen_geocode_req_s *)g_malloc0(sizeof(mapzen_geocode_req_s));
455         if (geocode_req == NULL) {
456                 free(calldata_geocode);
457                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
458         }
459
460         char resultAddressQuery[1024] = "";
461
462         char *house_number = NULL;
463         maps_address_get_building_number(address, &house_number);
464
465         char *street = NULL;
466         maps_address_get_street(address, &street);
467         if (street != NULL) {
468                 if (house_number != NULL) {
469                         STRCAT(resultAddressQuery, house_number);
470                         STRCAT(resultAddressQuery, " ");
471                 }
472                 STRCAT(resultAddressQuery, street);
473         }
474
475         char *city = NULL;
476         maps_address_get_city(address, &city);
477         if ((strlen(resultAddressQuery) > 0) && (city != NULL)) {
478                 STRCAT(resultAddressQuery, ", ");
479                 STRCAT(resultAddressQuery, city);
480         } else if (city != NULL) {
481                 STRCAT(resultAddressQuery, city);
482         }
483
484         char *county = NULL;
485         maps_address_get_county(address, &county);
486         if ((strlen(resultAddressQuery) > 0) && (county != NULL)) {
487                 STRCAT(resultAddressQuery, ", ");
488                 STRCAT(resultAddressQuery, county);
489         }  else if (county != NULL) {
490                 STRCAT(resultAddressQuery, county);
491         }
492
493         char *state = NULL;
494         maps_address_get_state(address, &state);
495         if ((strlen(resultAddressQuery) > 0) && (state != NULL)) {
496                 STRCAT(resultAddressQuery, ", ");
497                 STRCAT(resultAddressQuery, state);
498         } else if (state != NULL) {
499                 STRCAT(resultAddressQuery, state);
500         }
501
502         char *postal_code = NULL;
503         maps_address_get_postal_code(address, &postal_code);
504         if ((strlen(resultAddressQuery) > 0) && (postal_code != NULL)) {
505                 STRCAT(resultAddressQuery, ", ");
506                 STRCAT(resultAddressQuery, postal_code);
507         } else if (postal_code != NULL) {
508                 STRCAT(resultAddressQuery, postal_code);
509         }
510
511         char *country = NULL;
512         maps_address_get_country(address, &country);
513         if ((strlen(resultAddressQuery) > 0) && (country != NULL)) {
514                 STRCAT(resultAddressQuery, ", ");
515                 STRCAT(resultAddressQuery, country);
516         } else if (country != NULL) {
517                 STRCAT(resultAddressQuery, country);
518         }
519
520         if (country == NULL) {
521                 char *country_code = NULL;
522                 maps_address_get_country_code(address, &country_code);
523                 if ((strlen(resultAddressQuery) > 0) && (country_code != NULL)) {
524                         STRCAT(resultAddressQuery, ", ");
525                         STRCAT(resultAddressQuery, country_code);
526                 } else if (country_code != NULL) {
527                         STRCAT(resultAddressQuery, country_code);
528                 }
529         }
530
531         geocode_req->address = g_strdup((gchar *) resultAddressQuery);
532         geocode_req->maps_key = g_strdup((gchar *) __provider_key);
533         geocode_req->boundary = NULL;
534
535         int max_result = 0;
536         maps_preference_get_max_results(preference, &max_result);
537
538         if (max_result <= 0)
539                 geocode_req->num_res = DEFAULT_NUM_RESULTS;
540         else
541                 geocode_req->num_res = max_result;
542
543         *request_id = ++__request_id;
544         calldata_geocode->reqID = __request_id;
545
546         int ret = mapzen_geocode(geocode_req, __mapzen_geocode_cb, __request_id, (void *) calldata_geocode);
547
548         return convert_mapzen_error_to_maps_error(ret);
549 }
550
551 static void __mapzen_reverse_geocode_cb(mapzen_error_e result, int request_id, mapzen_address_resp_s *address, void *user_data)
552 {
553         MAPS_LOGD("Got REV GEOCODE callback from ENGINE");
554         callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *) user_data;
555         if (result != MAPZEN_ERROR_NONE || address == NULL) {
556                 calldata_reverse_geocode->callback((maps_error_e) convert_mapzen_error_to_maps_error(result), calldata_reverse_geocode->reqID, 0, 0, NULL, calldata_reverse_geocode->data);
557         } else {
558                 int total_count = 1;
559                 int index = 0;
560
561                 maps_address_h addr = NULL;
562                 maps_address_create(&addr);
563
564                 /*TODO: housenumber?? */
565                 maps_address_set_street(addr, address->street);
566                 maps_address_set_city(addr, address->localadmin);
567                 maps_address_set_county(addr, address->county);
568                 maps_address_set_state(addr, address->region);
569                 maps_address_set_country(addr, address->country);
570                 maps_address_set_country_code(addr, address->country_a);
571                 maps_address_set_postal_code(addr, address->postalcode);
572
573                 calldata_reverse_geocode->callback(MAPS_ERROR_NONE, calldata_reverse_geocode->reqID, index, total_count, addr, calldata_reverse_geocode->data);
574         }
575 }
576
577 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)
578 {
579         if (!callback || !request_id)
580                 return MAPS_ERROR_INVALID_PARAMETER;
581
582         if (latitude > LATITUDE_RANGE || latitude < -LATITUDE_RANGE)
583                 return MAPS_ERROR_INVALID_PARAMETER;
584
585         if (longitude > LONGITUDE_RANGE || longitude < -LONGITUDE_RANGE)
586                 return MAPS_ERROR_INVALID_PARAMETER;
587
588         callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *)g_malloc0(sizeof(callback_info_reverse_geocode));
589         if (calldata_reverse_geocode == NULL)
590                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
591
592         calldata_reverse_geocode->callback = callback;
593         calldata_reverse_geocode->data = user_data;
594
595         mapzen_revgeocode_req_s *reverse_geocode_req = (mapzen_revgeocode_req_s *)g_malloc0(sizeof(mapzen_revgeocode_req_s));
596         if (reverse_geocode_req == NULL) {
597                 g_free(calldata_reverse_geocode);
598                 calldata_reverse_geocode = NULL;
599                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
600         }
601
602         reverse_geocode_req->maps_key = g_strdup((gchar *) __provider_key);
603         reverse_geocode_req->coordinates.latitude = latitude;
604         reverse_geocode_req->coordinates.longitude = longitude;
605
606         *request_id = ++__request_id;
607         calldata_reverse_geocode->reqID = __request_id;
608
609         int ret = mapzen_reverse_geocode(reverse_geocode_req, __mapzen_reverse_geocode_cb, __request_id, (void *) calldata_reverse_geocode);
610
611         return convert_mapzen_error_to_maps_error(ret);
612 }
613
614 static void __mapzen_route_cb(mapzen_error_e result, int request_id, mapzen_route_resp_s *route_info, void *user_data)
615 {
616         MAPS_LOGD(">>>>> START __mapzen_route_cb");
617
618         MAPS_LOGD(">>>>> PRE callback_info_route cast");
619         callback_info_route *calldata_route = (callback_info_route *) user_data;
620         MAPS_LOGD(">>>>> POST callback_info_route cast");
621
622         maps_error_e error;
623         if (route_info) {
624                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS route_info");
625                 maps_route_h tizen_route;
626                 int route_create_resp = maps_route_create(&tizen_route);
627                 if (route_create_resp != MAPS_ERROR_NONE)
628                         MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR maps_route_create");
629                 else
630                         MAPS_LOGD(">>>>> __mapzen_route_cb: GOOD maps_route_create");
631                 if (!tizen_route)
632                         MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR tizen_route handle is null START");
633
634                 /* Set trip origin */
635                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign trip origin");
636                 maps_coordinates_h origin;
637                 maps_coordinates_create(route_info->origin.latitude, route_info->origin.longitude, &origin);
638                 error = maps_route_set_origin(tizen_route, origin);
639                 if (error != MAPS_ERROR_NONE)
640                         MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR trip maps_route_set_origin");
641                 maps_coordinates_destroy(origin);
642
643                 /* Set trip destination */
644                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign trip destination");
645                 maps_coordinates_h destination;
646                 maps_coordinates_create(route_info->destination.latitude, route_info->destination.longitude, &destination);
647                 error = maps_route_set_destination(tizen_route, destination);
648                 if (error != MAPS_ERROR_NONE)
649                         MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR trip maps_route_set_destination");
650                 maps_coordinates_destroy(destination);
651
652                 /* Create trip top left point for bounding box */
653                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS trip top_left");
654                 maps_coordinates_h top_left;
655                 maps_coordinates_create(route_info->bounding_box.top_left.latitude, route_info->bounding_box.top_left.longitude, &top_left);
656
657                 /* Create trip bottom right point for bounding box */
658                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS trip bottom_right");
659                 maps_coordinates_h bottom_right;
660                 maps_coordinates_create(route_info->bounding_box.bottom_right.latitude, route_info->bounding_box.bottom_right.longitude, &bottom_right);
661
662                 /* Set trip bounding box */
663                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS trip maps_area_create_rectangle");
664                 maps_area_h bounds = NULL;
665                 maps_area_create_rectangle(top_left, bottom_right, &bounds);
666                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS trip maps_route_set_bounding_box");
667                 maps_route_set_bounding_box(tizen_route, bounds);
668                 maps_area_destroy(bounds);
669
670                 /* Clean up trip top left and bottom right points */
671                 maps_coordinates_destroy(top_left);
672                 maps_coordinates_destroy(bottom_right);
673
674                 /* Set transport mode */
675                 switch (route_info->type) {
676                 case COSTING_BICYCLE:
677                         maps_route_set_transport_mode(tizen_route, MAPS_ROUTE_TRANSPORT_MODE_BICYCLE);
678                         break;
679                 case COSTING_MULTIMODAL:
680                         maps_route_set_transport_mode(tizen_route, MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT);
681                         break;
682                 case COSTING_PEDESTRIAN:
683                         maps_route_set_transport_mode(tizen_route, MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN);
684                         break;
685                 case COSTING_AUTO:
686                 case COSTING_AUTO_SHORTER:
687                 default:
688                         maps_route_set_transport_mode(tizen_route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
689                         break;
690                 }
691
692                 /* Set total distance */
693                 maps_route_set_total_distance(tizen_route, route_info->distance);
694
695                 /* Set total duration */
696                 maps_route_set_total_duration(tizen_route, (long) route_info->time);
697
698                 /* Determine distance units */
699                 maps_distance_unit_e unit = MAPS_DISTANCE_UNIT_KM;
700                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS distance_unit");
701                 switch (route_info->distance_unit) {
702                 default:
703                         unit = MAPS_DISTANCE_UNIT_KM;
704                         break;
705                 }
706
707                 /* Set distance units */
708                 maps_route_set_distance_unit(tizen_route, unit);
709
710                 /* Setup for segment list */
711                 GList *segment_data = NULL;
712                 segment_data = g_list_first(route_info->segments);
713                 maps_item_list_h tizen_segment_list = NULL;
714                 maps_item_list_create(&tizen_segment_list);
715
716                 /*********************************************************************/
717                 /* Loop over segments */
718                 MAPS_LOGD(">>>>> PROCESS __mapzen_route_cb: Loop over segments");
719                 while (segment_data) {
720
721                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS create segment");
722                         maps_route_segment_h tizen_segment = NULL;
723                         maps_route_segment_create(&tizen_segment);
724                         mapzen_route_segment *segment = (mapzen_route_segment *) segment_data->data;
725
726                         /* Set segment origin */
727                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign segment origin");
728                         maps_coordinates_h origin;
729                         maps_coordinates_create(segment->origin.latitude, segment->origin.longitude, &origin);
730                         error = maps_route_segment_set_origin(tizen_segment, origin);
731                         if (error != MAPS_ERROR_NONE)
732                                 MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR segment maps_route_set_origin");
733                         maps_coordinates_destroy(origin);
734
735                         /* Set segment destination */
736                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign segment destination");
737                         maps_coordinates_h destination;
738                         maps_coordinates_create(segment->destination.latitude, segment->destination.longitude, &destination);
739                         error = maps_route_segment_set_destination(tizen_segment, destination);
740                         if (error != MAPS_ERROR_NONE)
741                                 MAPS_LOGD(">>>>> __mapzen_route_cb: ERROR segment maps_route_set_destination");
742                         maps_coordinates_destroy(destination);
743
744                         /* Create segment top left point for bounding box */
745                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS segment top_left");
746                         maps_coordinates_h top_left;
747                         maps_coordinates_create(segment->bounding_box.top_left.latitude, segment->bounding_box.top_left.longitude, &top_left);
748
749                         /* Create segment bottom right point for bounding box */
750                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS segment bottom_right");
751                         maps_coordinates_h bottom_right;
752                         maps_coordinates_create(segment->bounding_box.bottom_right.latitude, segment->bounding_box.bottom_right.longitude, &bottom_right);
753
754                         /* Set segment bounding box */
755                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS segment maps_area_create_rectangle");
756                         maps_area_h bounds = NULL;
757                         maps_area_create_rectangle(top_left, bottom_right, &bounds);
758                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS segment maps_route_set_bounding_box");
759                         maps_route_segment_set_bounding_box(tizen_segment, bounds);
760                         maps_area_destroy(bounds);
761
762                         /* Clean up segment top left and bottom right points */
763                         maps_coordinates_destroy(top_left);
764                         maps_coordinates_destroy(bottom_right);
765
766                         /* Set segment distance and time */
767                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign segment distance and time");
768                         maps_route_segment_set_distance(tizen_segment, segment->distance);
769                         maps_route_segment_set_duration(tizen_segment, segment->time);
770
771                         /* Set segment path */
772                         /* TODO */
773
774                         /* Set up for maneuver list */
775                         GList *maneuver_data = NULL;
776                         maneuver_data = g_list_first(segment->maneuvers);
777                         maps_item_list_h tizen_maneuver_list = NULL;
778                         maps_item_list_create(&tizen_maneuver_list);
779
780                         /*********************************************************************/
781                         /* Loop over maneuvers */
782                         MAPS_LOGD(">>>>> PROCESS __mapzen_route_cb: Loop over maneuvers");
783                         while (maneuver_data) {
784
785                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS create maneuver");
786                                 maps_route_maneuver_h tizen_maneuver = NULL;
787                                 maps_route_maneuver_create(&tizen_maneuver);
788                                 mapzen_route_maneuver *maneuver = (mapzen_route_maneuver *) maneuver_data->data;
789
790                                 /* Set maneuver direction */
791                                 /* TODO just set to none */
792
793                                 /* Set turn type from maneuver type */
794                                 /* TODO transform */
795                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign turn type");
796                                 /* maps_route_maneuver_set_turn_type(tizen_maneuver, __convert_route_turn_type(maneuver->turn_type)); */
797
798                                 /* Set maneuver position */
799                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign maneuver position");
800                                 maps_coordinates_h coord;
801                                 maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &coord);
802                                 maps_route_maneuver_set_position(tizen_maneuver, coord);
803                                 maps_coordinates_destroy(coord);
804
805                                 /* Set maneuver instruction */
806                                 if (maneuver->instruction) {
807                                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign instruction: %s", maneuver->instruction);
808                                         maps_route_maneuver_set_instruction_text(tizen_maneuver, (char *) maneuver->instruction);
809                                 }
810
811                                 /* Set maneuver street name */
812                                 if (maneuver->street_name) {
813                                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign street names: %s", maneuver->street_name);
814                                         maps_route_maneuver_set_road_name(tizen_maneuver, (char *) maneuver->street_name);
815                                 } else {
816                                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign street names: NULL");
817                                 }
818
819                                 /* Set maneuver locale */
820                                 /* TODO */
821
822                                 /* Set maneuver distance and time */
823                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS assign maneuver distance and time");
824                                 maps_route_maneuver_set_distance_to_next_instruction(tizen_maneuver, maneuver->distance);
825                                 maps_route_maneuver_set_time_to_next_instruction(tizen_maneuver, maneuver->time);
826
827                                 /* Append to maneuver list */
828                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS append to maneuver list");
829                                 maps_item_list_append(tizen_maneuver_list, (gpointer) tizen_maneuver, maps_route_maneuver_clone);
830                                 maps_route_maneuver_destroy(tizen_maneuver);
831
832                                 /* Fetching the next item from Maneuver list */
833                                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS Fetching the next item from Maneuver list");
834                                 maneuver_data = g_list_next(maneuver_data);
835                         } /* Loop over maneuvers */
836                         /*********************************************************************/
837
838                         /* Set maneuver list */
839                         maps_route_segment_set_maneuvers(tizen_segment, tizen_maneuver_list);
840                         maps_item_list_destroy(tizen_maneuver_list);
841
842                         /* Append to segment list */
843                         maps_item_list_append(tizen_segment_list, (gpointer) tizen_segment, maps_route_segment_clone);
844                         maps_route_segment_destroy(tizen_segment);
845
846                         /* Fetching the next item from Segment list */
847                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS Fetching the next item from Segment list");
848                         segment_data = g_list_next(segment_data);
849
850                 } /* Loop over segments */
851                 /*********************************************************************/
852
853                 /* Set segment list */
854                 maps_route_set_segments(tizen_route, tizen_segment_list);
855                 maps_item_list_destroy(tizen_segment_list);
856
857                 /* Set up for trip shape points/path */
858                 maps_item_list_h tizen_route_path_list = NULL;
859                 maps_item_list_create(&tizen_route_path_list);
860                 GList *shapePoints = NULL;
861                 shapePoints = g_list_first(route_info->shapePoints);
862
863                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS trip shapePoints");
864                 while (shapePoints) {
865                         coords_s *data = (coords_s *) shapePoints->data;
866
867                         maps_coordinates_h shapeCoords;
868                         maps_coordinates_create(data->latitude, data->longitude, &shapeCoords);
869                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS data->latitude: %f", data->latitude);
870                         MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS data->longitude: %f", data->longitude);
871
872                         maps_item_list_append(tizen_route_path_list, (gpointer) shapeCoords, maps_coordinates_clone);
873
874                         maps_coordinates_destroy(shapeCoords);
875
876                         shapePoints = g_list_next(shapePoints);
877                 }
878
879                 /* Set trip path */
880                 maps_route_set_path(tizen_route, tizen_route_path_list);
881                 maps_item_list_destroy(tizen_route_path_list);
882                 MAPS_LOGD(">>>>> __mapzen_route_cb: PROCESS shapePoints DONE");
883
884                 MAPS_LOGD(">>>>> PROCESS __mapzen_route_cb: result=%d", result);
885                 MAPS_LOGD(">>>>> PROCESS __mapzen_route_cb: convert_mapzen_error_to_maps_error(result)=%d", convert_mapzen_error_to_maps_error(result));
886                 MAPS_LOGD(">>>>> PRE calldata_route->callback");
887                 MAPS_LOGD(">>>>> PRE calldata_route->callback address: %p", calldata_route->callback);
888                 bool b = calldata_route->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_route->reqID, 0, 1, tizen_route, calldata_route->data);
889                 MAPS_LOGD(">>>>> POST calldata_route->callback");
890                 if (!b)
891                         return;
892         } else {
893                 MAPS_LOGD(">>>>> PRE calldata_route->callback INVALID route_info");
894                 calldata_route->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_route->reqID, 0, 0, NULL, calldata_route->data);
895                 MAPS_LOGD(">>>>> POST calldata_route->callback INVALID route_info");
896         }
897
898         MAPS_LOGD(">>>>> END __mapzen_route_cb");
899 }
900
901 EXPORT_API int maps_plugin_search_route(const maps_coordinates_h origin,
902                 const maps_coordinates_h destination, maps_preference_h preference,
903                 maps_service_search_route_cb callback, void *user_data, int *request_id) {
904         MAPS_LOGD(">>>>> START maps_plugin_search_route");
905         MAPS_LOGD(">>>>> maps_plugin_search_route PROCESS: callback address=%p", callback);
906         MAPS_LOGD(">>>>> maps_plugin_search_route PROCESS: request_id=%d", *request_id);
907
908         if (!origin || !destination || !callback || !request_id)
909                 return MAPS_ERROR_INVALID_PARAMETER;
910
911         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
912         if (calldata_route == NULL)
913                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
914
915         calldata_route->callback = callback;
916         calldata_route->data = user_data;
917
918         mapzen_route_req_s *route_req = (mapzen_route_req_s *)g_malloc0(sizeof(mapzen_route_req_s));
919         if (route_req == NULL) {
920                 g_free(calldata_route);
921                 calldata_route = NULL;
922                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
923         }
924
925         route_req->maps_key = g_strdup((gchar *) __provider_key);
926
927         double origin_lat, origin_lon;
928         double dest_lat, dest_lon;
929
930         maps_coordinates_get_latitude(origin, &origin_lat);
931         maps_coordinates_get_longitude(origin, &origin_lon);
932
933         maps_coordinates_get_latitude(destination, &dest_lat);
934         maps_coordinates_get_longitude(destination, &dest_lon);
935
936         route_req->from.latitude = origin_lat;
937         route_req->from.longitude = origin_lon;
938
939         route_req->to.latitude = dest_lat;
940         route_req->to.longitude = dest_lon;
941
942         MAPS_LOGD("getting transport mode..");
943         maps_route_transport_mode_e transport_mode;
944         maps_preference_get_route_transport_mode(preference, &transport_mode);
945
946         switch (transport_mode) {
947         case MAPS_ROUTE_TRANSPORT_MODE_CAR:
948                 route_req->type = COSTING_AUTO;
949                 break;
950         case MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN:
951                 route_req->type = COSTING_PEDESTRIAN;
952                 break;
953         case MAPS_ROUTE_TRANSPORT_MODE_BICYCLE:
954                 route_req->type = COSTING_BICYCLE;
955                 break;
956         case MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT:
957                 route_req->type = COSTING_MULTIMODAL;
958                 break;
959         default:
960                 return MAPS_ERROR_INVALID_PARAMETER;
961                 break;
962         }
963
964         /* Unit */
965         maps_distance_unit_e unit;
966         maps_preference_get_distance_unit(preference, &unit);
967
968         switch (unit) {
969         case MAPS_DISTANCE_UNIT_KM:
970                 route_req->unit = UNIT_KM;
971                 break;
972         default:
973                 return MAPS_ERROR_INVALID_PARAMETER;
974         }
975
976         route_req->avoids = PENALTY_NONE;
977         maps_route_feature_weight_e routeWeight;
978         maps_preference_get_route_feature_weight(preference, &routeWeight);
979
980         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
981                 maps_route_feature_e routeFeature;
982                 maps_preference_get_route_feature(preference, &routeFeature);
983
984                 switch (routeFeature) {
985                 case MAPS_ROUTE_FEATURE_TOLL:
986                         route_req->avoids = PENALTY_TOLL_ROADS;
987                         break;
988                 case MAPS_ROUTE_FEATURE_MOTORWAY:
989                         route_req->avoids = PENALTY_LIMITED_ACCESS;
990                         break;
991                 case MAPS_ROUTE_FEATURE_BOATFERRY:
992                 case MAPS_ROUTE_FEATURE_RAILFERRY:
993                         route_req->avoids = PENALTY_USE_FERRY;
994                         break;
995                 case MAPS_ROUTE_FEATURE_DIRTROAD:
996                         route_req->avoids = PENALTY_USE_UNPAVED;
997                         break;
998                 default:
999                         return MAPS_ERROR_INVALID_PARAMETER;
1000                         break;
1001                 }
1002         }
1003
1004         route_req->way_points = NULL;
1005
1006         *request_id = ++__request_id;
1007         calldata_route->reqID = __request_id;
1008         MAPS_LOGD(">>>>> maps_plugin_search_route PROCESS: calldata_route->reqID=%d", calldata_route->reqID);
1009
1010         MAPS_LOGD(">>>>> PRE mapzen_start_route");
1011         int ret = mapzen_start_route(route_req, __mapzen_route_cb, __request_id, (void *)calldata_route);
1012         MAPS_LOGD(">>>>> POST mapzen_start_route");
1013
1014         MAPS_LOGD(">>>>> END maps_plugin_search_route");
1015         return convert_mapzen_error_to_maps_error(ret);
1016 }
1017
1018 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)
1019 {
1020         if (!waypoint_list || waypoint_num < 2 || !callback || !request_id)
1021                 return MAPS_ERROR_INVALID_PARAMETER;
1022
1023         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
1024         if (calldata_route == NULL)
1025                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1026
1027         calldata_route->callback = callback;
1028         calldata_route->data = user_data;
1029
1030         mapzen_route_req_s *route_req = (mapzen_route_req_s *)g_malloc0(sizeof(mapzen_route_req_s));
1031         if (route_req == NULL) {
1032                 g_free(calldata_route);
1033                 calldata_route = NULL;
1034                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1035         }
1036
1037         route_req->maps_key = g_strdup((gchar *) __provider_key);
1038
1039         route_req->from.latitude = 0.0;
1040         route_req->from.longitude = 0.0;
1041
1042         route_req->to.latitude = 0.0;
1043         route_req->to.longitude = 0.0;
1044
1045         MAPS_LOGD("getting transport mode..");
1046         maps_route_transport_mode_e transport_mode;
1047         maps_preference_get_route_transport_mode(preference, &transport_mode);
1048
1049         switch (transport_mode) {
1050         case MAPS_ROUTE_TRANSPORT_MODE_CAR:
1051                 route_req->type = COSTING_AUTO;
1052                 break;
1053         case MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN:
1054                 route_req->type = COSTING_PEDESTRIAN;
1055                 break;
1056         case MAPS_ROUTE_TRANSPORT_MODE_BICYCLE:
1057                 route_req->type = COSTING_BICYCLE;
1058                 break;
1059         case MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT:
1060                 route_req->type = COSTING_MULTIMODAL;
1061                 break;
1062         default:
1063                 return MAPS_ERROR_INVALID_PARAMETER;
1064                 break;
1065         }
1066
1067         /* Unit */
1068         maps_distance_unit_e unit;
1069         maps_preference_get_distance_unit(preference, &unit);
1070
1071         switch (unit) {
1072         case MAPS_DISTANCE_UNIT_KM:
1073                 route_req->unit = UNIT_KM;
1074                 break;
1075         default:
1076                 return MAPS_ERROR_INVALID_PARAMETER;
1077         }
1078
1079         route_req->avoids = PENALTY_NONE;
1080         maps_route_feature_weight_e routeWeight;
1081         maps_preference_get_route_feature_weight(preference, &routeWeight);
1082
1083         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
1084                 maps_route_feature_e routeFeature;
1085                 maps_preference_get_route_feature(preference, &routeFeature);
1086
1087                 switch (routeFeature) {
1088                 case MAPS_ROUTE_FEATURE_TOLL:
1089                         route_req->avoids = PENALTY_TOLL_ROADS;
1090                         break;
1091                 case MAPS_ROUTE_FEATURE_MOTORWAY:
1092                         route_req->avoids = PENALTY_LIMITED_ACCESS;
1093                         break;
1094                 case MAPS_ROUTE_FEATURE_BOATFERRY:
1095                 case MAPS_ROUTE_FEATURE_RAILFERRY:
1096                         route_req->avoids = PENALTY_USE_FERRY;
1097                         break;
1098                 case MAPS_ROUTE_FEATURE_DIRTROAD:
1099                         route_req->avoids = PENALTY_USE_UNPAVED;
1100                         break;
1101                 default:
1102                         return MAPS_ERROR_INVALID_PARAMETER;
1103                         break;
1104                 }
1105         }
1106
1107         /* Waypoints */
1108         route_req->way_points = NULL;
1109         if (waypoint_num != 0) {
1110                 int index = 0;
1111                 double latitude = 0.0, longitude = 0.0;
1112                 for (index = 0; index < waypoint_num; index++) {
1113                         if (waypoint_list[index] != NULL) {
1114                                 maps_coordinates_get_latitude(waypoint_list[index], &latitude);
1115                                 maps_coordinates_get_longitude(waypoint_list[index], &longitude);
1116
1117                                 coords_s *data = (coords_s *)g_malloc0(sizeof(coords_s));
1118                                 if (data) {
1119                                         data->latitude = latitude;
1120                                         data->longitude = longitude;
1121
1122                                         if (route_req->way_points == NULL)
1123                                                 route_req->way_points = g_list_append(route_req->way_points, (gpointer) data);
1124                                         else
1125                                                 route_req->way_points = g_list_insert_before(route_req->way_points, NULL, (gpointer) data);
1126                                 }
1127                         }
1128                 }
1129         }
1130
1131         *request_id = ++__request_id;
1132         calldata_route->reqID = __request_id;
1133
1134         int ret = mapzen_start_route(route_req, __mapzen_route_cb, __request_id, (void *)calldata_route);
1135
1136         return convert_mapzen_error_to_maps_error(ret);
1137 }
1138
1139 static void __mapzen_place_search_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
1140 {
1141         MAPS_LOGD("Got places result from ENGINE...");
1142
1143         callback_info_place *calldata_place = (callback_info_place *) user_data;
1144
1145         if (result != MAPZEN_ERROR_NONE || places == NULL) {
1146                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1147                 calldata_place->callback((maps_error_e) convert_mapzen_error_to_maps_error(result), calldata_place->reqID, 0, 0, NULL, calldata_place->data);
1148         } else {
1149                 guint total_count = 0;
1150                 int index = 0;
1151                 total_count = g_list_length(places);
1152                 if (total_count > 0) {
1153                         maps_place_h place = NULL;
1154                         MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
1155
1156                         GList *temp_place = NULL;
1157                         temp_place = g_list_first(places);
1158
1159                         while (temp_place) {
1160                                 maps_place_create(&place);
1161                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1162                                 maps_place_set_id(place, mapzen_place->place_id);
1163                                 maps_place_set_name(place, mapzen_place->display_name);
1164
1165                                 /* Address */
1166                                 if (mapzen_place->address) {
1167                                         maps_address_h addr = NULL;
1168                                         maps_address_create(&addr);
1169
1170                                         maps_address_set_street(addr, mapzen_place->address->street);
1171                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1172                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1173                                         maps_address_set_county(addr, mapzen_place->address->county);
1174                                         maps_address_set_state(addr, mapzen_place->address->region);
1175                                         maps_address_set_country(addr, mapzen_place->address->country);
1176                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1177                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1178                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1179
1180                                         maps_place_set_address(place, addr);
1181                                         maps_address_destroy(addr);
1182                                 } else {
1183                                         maps_place_set_address(place, NULL);
1184                                 }
1185
1186                                 maps_coordinates_h coord;
1187                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1188
1189                                 maps_place_set_location(place, coord);
1190                                 maps_coordinates_destroy(coord);
1191
1192                                 GList *cats = NULL;
1193                                 cats = g_list_first(mapzen_place->categories);
1194
1195                                 maps_item_list_h cat_list;
1196                                 maps_item_list_create(&cat_list);
1197
1198                                 while (cats != NULL) {
1199                                         if (cats->data != NULL) {
1200                                                 maps_place_category_h place_cat;
1201                                                 maps_place_category_create(&place_cat);
1202                                                 maps_place_category_set_name(place_cat, cats->data);
1203                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1204                                                 maps_place_category_destroy(place_cat);
1205                                         }
1206                                         cats = g_list_next(cats);
1207                                 }
1208
1209                                 if (g_list_length(cat_list) > 0) {
1210                                         maps_place_set_categories(place, cat_list);
1211                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1212                                 }
1213                                 maps_item_list_destroy(cat_list);
1214
1215                                 /* Don't have URLs yet.... */
1216                                 /*maps_place_image_h place_image = NULL; */
1217                                 /*maps_place_image_create(&place_image); */
1218                                 /*no url at this time. */
1219                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1220                                 /*maps_item_list_h image_list; */
1221                                 /*maps_item_list_create(&image_list); */
1222                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1223                                 /*maps_place_set_images(place, image_list); */
1224
1225                                 /*maps_place_image_destroy(place_image); */
1226                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1227                                 /*maps_item_list_destroy(image_list); */
1228
1229                                 bool b = calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, index, total_count, place, calldata_place->data);
1230                                 if (!b)
1231                                         return;
1232
1233                                 index++;
1234
1235                                 temp_place = temp_place->next;
1236                         }
1237                 } else {
1238                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, index, total_count, NULL, calldata_place->data);
1239                 }
1240         }
1241 }
1242
1243 static void __mapzen_place_get_details_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
1244 {
1245         MAPS_LOGD("Got places details result from ENGINE...");
1246
1247         callback_info_place_details *calldata_place = (callback_info_place_details *) user_data;
1248
1249         if (result != MAPZEN_ERROR_NONE || places == NULL) {
1250                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1251                 calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, NULL, calldata_place->data);
1252         } else {
1253                 guint total_count = 0;
1254                 total_count = g_list_length(places);
1255                 /* Should only have one result */
1256                 if (total_count == 1) {
1257                         maps_place_h place = NULL;
1258                         MAPS_LOGD("Got places details result from ENGINE... count -> %d", total_count);
1259
1260                         GList *temp_place = NULL;
1261                         temp_place = g_list_first(places);
1262
1263                         if (temp_place) {
1264                                 maps_place_create(&place);
1265                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1266                                 maps_place_set_id(place, mapzen_place->place_id);
1267                                 maps_place_set_name(place, mapzen_place->display_name);
1268
1269                                 /* Address */
1270                                 if (mapzen_place->address) {
1271                                         maps_address_h addr = NULL;
1272                                         maps_address_create(&addr);
1273
1274                                         maps_address_set_street(addr, mapzen_place->address->street);
1275                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1276                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1277                                         maps_address_set_county(addr, mapzen_place->address->county);
1278                                         maps_address_set_state(addr, mapzen_place->address->region);
1279                                         maps_address_set_country(addr, mapzen_place->address->country);
1280                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1281                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1282                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1283
1284                                         maps_place_set_address(place, addr);
1285                                         maps_address_destroy(addr);
1286                                 } else {
1287                                         maps_place_set_address(place, NULL);
1288                                 }
1289
1290                                 maps_coordinates_h coord;
1291                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1292
1293                                 maps_place_set_location(place, coord);
1294                                 maps_coordinates_destroy(coord);
1295
1296                                 GList *cats = NULL;
1297                                 cats = g_list_first(mapzen_place->categories);
1298
1299                                 maps_item_list_h cat_list;
1300                                 maps_item_list_create(&cat_list);
1301
1302                                 while (cats != NULL) {
1303                                         if (cats->data != NULL) {
1304                                                 maps_place_category_h place_cat;
1305                                                 maps_place_category_create(&place_cat);
1306                                                 maps_place_category_set_name(place_cat, cats->data);
1307                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1308                                                 maps_place_category_destroy(place_cat);
1309                                         }
1310                                         cats = g_list_next(cats);
1311                                 }
1312
1313                                 if (g_list_length(cat_list) > 0) {
1314                                         maps_place_set_categories(place, cat_list);
1315                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1316                                 }
1317                                 maps_item_list_destroy(cat_list);
1318
1319                                 /* Don't have URLs yet.... */
1320                                 /*maps_place_image_h place_image = NULL; */
1321                                 /*maps_place_image_create(&place_image); */
1322                                 /*no url at this time. */
1323                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1324                                 /*maps_item_list_h image_list; */
1325                                 /*maps_item_list_create(&image_list); */
1326                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1327                                 /*maps_place_set_images(place, image_list); */
1328
1329                                 /*maps_place_image_destroy(place_image); */
1330                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1331                                 /*maps_item_list_destroy(image_list); */
1332
1333                                 calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, place, calldata_place->data);
1334                                 return;
1335                         }
1336                 }
1337         }
1338         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, NULL, calldata_place->data);
1339 }
1340
1341 static void __maps_service_search_place_list_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
1342 {
1343         MAPS_LOGD("Got places result from ENGINE...");
1344
1345         callback_info_place_list *calldata_place = (callback_info_place_list *) user_data;
1346
1347         if (result != MAPZEN_ERROR_NONE || places == NULL) {
1348                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1349                 calldata_place->callback((maps_error_e) convert_mapzen_error_to_maps_error(result), calldata_place->reqID, 0, NULL, calldata_place->data);
1350         } else {
1351                 guint total_count = 0;
1352                 total_count = g_list_length(places);
1353                 if (total_count > 0) {
1354                         maps_place_h place = NULL;
1355                         MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
1356
1357                         maps_place_list_h place_list = NULL;
1358                         maps_place_list_create(&place_list);
1359
1360                         GList *temp_place = NULL;
1361                         temp_place = g_list_first(places);
1362
1363                         while (temp_place) {
1364                                 maps_place_create(&place);
1365                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1366                                 maps_place_set_id(place, mapzen_place->place_id);
1367                                 maps_place_set_name(place, mapzen_place->display_name);
1368
1369                                 /* Address */
1370                                 if (mapzen_place->address) {
1371                                         maps_address_h addr = NULL;
1372                                         maps_address_create(&addr);
1373
1374                                         maps_address_set_street(addr, mapzen_place->address->street);
1375                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1376                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1377                                         maps_address_set_county(addr, mapzen_place->address->county);
1378                                         maps_address_set_state(addr, mapzen_place->address->region);
1379                                         maps_address_set_country(addr, mapzen_place->address->country);
1380                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1381                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1382                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1383
1384                                         maps_place_set_address(place, addr);
1385                                         maps_address_destroy(addr);
1386                                 } else {
1387                                         maps_place_set_address(place, NULL);
1388                                 }
1389
1390                                 maps_coordinates_h coord;
1391                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1392
1393                                 maps_place_set_location(place, coord);
1394                                 maps_coordinates_destroy(coord);
1395
1396                                 GList *cats = NULL;
1397                                 cats = g_list_first(mapzen_place->categories);
1398
1399                                 maps_item_list_h cat_list;
1400                                 maps_item_list_create(&cat_list);
1401
1402                                 while (cats != NULL) {
1403                                         if (cats->data != NULL) {
1404                                                 maps_place_category_h place_cat;
1405                                                 maps_place_category_create(&place_cat);
1406                                                 maps_place_category_set_name(place_cat, cats->data);
1407                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1408                                                 maps_place_category_destroy(place_cat);
1409                                         }
1410                                         cats = g_list_next(cats);
1411                                 }
1412
1413                                 if (g_list_length(cat_list) > 0) {
1414                                         maps_place_set_categories(place, cat_list);
1415                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1416                                 }
1417                                 maps_item_list_destroy(cat_list);
1418
1419                                 /* Don't have URLs yet.... */
1420                                 /*maps_place_image_h place_image = NULL; */
1421                                 /*maps_place_image_create(&place_image); */
1422                                 /*no url at this time. */
1423                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1424                                 /*maps_item_list_h image_list; */
1425                                 /*maps_item_list_create(&image_list); */
1426                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1427                                 /*maps_place_set_images(place, image_list); */
1428
1429                                 /*maps_place_image_destroy(place_image); */
1430                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1431                                 /*maps_item_list_destroy(image_list); */
1432
1433                                 maps_item_list_append(place_list, place, maps_place_clone);
1434                                 maps_place_image_destroy(place);
1435                                 place = NULL;
1436                                 temp_place = temp_place->next;
1437                         }
1438                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, total_count, place_list, calldata_place->data);
1439
1440                 } else {
1441                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, total_count, NULL, calldata_place->data);
1442                 }
1443         }
1444 }
1445
1446 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)
1447 {
1448         if (!position || !filter || !callback || !request_id)
1449                 return MAPS_ERROR_INVALID_PARAMETER;
1450         if (distance <= 0)
1451                 return MAPS_ERROR_INVALID_PARAMETER;
1452
1453         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1454         if (calldata_place == NULL)
1455                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1456
1457         calldata_place->callback = callback;
1458         calldata_place->data = user_data;
1459
1460         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1461         if (place_req == NULL) {
1462                 g_free(calldata_place);
1463                 calldata_place = NULL;
1464                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1465         }
1466
1467         place_req->maps_key = g_strdup((gchar *) __provider_key);
1468
1469         int max_result;
1470         maps_preference_get_max_results(preference, &max_result);
1471
1472         if (max_result == 0)
1473                 place_req->num_res = DEFAULT_NUM_RESULTS;
1474         else
1475                 place_req->num_res = max_result;
1476
1477         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1478
1479         char *categoryName = NULL;
1480         char *searchKeyword = NULL;
1481
1482         maps_place_category_h category = NULL;
1483         maps_place_filter_get_category(filter, &category);
1484         maps_place_filter_get_keyword(filter, &searchKeyword);
1485
1486         if (category) {
1487                 maps_place_category_get_name(category, &categoryName);
1488                 maps_place_category_destroy(category);
1489         }
1490
1491         if (categoryName)
1492                 place_req->categories = g_strdup_printf("%s", categoryName);
1493
1494         if (searchKeyword)
1495                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1496
1497         if (!searchKeyword && !categoryName) {
1498                 g_free(calldata_place);
1499                 calldata_place = NULL;
1500                 g_free(place_req);
1501                 place_req = NULL;
1502                 return MAPS_ERROR_INVALID_PARAMETER;
1503         }
1504
1505         if (searchKeyword) {
1506                 g_free(searchKeyword);
1507                 searchKeyword = NULL;
1508         }
1509
1510         if (categoryName) {
1511                 g_free(categoryName);
1512                 categoryName = NULL;
1513         }
1514
1515         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1516
1517         place_req->boundary = NULL;
1518         place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1519
1520         if (place_req->boundary) {
1521                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1522                 double lat, lon;
1523                 maps_coordinates_get_latitude(position, &lat);
1524                 maps_coordinates_get_longitude(position, &lon);
1525                 place_req->boundary->circle.center.latitude = lat;
1526                 place_req->boundary->circle.center.longitude = lon;
1527                 place_req->boundary->circle.radius = distance;
1528         }
1529
1530         *request_id = ++__request_id;
1531         calldata_place->reqID = __request_id;
1532
1533         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1534
1535         return convert_mapzen_error_to_maps_error(ret);
1536 }
1537
1538 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)
1539 {
1540         if (!boundary || !filter || !callback || !request_id)
1541                 return MAPS_ERROR_INVALID_PARAMETER;
1542
1543         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1544         if (calldata_place == NULL)
1545                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1546
1547         calldata_place->callback = callback;
1548         calldata_place->data = user_data;
1549
1550         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1551         if (place_req == NULL) {
1552                 g_free(calldata_place);
1553                 calldata_place = NULL;
1554                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1555         }
1556
1557         place_req->maps_key = g_strdup((gchar *) __provider_key);
1558
1559         int max_result;
1560         maps_preference_get_max_results(preference, &max_result);
1561
1562         if (max_result == 0)
1563                 place_req->num_res = DEFAULT_NUM_RESULTS;
1564         else
1565                 place_req->num_res = max_result;
1566
1567         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1568
1569         char *categoryName = NULL;
1570         char *searchKeyword = NULL;
1571
1572         maps_place_category_h category = NULL;
1573         maps_place_filter_get_category(filter, &category);
1574         maps_place_filter_get_keyword(filter, &searchKeyword);
1575
1576         if (category) {
1577                 maps_place_category_get_name(category, &categoryName);
1578                 maps_place_category_destroy(category);
1579         }
1580
1581         if (categoryName)
1582                 place_req->categories = g_strdup_printf("%s", categoryName);
1583
1584         if (searchKeyword)
1585                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1586
1587         if (!searchKeyword && !categoryName) {
1588                 g_free(calldata_place);
1589                 calldata_place = NULL;
1590                 g_free(place_req);
1591                 place_req = NULL;
1592                 return MAPS_ERROR_INVALID_PARAMETER;
1593         }
1594
1595         if (searchKeyword) {
1596                 g_free(searchKeyword);
1597                 searchKeyword = NULL;
1598         }
1599
1600         if (categoryName) {
1601                 g_free(categoryName);
1602                 categoryName = NULL;
1603         }
1604
1605         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1606
1607         place_req->boundary = NULL;
1608         maps_area_s *bound = (maps_area_s *) boundary;
1609
1610         if (bound->type != MAPS_AREA_NONE) {
1611                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1612
1613                 if (place_req->boundary != NULL) {
1614                         if (bound->type == MAPS_AREA_CIRCLE) {
1615                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1616                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1617                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1618                                 place_req->boundary->circle.radius = bound->circle.radius;
1619                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1620                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1621                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1622                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1623                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1624                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1625                         }
1626                 }
1627         }
1628
1629         *request_id = ++__request_id;
1630         calldata_place->reqID = __request_id;
1631
1632         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1633
1634         return convert_mapzen_error_to_maps_error(ret);
1635 }
1636
1637 EXPORT_API int maps_plugin_search_place_list(const maps_area_h boundary, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_list_cb callback, void *user_data, int *request_id)
1638 {
1639
1640         if (!boundary || !filter || !callback || !request_id)
1641                 return MAPS_ERROR_INVALID_PARAMETER;
1642
1643         callback_info_place_list *calldata_place = (callback_info_place_list *)g_malloc0(sizeof(callback_info_place_list));
1644         if (calldata_place == NULL)
1645                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1646
1647         calldata_place->callback = callback;
1648         calldata_place->data = user_data;
1649
1650         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1651         if (place_req == NULL) {
1652                 g_free(calldata_place);
1653                 calldata_place = NULL;
1654                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1655         }
1656
1657         place_req->maps_key = g_strdup((gchar *) __provider_key);
1658
1659         int max_result;
1660         maps_preference_get_max_results(preference, &max_result);
1661
1662         if (max_result == 0)
1663                 place_req->num_res = DEFAULT_NUM_RESULTS;
1664         else
1665                 place_req->num_res = max_result;
1666
1667         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1668
1669         char *categoryName = NULL;
1670         char *searchKeyword = NULL;
1671
1672         maps_place_category_h category = NULL;
1673         maps_place_filter_get_category(filter, &category);
1674         maps_place_filter_get_keyword(filter, &searchKeyword);
1675
1676         if (category) {
1677                 maps_place_category_get_name(category, &categoryName);
1678                 maps_place_category_destroy(category);
1679         }
1680
1681         if (categoryName)
1682                 place_req->categories = g_strdup_printf("%s", categoryName);
1683
1684         if (searchKeyword)
1685                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1686
1687         if (!searchKeyword && !categoryName) {
1688                 g_free(calldata_place);
1689                 calldata_place = NULL;
1690                 g_free(place_req);
1691                 place_req = NULL;
1692                 return MAPS_ERROR_INVALID_PARAMETER;
1693         }
1694
1695         if (searchKeyword) {
1696                 g_free(searchKeyword);
1697                 searchKeyword = NULL;
1698         }
1699
1700         if (categoryName) {
1701                 g_free(categoryName);
1702                 categoryName = NULL;
1703         }
1704
1705         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1706
1707         place_req->boundary = NULL;
1708         maps_area_s *bound = (maps_area_s *) boundary;
1709
1710         if (bound->type != MAPS_AREA_NONE) {
1711                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1712
1713                 if (place_req->boundary != NULL) {
1714                         if (bound->type == MAPS_AREA_CIRCLE) {
1715                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1716                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1717                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1718                                 place_req->boundary->circle.radius = bound->circle.radius;
1719                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1720                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1721                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1722                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1723                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1724                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1725                         }
1726                 }
1727         }
1728
1729         *request_id = ++__request_id;
1730         calldata_place->reqID = __request_id;
1731
1732         int ret = mapzen_search_place_list(place_req, __maps_service_search_place_list_cb, __request_id, (void *) calldata_place);
1733
1734         return convert_mapzen_error_to_maps_error(ret);
1735 }
1736
1737 EXPORT_API int maps_plugin_get_place_details(const char *uri, maps_service_get_place_details_cb callback, void *user_data, int *request_id)
1738 {
1739         if (!uri || !callback || !request_id)
1740                 return MAPS_ERROR_INVALID_PARAMETER;
1741
1742         callback_info_place_details *calldata_place = (callback_info_place_details *)g_malloc0(sizeof(callback_info_place_details));
1743         if (calldata_place == NULL)
1744                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1745
1746         calldata_place->callback = callback;
1747         calldata_place->data = user_data;
1748
1749         mapzen_get_details_req_s *place_req = (mapzen_get_details_req_s *)g_malloc0(sizeof(mapzen_get_details_req_s));
1750         if (place_req == NULL) {
1751                 g_free(calldata_place);
1752                 calldata_place = NULL;
1753                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1754         }
1755
1756         place_req->maps_key = g_strdup((gchar *) __provider_key);
1757         place_req->uri = g_strdup_printf("%s", uri);
1758
1759         *request_id = ++__request_id;
1760         calldata_place->reqID = __request_id;
1761
1762         int ret = mapzen_get_place_details(place_req, __mapzen_place_get_details_cb, __request_id, (void *) calldata_place);
1763
1764         return convert_mapzen_error_to_maps_error(ret);
1765 }
1766
1767 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)
1768 {
1769         if (!address || !boundary || !filter || !callback || !request_id)
1770                 return MAPS_ERROR_INVALID_PARAMETER;
1771
1772         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1773         if (calldata_place == NULL)
1774                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1775
1776         calldata_place->callback = callback;
1777         calldata_place->data = user_data;
1778
1779         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1780         if (place_req == NULL) {
1781                 g_free(calldata_place);
1782                 calldata_place = NULL;
1783                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1784         }
1785
1786         place_req->maps_key = g_strdup((gchar *) __provider_key);
1787
1788         int max_result;
1789         maps_preference_get_max_results(preference, &max_result);
1790
1791         if (max_result == 0)
1792                 place_req->num_res = DEFAULT_NUM_RESULTS;
1793         else
1794                 place_req->num_res = max_result;
1795
1796         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1797
1798         char *categoryName = NULL;
1799
1800         maps_place_category_h category = NULL;
1801         maps_place_filter_get_category(filter, &category);
1802
1803         if (category) {
1804                 maps_place_category_get_name(category, &categoryName);
1805                 maps_place_category_destroy(category);
1806         }
1807
1808         if (categoryName)
1809                 place_req->categories = g_strdup_printf("%s", categoryName);
1810
1811         if (address)
1812                 place_req->search_string = g_strdup_printf("%s", address);
1813
1814         if (!address && !categoryName) {
1815                 g_free(calldata_place);
1816                 calldata_place = NULL;
1817                 g_free(place_req);
1818                 place_req = NULL;
1819                 return MAPS_ERROR_INVALID_PARAMETER;
1820         }
1821
1822         if (categoryName) {
1823                 g_free(categoryName);
1824                 categoryName = NULL;
1825         }
1826
1827         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1828
1829         place_req->boundary = NULL;
1830         maps_area_s *bound = (maps_area_s *) boundary;
1831
1832         if (bound->type != MAPS_AREA_NONE) {
1833                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1834
1835                 if (place_req->boundary != NULL) {
1836                         if (bound->type == MAPS_AREA_CIRCLE) {
1837                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1838                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1839                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1840                                 place_req->boundary->circle.radius = bound->circle.radius;
1841                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1842                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1843                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1844                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1845                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1846                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1847                         }
1848                 }
1849         }
1850
1851         *request_id = ++__request_id;
1852         calldata_place->reqID = __request_id;
1853
1854         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1855
1856         return convert_mapzen_error_to_maps_error(ret);
1857 }
1858
1859 EXPORT_API int maps_plugin_cancel_request(int request_id)
1860 {
1861         MAPS_LOGD("Plugin_Cancel_Request...");
1862         if (request_id < 0)
1863                 return MAPS_ERROR_INVALID_PARAMETER;
1864
1865         int ret = mapzen_cancel_request(request_id);
1866
1867         return convert_mapzen_error_to_maps_error(ret);
1868 }