799b0e13f9c29d1bfcd9d127bdfc8bbf2d6857ef
[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("__mapzen_route_cb");
617         callback_info_route *calldata_route = (callback_info_route *) user_data;
618
619         if (route_info) {
620                 maps_route_h route;
621                 maps_route_create(&route);
622
623                 maps_coordinates_h top_left;
624                 maps_coordinates_create(route_info->bounding_box.top_left.latitude, route_info->bounding_box.top_left.longitude, &top_left);
625
626                 maps_coordinates_h bottom_right;
627                 maps_coordinates_create(route_info->bounding_box.bottom_right.latitude, route_info->bounding_box.bottom_right.longitude, &bottom_right);
628
629                 maps_area_h bounds = NULL;
630                 maps_area_create_rectangle(top_left, bottom_right, &bounds);
631                 maps_route_set_bounding_box(route, bounds);
632                 maps_area_destroy(bounds);
633
634                 maps_coordinates_destroy(top_left);
635                 maps_coordinates_destroy(bottom_right);
636
637                 maps_distance_unit_e unit = MAPS_DISTANCE_UNIT_M;
638
639                 switch (route_info->distance_unit) {
640                 case UNIT_M:
641                         unit = MAPS_DISTANCE_UNIT_M;
642                         break;
643                 case UNIT_KM:
644                         unit = MAPS_DISTANCE_UNIT_KM;
645                         break;
646                 /*case ROUTE_UNIT_FT:
647                         unit = MAPS_DISTANCE_UNIT_FT;
648                         break;
649                 case ROUTE_UNIT_YD:
650                         unit = MAPS_DISTANCE_UNIT_YD;
651                         break;*/
652                 }
653
654                 maps_route_set_distance_unit(route, unit);
655                 maps_route_set_total_distance(route, route_info->distance);
656                 maps_route_set_total_duration(route, (long) route_info->time);
657                 if (route_info->type == COSTING_AUTO)
658                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
659                 else if (route_info->type == COSTING_PEDESTRIAN)
660                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN);
661                 else if (route_info->type == COSTING_BICYCLE)
662                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_BICYCLE);
663                 else if (route_info->type == COSTING_MULTIMODAL)
664                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT);
665                 else
666                         maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
667
668                 maps_item_list_h segment_list = NULL;
669                 maps_item_list_create(&segment_list);
670
671                 GList *maneuver_data = NULL;
672                 maneuver_data = g_list_first(route_info->maneuvers);
673
674                 while (maneuver_data) {
675                         maps_route_segment_h segment = NULL;
676                         maps_route_segment_create(&segment);
677
678                         maps_route_maneuver_h man = NULL;
679                         maps_route_maneuver_create(&man);
680                         mapzen_route_maneuver *maneuver = (mapzen_route_maneuver *) maneuver_data->data;
681
682                         /* Segment Origin and Destination */
683                         maps_coordinates_h segmentStartPoint;
684                         maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &segmentStartPoint);
685                         maps_route_segment_set_origin(segment, segmentStartPoint);      /* origin */
686                         maps_coordinates_destroy(segmentStartPoint);
687
688                         maps_coordinates_h segmentEndPoint;
689                         maps_coordinates_create(maneuver->end_point.latitude, maneuver->end_point.longitude, &segmentEndPoint);
690
691                         MAPS_LOGD(">>> Segment start : %f, %f <<<", maneuver->start_point.latitude, maneuver->start_point.longitude);
692                         MAPS_LOGD(">>> Segment end : %f, %f <<<", maneuver->end_point.latitude, maneuver->end_point.longitude);
693
694                         maps_route_segment_set_destination(segment, segmentEndPoint);   /* destination */
695                         maps_coordinates_destroy(segmentEndPoint);
696
697                         /* Segment distance */
698                         maps_route_segment_set_distance(segment, maneuver->distance);
699                         maps_route_segment_set_duration(segment, maneuver->time);
700
701                         /* Maneuver distance */
702                         maps_route_maneuver_set_distance_to_next_instruction(man, maneuver->distance);
703                         maps_route_maneuver_set_time_to_next_instruction(man, maneuver->time);
704
705                         /*maps_route_maneuver_set_turn_type(man, __convert_route_turn_type(maneuver->turn_type)); */
706
707                         /* maneuver_set_traffic_direction(man, (traffic_direction_e)action_id); */
708
709                         /* Maneuver Instruction */
710                         if (maneuver->instruction)
711                                 maps_route_maneuver_set_instruction_text(man, (char *) maneuver->instruction);
712
713                         /* Maneuver Street Name */
714                         if (maneuver->street_name) {
715                                 MAPS_LOGD("Street Name >>>> %s", maneuver->street_name);
716                                 maps_route_maneuver_set_road_name(man, (char *) maneuver->street_name);
717                         } else {
718                                 MAPS_LOGD("Street Name >>>> NIL");
719                         }
720
721                         /*/ Maneuver start position */
722                         maps_coordinates_h coord;
723                         maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &coord);
724
725                         maps_route_maneuver_set_position(man, coord);
726                         maps_coordinates_destroy(coord);
727
728                         maps_item_list_h maneuver_list = NULL;
729                         maps_item_list_create(&maneuver_list);
730                         maps_item_list_append(maneuver_list, (gpointer) man, maps_route_maneuver_clone);
731                         maps_route_segment_set_maneuvers(segment, maneuver_list);
732
733                         maps_item_list_destroy(maneuver_list);
734                         maps_route_maneuver_destroy(man);
735
736                         maps_item_list_append(segment_list, (gpointer) segment, maps_route_segment_clone);
737                         maps_route_segment_destroy(segment);
738
739                         /* Fetching the next item from Maneuver/Segment list */
740                         maneuver_data = g_list_next(maneuver_data);
741                 }
742                 maps_route_set_segments(route, segment_list);
743                 maps_item_list_destroy(segment_list);
744
745                 /* Shape points - path */
746                 maps_item_list_h path_list = NULL;
747                 maps_item_list_create(&path_list);
748
749                 GList *shapePoints = NULL;
750                 shapePoints = g_list_first(route_info->shapePoints);
751
752                 while (shapePoints) {
753                         coords_s *data = (coords_s *) shapePoints->data;
754
755                         maps_coordinates_h shapeCoords;
756                         maps_coordinates_create(data->latitude, data->longitude, &shapeCoords);
757
758                         maps_item_list_append(path_list, (gpointer) shapeCoords, maps_coordinates_clone);
759
760                         maps_coordinates_destroy(shapeCoords);
761
762                         shapePoints = g_list_next(shapePoints);
763                 }
764                 maps_route_set_path(route, path_list);
765                 maps_item_list_destroy(path_list);
766
767                 bool b = calldata_route->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_route->reqID, 0, 1, route, calldata_route->data);
768                 if (!b)
769                         return;
770         } else {
771                 calldata_route->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_route->reqID, 0, 0, NULL, calldata_route->data);
772         }
773 }
774
775 EXPORT_API int maps_plugin_search_route(const maps_coordinates_h origin, const maps_coordinates_h destination, maps_preference_h preference,    maps_service_search_route_cb callback, void *user_data, int *request_id)
776 {
777         if (!origin || !destination || !callback || !request_id)
778                 return MAPS_ERROR_INVALID_PARAMETER;
779
780         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
781         if (calldata_route == NULL)
782                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
783
784         calldata_route->callback = callback;
785         calldata_route->data = user_data;
786
787         mapzen_route_req_s *route_req = (mapzen_route_req_s *)g_malloc0(sizeof(mapzen_route_req_s));
788         if (route_req == NULL) {
789                 g_free(calldata_route);
790                 calldata_route = NULL;
791                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
792         }
793
794         route_req->maps_key = g_strdup((gchar *) __provider_key);
795
796         double origin_lat, origin_lon;
797         double dest_lat, dest_lon;
798
799         maps_coordinates_get_latitude(origin, &origin_lat);
800         maps_coordinates_get_longitude(origin, &origin_lon);
801
802         maps_coordinates_get_latitude(destination, &dest_lat);
803         maps_coordinates_get_longitude(destination, &dest_lon);
804
805         route_req->from.latitude = origin_lat;
806         route_req->from.longitude = origin_lon;
807
808         route_req->to.latitude = dest_lat;
809         route_req->to.longitude = dest_lon;
810
811         MAPS_LOGD("getting transport mode..");
812         maps_route_transport_mode_e transport_mode;
813         maps_preference_get_route_transport_mode(preference, &transport_mode);
814
815         if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
816                 route_req->type = COSTING_AUTO;
817         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
818                 route_req->type = COSTING_PEDESTRIAN;
819         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
820                 route_req->type = COSTING_BICYCLE;
821         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
822                 route_req->type = COSTING_MULTIMODAL;
823         else
824                 route_req->type = COSTING_AUTO; /* Keeping it as default */
825
826         route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
827
828         /* Unit */
829         maps_distance_unit_e unit;
830         maps_preference_get_distance_unit(preference, &unit);
831
832         switch (unit) {
833         case MAPS_DISTANCE_UNIT_M:
834                 route_req->unit = UNIT_M; /*miles, not meters */
835                 break;
836         case MAPS_DISTANCE_UNIT_KM:
837                 route_req->unit = UNIT_KM;
838                 break;
839         case MAPS_DISTANCE_UNIT_FT:
840                 /*route_req->unit = ROUTE_UNIT_FT; */
841                 break;
842         case MAPS_DISTANCE_UNIT_YD:
843                 /*route_req->unit = ROUTE_UNIT_YD; */
844                 break;
845         }
846
847         route_req->avoids = PENALTY_NONE;
848         maps_route_feature_weight_e routeWeight;
849         maps_preference_get_route_feature_weight(preference, &routeWeight);
850
851         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
852                 maps_route_feature_e routeFeature;
853                 maps_preference_get_route_feature(preference, &routeFeature);
854
855                 if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
856                         route_req->avoids = PENALTY_TOLL_ROADS;
857                 else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
858                         route_req->avoids = PENALTY_LIMITED_ACCESS;
859                 else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
860                         route_req->avoids = PENALTY_USE_FERRY;
861                 else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
862                         route_req->avoids = PENALTY_USE_UNPAVED;
863                 else
864                         route_req->avoids = PENALTY_NONE;
865         }
866
867         route_req->way_points = NULL;
868
869         *request_id = ++__request_id;
870         calldata_route->reqID = __request_id;
871
872         int ret = mapzen_start_route(route_req, __mapzen_route_cb, __request_id, (void *)calldata_route);
873
874         return convert_mapzen_error_to_maps_error(ret);
875 }
876
877 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)
878 {
879         if (!waypoint_list || waypoint_num < 2 || !callback || !request_id)
880                 return MAPS_ERROR_INVALID_PARAMETER;
881
882         callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
883         if (calldata_route == NULL)
884                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
885
886         calldata_route->callback = callback;
887         calldata_route->data = user_data;
888
889         mapzen_route_req_s *route_req = (mapzen_route_req_s *)g_malloc0(sizeof(mapzen_route_req_s));
890         if (route_req == NULL) {
891                 g_free(calldata_route);
892                 calldata_route = NULL;
893                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
894         }
895
896         route_req->maps_key = g_strdup((gchar *) __provider_key);
897
898         route_req->from.latitude = 0.0;
899         route_req->from.longitude = 0.0;
900
901         route_req->to.latitude = 0.0;
902         route_req->to.longitude = 0.0;
903
904         MAPS_LOGD("getting transport mode..");
905         maps_route_transport_mode_e transport_mode;
906         maps_preference_get_route_transport_mode(preference, &transport_mode);
907
908         if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
909                 route_req->type = COSTING_AUTO;
910         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
911                 route_req->type = COSTING_PEDESTRIAN;
912         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
913                 route_req->type = COSTING_BICYCLE;
914         else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
915                 route_req->type = COSTING_MULTIMODAL;
916         else
917                 route_req->type = COSTING_AUTO; /* Keeping it as default */
918
919         route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
920
921         /* Unit */
922         maps_distance_unit_e unit;
923         maps_preference_get_distance_unit(preference, &unit);
924
925         switch (unit) {
926         case MAPS_DISTANCE_UNIT_M:
927                 route_req->unit = UNIT_M;  /*miles, not meters */
928                 break;
929         case MAPS_DISTANCE_UNIT_KM:
930                 route_req->unit = UNIT_KM;
931                 break;
932         case MAPS_DISTANCE_UNIT_FT:
933         /*      route_req->unit = ROUTE_UNIT_FT; */
934                 break;
935         case MAPS_DISTANCE_UNIT_YD:
936         /*      route_req->unit = ROUTE_UNIT_YD; */
937                 break;
938         }
939
940         route_req->avoids = PENALTY_NONE;
941         maps_route_feature_weight_e routeWeight;
942         maps_preference_get_route_feature_weight(preference, &routeWeight);
943
944         if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
945                 maps_route_feature_e routeFeature;
946                 maps_preference_get_route_feature(preference, &routeFeature);
947
948                 if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
949                         route_req->avoids = PENALTY_TOLL_ROADS;
950                 else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
951                         route_req->avoids = PENALTY_LIMITED_ACCESS;
952                 else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
953                         route_req->avoids = PENALTY_USE_FERRY;
954                 else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
955                         route_req->avoids = PENALTY_USE_UNPAVED;
956                 else
957                         route_req->avoids = PENALTY_NONE;
958         }
959
960         /* Waypoints */
961         route_req->way_points = NULL;
962         if (waypoint_num != 0) {
963                 int index = 0;
964                 double latitude = 0.0, longitude = 0.0;
965                 for (index = 0; index < waypoint_num; index++) {
966                         if (waypoint_list[index] != NULL) {
967                                 maps_coordinates_get_latitude(waypoint_list[index], &latitude);
968                                 maps_coordinates_get_longitude(waypoint_list[index], &longitude);
969
970                                 coords_s *data = (coords_s *)g_malloc0(sizeof(coords_s));
971                                 if (data) {
972                                         data->latitude = latitude;
973                                         data->longitude = longitude;
974
975                                         if (route_req->way_points == NULL)
976                                                 route_req->way_points = g_list_append(route_req->way_points, (gpointer) data);
977                                         else
978                                                 route_req->way_points = g_list_insert_before(route_req->way_points, NULL, (gpointer) data);
979                                 }
980                         }
981                 }
982         }
983
984         *request_id = ++__request_id;
985         calldata_route->reqID = __request_id;
986
987         int ret = mapzen_start_route(route_req, __mapzen_route_cb, __request_id, (void *)calldata_route);
988
989         return convert_mapzen_error_to_maps_error(ret);
990 }
991
992 static void __mapzen_place_search_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
993 {
994         MAPS_LOGD("Got places result from ENGINE...");
995
996         callback_info_place *calldata_place = (callback_info_place *) user_data;
997
998         if (result != MAPZEN_ERROR_NONE || places == NULL) {
999                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1000                 calldata_place->callback((maps_error_e) convert_mapzen_error_to_maps_error(result), calldata_place->reqID, 0, 0, NULL, calldata_place->data);
1001         } else {
1002                 guint total_count = 0;
1003                 int index = 0;
1004                 total_count = g_list_length(places);
1005                 if (total_count > 0) {
1006                         maps_place_h place = NULL;
1007                         MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
1008
1009                         GList *temp_place = NULL;
1010                         temp_place = g_list_first(places);
1011
1012                         while (temp_place) {
1013                                 maps_place_create(&place);
1014                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1015                                 maps_place_set_id(place, mapzen_place->place_id);
1016                                 maps_place_set_name(place, mapzen_place->display_name);
1017
1018                                 /* Address */
1019                                 if (mapzen_place->address) {
1020                                         maps_address_h addr = NULL;
1021                                         maps_address_create(&addr);
1022
1023                                         maps_address_set_street(addr, mapzen_place->address->street);
1024                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1025                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1026                                         maps_address_set_county(addr, mapzen_place->address->county);
1027                                         maps_address_set_state(addr, mapzen_place->address->region);
1028                                         maps_address_set_country(addr, mapzen_place->address->country);
1029                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1030                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1031                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1032
1033                                         maps_place_set_address(place, addr);
1034                                         maps_address_destroy(addr);
1035                                 } else {
1036                                         maps_place_set_address(place, NULL);
1037                                 }
1038
1039                                 maps_coordinates_h coord;
1040                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1041
1042                                 maps_place_set_location(place, coord);
1043                                 maps_coordinates_destroy(coord);
1044
1045                                 GList *cats = NULL;
1046                                 cats = g_list_first(mapzen_place->categories);
1047
1048                                 maps_item_list_h cat_list;
1049                                 maps_item_list_create(&cat_list);
1050
1051                                 while (cats != NULL) {
1052                                         if (cats->data != NULL) {
1053                                                 maps_place_category_h place_cat;
1054                                                 maps_place_category_create(&place_cat);
1055                                                 maps_place_category_set_name(place_cat, cats->data);
1056                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1057                                                 maps_place_category_destroy(place_cat);
1058                                         }
1059                                         cats = g_list_next(cats);
1060                                 }
1061
1062                                 if (g_list_length(cat_list) > 0) {
1063                                         maps_place_set_categories(place, cat_list);
1064                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1065                                 }
1066                                 maps_item_list_destroy(cat_list);
1067
1068                                 /* Don't have URLs yet.... */
1069                                 /*maps_place_image_h place_image = NULL; */
1070                                 /*maps_place_image_create(&place_image); */
1071                                 /*no url at this time. */
1072                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1073                                 /*maps_item_list_h image_list; */
1074                                 /*maps_item_list_create(&image_list); */
1075                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1076                                 /*maps_place_set_images(place, image_list); */
1077
1078                                 /*maps_place_image_destroy(place_image); */
1079                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1080                                 /*maps_item_list_destroy(image_list); */
1081
1082                                 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);
1083                                 if (!b)
1084                                         return;
1085
1086                                 index++;
1087
1088                                 temp_place = temp_place->next;
1089                         }
1090                 } else {
1091                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, index, total_count, NULL, calldata_place->data);
1092                 }
1093         }
1094 }
1095
1096 static void __mapzen_place_get_details_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
1097 {
1098         MAPS_LOGD("Got places details result from ENGINE...");
1099
1100         callback_info_place_details *calldata_place = (callback_info_place_details *) user_data;
1101
1102         if (result != MAPZEN_ERROR_NONE || places == NULL) {
1103                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1104                 calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, NULL, calldata_place->data);
1105         } else {
1106                 guint total_count = 0;
1107                 total_count = g_list_length(places);
1108                 /* Should only have one result */
1109                 if (total_count == 1) {
1110                         maps_place_h place = NULL;
1111                         MAPS_LOGD("Got places details result from ENGINE... count -> %d", total_count);
1112
1113                         GList *temp_place = NULL;
1114                         temp_place = g_list_first(places);
1115
1116                         if (temp_place) {
1117                                 maps_place_create(&place);
1118                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1119                                 maps_place_set_id(place, mapzen_place->place_id);
1120                                 maps_place_set_name(place, mapzen_place->display_name);
1121
1122                                 /* Address */
1123                                 if (mapzen_place->address) {
1124                                         maps_address_h addr = NULL;
1125                                         maps_address_create(&addr);
1126
1127                                         maps_address_set_street(addr, mapzen_place->address->street);
1128                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1129                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1130                                         maps_address_set_county(addr, mapzen_place->address->county);
1131                                         maps_address_set_state(addr, mapzen_place->address->region);
1132                                         maps_address_set_country(addr, mapzen_place->address->country);
1133                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1134                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1135                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1136
1137                                         maps_place_set_address(place, addr);
1138                                         maps_address_destroy(addr);
1139                                 } else {
1140                                         maps_place_set_address(place, NULL);
1141                                 }
1142
1143                                 maps_coordinates_h coord;
1144                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1145
1146                                 maps_place_set_location(place, coord);
1147                                 maps_coordinates_destroy(coord);
1148
1149                                 GList *cats = NULL;
1150                                 cats = g_list_first(mapzen_place->categories);
1151
1152                                 maps_item_list_h cat_list;
1153                                 maps_item_list_create(&cat_list);
1154
1155                                 while (cats != NULL) {
1156                                         if (cats->data != NULL) {
1157                                                 maps_place_category_h place_cat;
1158                                                 maps_place_category_create(&place_cat);
1159                                                 maps_place_category_set_name(place_cat, cats->data);
1160                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1161                                                 maps_place_category_destroy(place_cat);
1162                                         }
1163                                         cats = g_list_next(cats);
1164                                 }
1165
1166                                 if (g_list_length(cat_list) > 0) {
1167                                         maps_place_set_categories(place, cat_list);
1168                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1169                                 }
1170                                 maps_item_list_destroy(cat_list);
1171
1172                                 /* Don't have URLs yet.... */
1173                                 /*maps_place_image_h place_image = NULL; */
1174                                 /*maps_place_image_create(&place_image); */
1175                                 /*no url at this time. */
1176                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1177                                 /*maps_item_list_h image_list; */
1178                                 /*maps_item_list_create(&image_list); */
1179                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1180                                 /*maps_place_set_images(place, image_list); */
1181
1182                                 /*maps_place_image_destroy(place_image); */
1183                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1184                                 /*maps_item_list_destroy(image_list); */
1185
1186                                 calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, place, calldata_place->data);
1187                                 return;
1188                         }
1189                 }
1190         }
1191         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, NULL, calldata_place->data);
1192 }
1193
1194 static void __maps_service_search_place_list_cb(mapzen_error_e result, int request_id, GList *places, void *user_data)
1195 {
1196         MAPS_LOGD("Got places result from ENGINE...");
1197
1198         callback_info_place_list *calldata_place = (callback_info_place_list *) user_data;
1199
1200         if (result != MAPZEN_ERROR_NONE || places == NULL) {
1201                 MAPS_LOGD("Got places result from ENGINE...result is NULL");
1202                 calldata_place->callback((maps_error_e) convert_mapzen_error_to_maps_error(result), calldata_place->reqID, 0, NULL, calldata_place->data);
1203         } else {
1204                 guint total_count = 0;
1205                 total_count = g_list_length(places);
1206                 if (total_count > 0) {
1207                         maps_place_h place = NULL;
1208                         MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
1209
1210                         maps_place_list_h place_list = NULL;
1211                         maps_place_list_create(&place_list);
1212
1213                         GList *temp_place = NULL;
1214                         temp_place = g_list_first(places);
1215
1216                         while (temp_place) {
1217                                 maps_place_create(&place);
1218                                 mapzen_place_resp_s *mapzen_place = (mapzen_place_resp_s *) temp_place->data;
1219                                 maps_place_set_id(place, mapzen_place->place_id);
1220                                 maps_place_set_name(place, mapzen_place->display_name);
1221
1222                                 /* Address */
1223                                 if (mapzen_place->address) {
1224                                         maps_address_h addr = NULL;
1225                                         maps_address_create(&addr);
1226
1227                                         maps_address_set_street(addr, mapzen_place->address->street);
1228                                         maps_address_set_building_number(addr, mapzen_place->address->housenumber);
1229                                         maps_address_set_city(addr, mapzen_place->address->localadmin);
1230                                         maps_address_set_county(addr, mapzen_place->address->county);
1231                                         maps_address_set_state(addr, mapzen_place->address->region);
1232                                         maps_address_set_country(addr, mapzen_place->address->country);
1233                                         maps_address_set_country_code(addr, mapzen_place->address->country_a);
1234                                         maps_address_set_postal_code(addr, mapzen_place->address->postalcode);
1235                                         maps_address_set_freetext(addr, mapzen_place->display_name);
1236
1237                                         maps_place_set_address(place, addr);
1238                                         maps_address_destroy(addr);
1239                                 } else {
1240                                         maps_place_set_address(place, NULL);
1241                                 }
1242
1243                                 maps_coordinates_h coord;
1244                                 maps_coordinates_create(mapzen_place->coordinates.latitude, mapzen_place->coordinates.longitude, &coord);
1245
1246                                 maps_place_set_location(place, coord);
1247                                 maps_coordinates_destroy(coord);
1248
1249                                 GList *cats = NULL;
1250                                 cats = g_list_first(mapzen_place->categories);
1251
1252                                 maps_item_list_h cat_list;
1253                                 maps_item_list_create(&cat_list);
1254
1255                                 while (cats != NULL) {
1256                                         if (cats->data != NULL) {
1257                                                 maps_place_category_h place_cat;
1258                                                 maps_place_category_create(&place_cat);
1259                                                 maps_place_category_set_name(place_cat, cats->data);
1260                                                 maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
1261                                                 maps_place_category_destroy(place_cat);
1262                                         }
1263                                         cats = g_list_next(cats);
1264                                 }
1265
1266                                 if (g_list_length(cat_list) > 0) {
1267                                         maps_place_set_categories(place, cat_list);
1268                                         maps_item_list_remove_all(cat_list, maps_place_category_destroy);
1269                                 }
1270                                 maps_item_list_destroy(cat_list);
1271
1272                                 /* Don't have URLs yet.... */
1273                                 /*maps_place_image_h place_image = NULL; */
1274                                 /*maps_place_image_create(&place_image); */
1275                                 /*no url at this time. */
1276                                 /*maps_place_image_set_url(place_image, mapzen_place->icon_url); */
1277                                 /*maps_item_list_h image_list; */
1278                                 /*maps_item_list_create(&image_list); */
1279                                 /*maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone); */
1280                                 /*maps_place_set_images(place, image_list); */
1281
1282                                 /*maps_place_image_destroy(place_image); */
1283                                 /*maps_item_list_remove_all(image_list, maps_place_image_destroy); */
1284                                 /*maps_item_list_destroy(image_list); */
1285
1286                                 maps_item_list_append(place_list, place, maps_place_clone);
1287                                 maps_place_image_destroy(place);
1288                                 place = NULL;
1289                                 temp_place = temp_place->next;
1290                         }
1291                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, total_count, place_list, calldata_place->data);
1292
1293                 } else {
1294                         calldata_place->callback((maps_error_e)convert_mapzen_error_to_maps_error(result), calldata_place->reqID, total_count, NULL, calldata_place->data);
1295                 }
1296         }
1297 }
1298
1299 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)
1300 {
1301         if (!position || !filter || !callback || !request_id)
1302                 return MAPS_ERROR_INVALID_PARAMETER;
1303         if (distance <= 0)
1304                 return MAPS_ERROR_INVALID_PARAMETER;
1305
1306         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1307         if (calldata_place == NULL)
1308                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1309
1310         calldata_place->callback = callback;
1311         calldata_place->data = user_data;
1312
1313         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1314         if (place_req == NULL) {
1315                 g_free(calldata_place);
1316                 calldata_place = NULL;
1317                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1318         }
1319
1320         place_req->maps_key = g_strdup((gchar *) __provider_key);
1321
1322         int max_result;
1323         maps_preference_get_max_results(preference, &max_result);
1324
1325         if (max_result == 0)
1326                 place_req->num_res = DEFAULT_NUM_RESULTS;
1327         else
1328                 place_req->num_res = max_result;
1329
1330         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1331
1332         char *categoryName = NULL;
1333         char *searchKeyword = NULL;
1334
1335         maps_place_category_h category = NULL;
1336         maps_place_filter_get_category(filter, &category);
1337         maps_place_filter_get_keyword(filter, &searchKeyword);
1338
1339         if (category) {
1340                 maps_place_category_get_name(category, &categoryName);
1341                 maps_place_category_destroy(category);
1342         }
1343
1344         if (categoryName)
1345                 place_req->categories = g_strdup_printf("%s", categoryName);
1346
1347         if (searchKeyword)
1348                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1349
1350         if (!searchKeyword && !categoryName) {
1351                 g_free(calldata_place);
1352                 calldata_place = NULL;
1353                 g_free(place_req);
1354                 place_req = NULL;
1355                 return MAPS_ERROR_INVALID_PARAMETER;
1356         }
1357
1358         if (searchKeyword) {
1359                 g_free(searchKeyword);
1360                 searchKeyword = NULL;
1361         }
1362
1363         if (categoryName) {
1364                 g_free(categoryName);
1365                 categoryName = NULL;
1366         }
1367
1368         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1369
1370         place_req->boundary = NULL;
1371         place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1372
1373         if (place_req->boundary) {
1374                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1375                 double lat, lon;
1376                 maps_coordinates_get_latitude(position, &lat);
1377                 maps_coordinates_get_longitude(position, &lon);
1378                 place_req->boundary->circle.center.latitude = lat;
1379                 place_req->boundary->circle.center.longitude = lon;
1380                 place_req->boundary->circle.radius = distance;
1381         }
1382
1383         *request_id = ++__request_id;
1384         calldata_place->reqID = __request_id;
1385
1386         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1387
1388         return convert_mapzen_error_to_maps_error(ret);
1389 }
1390
1391 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)
1392 {
1393         if (!boundary || !filter || !callback || !request_id)
1394                 return MAPS_ERROR_INVALID_PARAMETER;
1395
1396         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1397         if (calldata_place == NULL)
1398                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1399
1400         calldata_place->callback = callback;
1401         calldata_place->data = user_data;
1402
1403         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1404         if (place_req == NULL) {
1405                 g_free(calldata_place);
1406                 calldata_place = NULL;
1407                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1408         }
1409
1410         place_req->maps_key = g_strdup((gchar *) __provider_key);
1411
1412         int max_result;
1413         maps_preference_get_max_results(preference, &max_result);
1414
1415         if (max_result == 0)
1416                 place_req->num_res = DEFAULT_NUM_RESULTS;
1417         else
1418                 place_req->num_res = max_result;
1419
1420         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1421
1422         char *categoryName = NULL;
1423         char *searchKeyword = NULL;
1424
1425         maps_place_category_h category = NULL;
1426         maps_place_filter_get_category(filter, &category);
1427         maps_place_filter_get_keyword(filter, &searchKeyword);
1428
1429         if (category) {
1430                 maps_place_category_get_name(category, &categoryName);
1431                 maps_place_category_destroy(category);
1432         }
1433
1434         if (categoryName)
1435                 place_req->categories = g_strdup_printf("%s", categoryName);
1436
1437         if (searchKeyword)
1438                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1439
1440         if (!searchKeyword && !categoryName) {
1441                 g_free(calldata_place);
1442                 calldata_place = NULL;
1443                 g_free(place_req);
1444                 place_req = NULL;
1445                 return MAPS_ERROR_INVALID_PARAMETER;
1446         }
1447
1448         if (searchKeyword) {
1449                 g_free(searchKeyword);
1450                 searchKeyword = NULL;
1451         }
1452
1453         if (categoryName) {
1454                 g_free(categoryName);
1455                 categoryName = NULL;
1456         }
1457
1458         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1459
1460         place_req->boundary = NULL;
1461         maps_area_s *bound = (maps_area_s *) boundary;
1462
1463         if (bound->type != MAPS_AREA_NONE) {
1464                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1465
1466                 if (place_req->boundary != NULL) {
1467                         if (bound->type == MAPS_AREA_CIRCLE) {
1468                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1469                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1470                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1471                                 place_req->boundary->circle.radius = bound->circle.radius;
1472                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1473                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1474                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1475                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1476                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1477                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1478                         }
1479                 }
1480         }
1481
1482         *request_id = ++__request_id;
1483         calldata_place->reqID = __request_id;
1484
1485         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1486
1487         return convert_mapzen_error_to_maps_error(ret);
1488 }
1489
1490 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)
1491 {
1492
1493         if (!boundary || !filter || !callback || !request_id)
1494                 return MAPS_ERROR_INVALID_PARAMETER;
1495
1496         callback_info_place_list *calldata_place = (callback_info_place_list *)g_malloc0(sizeof(callback_info_place_list));
1497         if (calldata_place == NULL)
1498                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1499
1500         calldata_place->callback = callback;
1501         calldata_place->data = user_data;
1502
1503         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1504         if (place_req == NULL) {
1505                 g_free(calldata_place);
1506                 calldata_place = NULL;
1507                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1508         }
1509
1510         place_req->maps_key = g_strdup((gchar *) __provider_key);
1511
1512         int max_result;
1513         maps_preference_get_max_results(preference, &max_result);
1514
1515         if (max_result == 0)
1516                 place_req->num_res = DEFAULT_NUM_RESULTS;
1517         else
1518                 place_req->num_res = max_result;
1519
1520         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1521
1522         char *categoryName = NULL;
1523         char *searchKeyword = NULL;
1524
1525         maps_place_category_h category = NULL;
1526         maps_place_filter_get_category(filter, &category);
1527         maps_place_filter_get_keyword(filter, &searchKeyword);
1528
1529         if (category) {
1530                 maps_place_category_get_name(category, &categoryName);
1531                 maps_place_category_destroy(category);
1532         }
1533
1534         if (categoryName)
1535                 place_req->categories = g_strdup_printf("%s", categoryName);
1536
1537         if (searchKeyword)
1538                 place_req->search_string = g_strdup_printf("%s", searchKeyword);
1539
1540         if (!searchKeyword && !categoryName) {
1541                 g_free(calldata_place);
1542                 calldata_place = NULL;
1543                 g_free(place_req);
1544                 place_req = NULL;
1545                 return MAPS_ERROR_INVALID_PARAMETER;
1546         }
1547
1548         if (searchKeyword) {
1549                 g_free(searchKeyword);
1550                 searchKeyword = NULL;
1551         }
1552
1553         if (categoryName) {
1554                 g_free(categoryName);
1555                 categoryName = NULL;
1556         }
1557
1558         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1559
1560         place_req->boundary = NULL;
1561         maps_area_s *bound = (maps_area_s *) boundary;
1562
1563         if (bound->type != MAPS_AREA_NONE) {
1564                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1565
1566                 if (place_req->boundary != NULL) {
1567                         if (bound->type == MAPS_AREA_CIRCLE) {
1568                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1569                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1570                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1571                                 place_req->boundary->circle.radius = bound->circle.radius;
1572                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1573                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1574                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1575                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1576                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1577                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1578                         }
1579                 }
1580         }
1581
1582         *request_id = ++__request_id;
1583         calldata_place->reqID = __request_id;
1584
1585         int ret = mapzen_search_place_list(place_req, __maps_service_search_place_list_cb, __request_id, (void *) calldata_place);
1586
1587         return convert_mapzen_error_to_maps_error(ret);
1588 }
1589
1590 EXPORT_API int maps_plugin_get_place_details(const char *uri, maps_service_get_place_details_cb callback, void *user_data, int *request_id)
1591 {
1592         if (!uri || !callback || !request_id)
1593                 return MAPS_ERROR_INVALID_PARAMETER;
1594
1595         callback_info_place_details *calldata_place = (callback_info_place_details *)g_malloc0(sizeof(callback_info_place_details));
1596         if (calldata_place == NULL)
1597                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1598
1599         calldata_place->callback = callback;
1600         calldata_place->data = user_data;
1601
1602         mapzen_get_details_req_s *place_req = (mapzen_get_details_req_s *)g_malloc0(sizeof(mapzen_get_details_req_s));
1603         if (place_req == NULL) {
1604                 g_free(calldata_place);
1605                 calldata_place = NULL;
1606                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1607         }
1608
1609         place_req->maps_key = g_strdup((gchar *) __provider_key);
1610         place_req->uri = g_strdup_printf("%s", uri);
1611
1612         *request_id = ++__request_id;
1613         calldata_place->reqID = __request_id;
1614
1615         int ret = mapzen_get_place_details(place_req, __mapzen_place_get_details_cb, __request_id, (void *) calldata_place);
1616
1617         return convert_mapzen_error_to_maps_error(ret);
1618 }
1619
1620 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)
1621 {
1622         if (!address || !boundary || !filter || !callback || !request_id)
1623                 return MAPS_ERROR_INVALID_PARAMETER;
1624
1625         callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
1626         if (calldata_place == NULL)
1627                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1628
1629         calldata_place->callback = callback;
1630         calldata_place->data = user_data;
1631
1632         mapzen_search_req_s *place_req = (mapzen_search_req_s *)g_malloc0(sizeof(mapzen_search_req_s));
1633         if (place_req == NULL) {
1634                 g_free(calldata_place);
1635                 calldata_place = NULL;
1636                 MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
1637         }
1638
1639         place_req->maps_key = g_strdup((gchar *) __provider_key);
1640
1641         int max_result;
1642         maps_preference_get_max_results(preference, &max_result);
1643
1644         if (max_result == 0)
1645                 place_req->num_res = DEFAULT_NUM_RESULTS;
1646         else
1647                 place_req->num_res = max_result;
1648
1649         MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
1650
1651         char *categoryName = NULL;
1652
1653         maps_place_category_h category = NULL;
1654         maps_place_filter_get_category(filter, &category);
1655
1656         if (category) {
1657                 maps_place_category_get_name(category, &categoryName);
1658                 maps_place_category_destroy(category);
1659         }
1660
1661         if (categoryName)
1662                 place_req->categories = g_strdup_printf("%s", categoryName);
1663
1664         if (address)
1665                 place_req->search_string = g_strdup_printf("%s", address);
1666
1667         if (!address && !categoryName) {
1668                 g_free(calldata_place);
1669                 calldata_place = NULL;
1670                 g_free(place_req);
1671                 place_req = NULL;
1672                 return MAPS_ERROR_INVALID_PARAMETER;
1673         }
1674
1675         if (categoryName) {
1676                 g_free(categoryName);
1677                 categoryName = NULL;
1678         }
1679
1680         MAPS_LOGD(">>>>>>>> Place search categories :: %s <<<<<<<<<", place_req->categories);
1681
1682         place_req->boundary = NULL;
1683         maps_area_s *bound = (maps_area_s *) boundary;
1684
1685         if (bound->type != MAPS_AREA_NONE) {
1686                 place_req->boundary = (mapzen_boundary_s *)g_malloc0(sizeof(mapzen_boundary_s));
1687
1688                 if (place_req->boundary != NULL) {
1689                         if (bound->type == MAPS_AREA_CIRCLE) {
1690                                 place_req->boundary->type = MAPZEN_BOUNDARY_CIRCLE;
1691                                 place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
1692                                 place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
1693                                 place_req->boundary->circle.radius = bound->circle.radius;
1694                         } else if (bound->type == MAPS_AREA_RECTANGLE) {
1695                                 place_req->boundary->type = MAPZEN_BOUNDARY_RECT;
1696                                 place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
1697                                 place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
1698                                 place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
1699                                 place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
1700                         }
1701                 }
1702         }
1703
1704         *request_id = ++__request_id;
1705         calldata_place->reqID = __request_id;
1706
1707         int ret = mapzen_search_place(place_req, __mapzen_place_search_cb, __request_id, (void *) calldata_place);
1708
1709         return convert_mapzen_error_to_maps_error(ret);
1710 }
1711
1712 EXPORT_API int maps_plugin_cancel_request(int request_id)
1713 {
1714         MAPS_LOGD("Plugin_Cancel_Request...");
1715         if (request_id < 0)
1716                 return MAPS_ERROR_INVALID_PARAMETER;
1717
1718         int ret = mapzen_cancel_request(request_id);
1719
1720         return convert_mapzen_error_to_maps_error(ret);
1721 }