2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "maps_util.h"
19 #include "maps_route_plugin.h"
20 #include "maps_error.h"
21 #include "maps_preference.h"
22 #include "maps_route_segment_plugin.h"
23 #include "maps_route_private.h"
24 #include "maps_route_segment_private.h"
25 #include "maps_condition.h"
27 static bool __is_supported(const maps_route_h route, maps_service_data_e data)
29 bool supported = false;
30 _maps_route_is_data_supported(route, data, &supported);
34 static bool __maps_route_set_supported_data_foreach_cb(int index, int total,
38 _maps_route_segment_set_supported_data(data, user_data);
42 /*----------------------------------------------------------------------------*/
47 typedef struct _maps_route_s
49 char *route_id; /*< route_id */
50 maps_coordinates_h origin; /*< Coordinate StartCoord */
51 maps_coordinates_h destination; /*< Coordinates destCoord */
52 maps_area_h bounding_box; /*< A rectangular geographical area */
53 maps_route_transport_mode_e transport_mode; /*< The transport mode
55 double total_distance; /*< Total distance */
56 long total_duration; /*< Total duration */
57 maps_distance_unit_e distance_unit; /*< Distance units */
58 maps_item_list_h segments; /*< List of segments,
59 maps_route_segment_h */
60 maps_item_list_h path; /*< Path, list of maps_coordinates_h */
61 maps_item_hashtable_h properties; /*< Key/Value> */
63 /* The table of available data features */
64 maps_int_hashtable_h supported_data;
65 /* TODO: implement hashtable<int, int> */
68 const gsize _MAPS_ROUTE_ID_MAX_LENGTH = MAPS_BASE_ID_MAX_LEN;
70 /*----------------------------------------------------------------------------*/
72 EXPORT_API int maps_route_create(maps_route_h *route)
74 if (!maps_condition_check_maps_feature())
75 return MAPS_ERROR_NOT_SUPPORTED;
77 return MAPS_ERROR_INVALID_PARAMETER;
78 *route = (maps_route_h) g_slice_new0(maps_route_s);
81 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
82 return MAPS_ERROR_OUT_OF_MEMORY;
85 return MAPS_ERROR_NONE;
88 EXPORT_API int maps_route_destroy(maps_route_h route)
90 if (!maps_condition_check_maps_feature())
91 return MAPS_ERROR_NOT_SUPPORTED;
93 return MAPS_ERROR_INVALID_PARAMETER;
95 maps_route_s *p = (maps_route_s *) route;
100 maps_coordinates_destroy(p->origin);
102 maps_coordinates_destroy(p->destination);
104 maps_area_destroy(p->bounding_box);
106 maps_item_hashtable_destroy(p->properties);
109 maps_item_list_remove_all(p->segments,
110 maps_route_segment_destroy);
111 maps_item_list_destroy(p->segments);
115 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
116 maps_item_list_destroy(p->path);
119 if (p->supported_data)
120 maps_int_hashtable_destroy(p->supported_data);
122 g_slice_free(maps_route_s, route);
123 return MAPS_ERROR_NONE;
126 EXPORT_API int maps_route_clone(const maps_route_h origin,
127 maps_route_h *cloned)
129 if (!maps_condition_check_maps_feature())
130 return MAPS_ERROR_NOT_SUPPORTED;
131 if (!cloned || !origin)
132 return MAPS_ERROR_INVALID_PARAMETER;
134 int error = MAPS_ERROR_NONE;
136 error = maps_route_create(cloned);
137 if (!(*cloned) || (error != MAPS_ERROR_NONE))
140 maps_route_s *r = (maps_route_s *) origin;
143 error = maps_route_set_route_id(*cloned, r->route_id);
144 if (error != MAPS_ERROR_NONE)
149 error = maps_route_set_origin(*cloned, r->origin);
150 if (error != MAPS_ERROR_NONE)
154 if (r->destination) {
155 error = maps_route_set_destination(*cloned, r->destination);
156 if (error != MAPS_ERROR_NONE)
160 if (r->bounding_box) {
161 error = maps_route_set_bounding_box(*cloned, r->bounding_box);
162 if (error != MAPS_ERROR_NONE)
166 error = maps_route_set_transport_mode(*cloned, r->transport_mode);
167 if (error != MAPS_ERROR_NONE)
170 error = maps_route_set_total_distance(*cloned, r->total_distance);
171 if (error != MAPS_ERROR_NONE)
174 error = maps_route_set_total_duration(*cloned, r->total_duration);
175 if (error != MAPS_ERROR_NONE)
178 error = maps_route_set_distance_unit(*cloned, r->distance_unit);
179 if (error != MAPS_ERROR_NONE)
183 error = maps_route_set_segments(*cloned, r->segments);
184 if (error != MAPS_ERROR_NONE)
189 error = maps_route_set_path(*cloned, r->path);
190 if (error != MAPS_ERROR_NONE)
195 error = maps_route_set_properties(*cloned, r->properties);
196 if (error != MAPS_ERROR_NONE)
200 if (r->supported_data) {
201 error = _maps_route_set_supported_data(*cloned, r->supported_data);
202 if (error != MAPS_ERROR_NONE)
206 return MAPS_ERROR_NONE;
209 maps_route_destroy(*cloned);
214 /*----------------------------------------------------------------------------*/
216 EXPORT_API int maps_route_get_route_id(const maps_route_h route,
219 if (!maps_condition_check_maps_feature())
220 return MAPS_ERROR_NOT_SUPPORTED;
221 if (!route || !route_id)
222 return MAPS_ERROR_INVALID_PARAMETER;
223 return maps_get_string(((maps_route_s *) route)->route_id,
224 _MAPS_ROUTE_ID_MAX_LENGTH, route_id);
227 EXPORT_API int maps_route_get_origin(const maps_route_h route,
228 maps_coordinates_h *origin)
230 if (!maps_condition_check_maps_feature())
231 return MAPS_ERROR_NOT_SUPPORTED;
232 if (!route || !origin)
233 return MAPS_ERROR_INVALID_PARAMETER;
234 maps_coordinates_clone(((maps_route_s *) route)->origin, origin);
235 return MAPS_ERROR_NONE;
238 EXPORT_API int maps_route_get_destination(const maps_route_h route,
239 maps_coordinates_h *destination)
241 if (!maps_condition_check_maps_feature())
242 return MAPS_ERROR_NOT_SUPPORTED;
243 if (!route || !destination)
244 return MAPS_ERROR_INVALID_PARAMETER;
245 return maps_coordinates_clone(((maps_route_s *) route)->destination,
249 EXPORT_API int maps_route_get_bounding_box(const maps_route_h route,
250 maps_area_h *bounding_box)
252 if (!maps_condition_check_maps_feature())
253 return MAPS_ERROR_NOT_SUPPORTED;
254 if (!route || !bounding_box)
255 return MAPS_ERROR_INVALID_PARAMETER;
256 return maps_area_clone(((maps_route_s *) route)->bounding_box,
260 EXPORT_API int maps_route_get_transport_mode(const maps_route_h route,
261 maps_route_transport_mode_e *transport_mode)
263 if (!maps_condition_check_maps_feature())
264 return MAPS_ERROR_NOT_SUPPORTED;
265 if (!route || !transport_mode)
266 return MAPS_ERROR_INVALID_PARAMETER;
267 *transport_mode = ((maps_route_s *) route)->transport_mode;
268 return MAPS_ERROR_NONE;
271 EXPORT_API int maps_route_get_total_distance(const maps_route_h route,
272 double *total_distance)
274 if (!maps_condition_check_maps_feature())
275 return MAPS_ERROR_NOT_SUPPORTED;
276 if (!route || !total_distance)
277 return MAPS_ERROR_INVALID_PARAMETER;
278 *total_distance = ((maps_route_s *) route)->total_distance;
279 return MAPS_ERROR_NONE;
282 EXPORT_API int maps_route_get_total_duration(const maps_route_h route,
283 long *total_duration)
285 if (!maps_condition_check_maps_feature())
286 return MAPS_ERROR_NOT_SUPPORTED;
287 if (!route || !total_duration)
288 return MAPS_ERROR_INVALID_PARAMETER;
289 *total_duration = ((maps_route_s *) route)->total_duration;
290 return MAPS_ERROR_NONE;
293 EXPORT_API int maps_route_foreach_path(const maps_route_h route,
294 maps_route_path_cb callback,
297 if (!maps_condition_check_maps_feature())
298 return MAPS_ERROR_NOT_SUPPORTED;
300 return MAPS_ERROR_INVALID_PARAMETER;
301 if (!__is_supported(route, MAPS_ROUTE_PATH))
302 return MAPS_ERROR_NOT_SUPPORTED;
304 return MAPS_ERROR_INVALID_PARAMETER;
305 if (!((maps_route_s *) route)->path)
306 return MAPS_ERROR_NOT_FOUND;
308 return maps_item_list_foreach(((maps_route_s *) route)->path,
309 maps_coordinates_clone, callback, user_data);
312 EXPORT_API int maps_route_foreach_segment(const maps_route_h route,
313 maps_route_segment_cb callback,
316 if (!maps_condition_check_maps_feature())
317 return MAPS_ERROR_NOT_SUPPORTED;
319 return MAPS_ERROR_INVALID_PARAMETER;
320 if (!__is_supported(route, MAPS_ROUTE_SEGMENTS_PATH)
321 && !__is_supported(route, MAPS_ROUTE_SEGMENTS_MANEUVERS))
322 return MAPS_ERROR_NOT_SUPPORTED;
324 return MAPS_ERROR_INVALID_PARAMETER;
325 if (!((maps_route_s *) route)->segments)
326 return MAPS_ERROR_NOT_FOUND;
328 return maps_item_list_foreach(((maps_route_s *) route)->segments,
329 maps_route_segment_clone, callback, user_data);
332 EXPORT_API int maps_route_foreach_property(const maps_route_h route,
333 maps_route_properties_cb callback,
336 if (!maps_condition_check_maps_feature())
337 return MAPS_ERROR_NOT_SUPPORTED;
338 if (!route || !callback)
339 return MAPS_ERROR_INVALID_PARAMETER;
340 if (!((maps_route_s *) route)->properties)
341 return MAPS_ERROR_NOT_FOUND;
342 return maps_item_hashtable_foreach(((maps_route_s *) route)->properties,
343 callback, user_data);
346 EXPORT_API int maps_route_get_distance_unit(const maps_route_h route,
347 maps_distance_unit_e *distance_unit)
349 if (!maps_condition_check_maps_feature())
350 return MAPS_ERROR_NOT_SUPPORTED;
351 if (!route || !distance_unit)
352 return MAPS_ERROR_INVALID_PARAMETER;
353 *distance_unit = ((maps_route_s *) route)->distance_unit;
354 return MAPS_ERROR_NONE;
357 int _maps_route_is_data_supported(const maps_route_h route,
358 maps_service_data_e data, bool *supported)
360 if (!maps_condition_check_maps_feature())
361 return MAPS_ERROR_NOT_SUPPORTED;
362 if (!route || !supported)
363 return MAPS_ERROR_INVALID_PARAMETER;
365 maps_route_s *r = (maps_route_s *)route;
367 if (!r->supported_data) {
368 /* This is a case when the "supported" flags are not set yet */
369 /* No need to limit access to fields */
371 return MAPS_ERROR_NONE;
375 return maps_int_hashtable_contains(r->supported_data, data, supported);
378 /*----------------------------------------------------------------------------*/
380 EXPORT_API int maps_route_set_route_id(const maps_route_h route,
381 const char *route_id)
383 if (!maps_condition_check_maps_feature())
384 return MAPS_ERROR_NOT_SUPPORTED;
385 if (!route || !route_id)
386 return MAPS_ERROR_INVALID_PARAMETER;
387 return maps_set_string(route_id, _MAPS_ROUTE_ID_MAX_LENGTH,
388 &((maps_route_s *) route)->route_id);
391 EXPORT_API int maps_route_set_origin(maps_route_h route,
392 const maps_coordinates_h origin)
394 if (!maps_condition_check_maps_feature())
395 return MAPS_ERROR_NOT_SUPPORTED;
396 if (!route || !origin)
397 return MAPS_ERROR_INVALID_PARAMETER;
398 maps_route_s *p = (maps_route_s *) route;
400 maps_coordinates_destroy(p->origin);
401 return maps_coordinates_clone(origin, &p->origin);
404 EXPORT_API int maps_route_set_destination(maps_route_h route,
405 const maps_coordinates_h destination)
407 if (!maps_condition_check_maps_feature())
408 return MAPS_ERROR_NOT_SUPPORTED;
409 if (!route || !destination)
410 return MAPS_ERROR_INVALID_PARAMETER;
411 maps_route_s *p = (maps_route_s *) route;
413 maps_coordinates_destroy(p->destination);
414 return maps_coordinates_clone(destination, &p->destination);
417 EXPORT_API int maps_route_set_bounding_box(maps_route_h route,
418 const maps_area_h bounding_box)
420 if (!maps_condition_check_maps_feature())
421 return MAPS_ERROR_NOT_SUPPORTED;
422 if (!route || !bounding_box)
423 return MAPS_ERROR_INVALID_PARAMETER;
424 maps_route_s *p = (maps_route_s *) route;
426 maps_area_destroy(p->bounding_box);
427 return maps_area_clone(bounding_box, &p->bounding_box);
430 EXPORT_API int maps_route_set_total_distance(maps_route_h route,
431 const double total_distance)
433 if (!maps_condition_check_maps_feature())
434 return MAPS_ERROR_NOT_SUPPORTED;
435 if (!route || total_distance < 0)
436 return MAPS_ERROR_INVALID_PARAMETER;
437 ((maps_route_s *) route)->total_distance = total_distance;
438 return MAPS_ERROR_NONE;
441 EXPORT_API int maps_route_set_total_duration(maps_route_h route,
442 const long total_duration)
444 if (!maps_condition_check_maps_feature())
445 return MAPS_ERROR_NOT_SUPPORTED;
446 if (!route || total_duration < 0)
447 return MAPS_ERROR_INVALID_PARAMETER;
448 ((maps_route_s *) route)->total_duration = total_duration;
449 return MAPS_ERROR_NONE;
452 EXPORT_API int maps_route_set_transport_mode(maps_route_h route,
453 const maps_route_transport_mode_e transport_mode)
455 if (!maps_condition_check_maps_feature())
456 return MAPS_ERROR_NOT_SUPPORTED;
458 return MAPS_ERROR_INVALID_PARAMETER;
459 if ((transport_mode < MAPS_ROUTE_TRANSPORT_MODE_CAR) ||
460 (transport_mode > MAPS_ROUTE_TRANSPORT_MODE_TRUCK))
461 return MAPS_ERROR_INVALID_PARAMETER;
462 ((maps_route_s *) route)->transport_mode = transport_mode;
463 return MAPS_ERROR_NONE;
466 EXPORT_API int maps_route_set_path(maps_route_h route,
467 const maps_item_list_h path)
469 if (!maps_condition_check_maps_feature())
470 return MAPS_ERROR_NOT_SUPPORTED;
472 return MAPS_ERROR_INVALID_PARAMETER;
473 maps_route_s *p = (maps_route_s *) route;
475 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
476 maps_item_list_destroy(p->path);
478 maps_item_list_clone(path, maps_coordinates_clone, &p->path);
479 return MAPS_ERROR_NONE;
482 EXPORT_API int maps_route_set_segments(maps_route_h route,
483 const maps_item_list_h segments)
485 if (!maps_condition_check_maps_feature())
486 return MAPS_ERROR_NOT_SUPPORTED;
487 if (!route || !segments)
488 return MAPS_ERROR_INVALID_PARAMETER;
489 maps_route_s *p = (maps_route_s *) route;
491 maps_item_list_remove_all(p->segments,
492 maps_route_segment_destroy);
493 maps_item_list_destroy(p->segments);
495 maps_item_list_clone(segments, maps_route_segment_clone, &p->segments);
496 return MAPS_ERROR_NONE;
499 EXPORT_API int maps_route_set_properties(maps_route_h route,
500 const maps_item_hashtable_h properties)
502 if (!maps_condition_check_maps_feature())
503 return MAPS_ERROR_NOT_SUPPORTED;
504 if (!route || !properties)
505 return MAPS_ERROR_INVALID_PARAMETER;
506 maps_route_s *p = (maps_route_s *) route;
508 maps_item_hashtable_destroy(p->properties);
509 return maps_item_hashtable_clone(properties, &p->properties);
512 EXPORT_API int maps_route_set_distance_unit(maps_route_h route,
513 const maps_distance_unit_e distance_unit)
515 if (!maps_condition_check_maps_feature())
516 return MAPS_ERROR_NOT_SUPPORTED;
518 return MAPS_ERROR_INVALID_PARAMETER;
519 if ((distance_unit < MAPS_DISTANCE_UNIT_M) ||
520 (distance_unit > MAPS_DISTANCE_UNIT_YD))
521 return MAPS_ERROR_INVALID_PARAMETER;
522 ((maps_route_s *) route)->distance_unit = distance_unit;
523 return MAPS_ERROR_NONE;
526 int _maps_route_set_supported_data(maps_route_h route,
527 const maps_int_hashtable_h supported_data)
529 if (!route || !supported_data)
530 return MAPS_ERROR_INVALID_PARAMETER;
531 maps_route_s *p = (maps_route_s *) route;
532 if (p->supported_data)
533 maps_int_hashtable_destroy(p->supported_data);
535 maps_int_hashtable_clone(supported_data, &p->supported_data);
536 if (error != MAPS_ERROR_NONE)
540 error = maps_item_list_foreach(p->segments, NULL,
541 __maps_route_set_supported_data_foreach_cb, supported_data);