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);
82 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
83 return MAPS_ERROR_OUT_OF_MEMORY;
87 return MAPS_ERROR_NONE;
90 EXPORT_API int maps_route_destroy(maps_route_h route)
92 if (!maps_condition_check_maps_feature())
93 return MAPS_ERROR_NOT_SUPPORTED;
95 return MAPS_ERROR_INVALID_PARAMETER;
97 maps_route_s *p = (maps_route_s *) route;
102 maps_coordinates_destroy(p->origin);
104 maps_coordinates_destroy(p->destination);
106 maps_area_destroy(p->bounding_box);
108 maps_item_hashtable_destroy(p->properties);
111 maps_item_list_remove_all(p->segments,
112 maps_route_segment_destroy);
113 maps_item_list_destroy(p->segments);
117 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
118 maps_item_list_destroy(p->path);
121 if (p->supported_data)
122 maps_int_hashtable_destroy(p->supported_data);
124 g_slice_free(maps_route_s, route);
125 return MAPS_ERROR_NONE;
128 EXPORT_API int maps_route_clone(const maps_route_h origin,
129 maps_route_h *cloned)
131 if (!maps_condition_check_maps_feature())
132 return MAPS_ERROR_NOT_SUPPORTED;
133 if (!cloned || !origin)
134 return MAPS_ERROR_INVALID_PARAMETER;
136 int error = MAPS_ERROR_NONE;
138 error = maps_route_create(cloned);
139 if (!(*cloned) || (error != MAPS_ERROR_NONE))
142 maps_route_s *r = (maps_route_s *) origin;
145 error = maps_route_set_route_id(*cloned, r->route_id);
146 if (error != MAPS_ERROR_NONE)
151 error = maps_route_set_origin(*cloned, r->origin);
152 if (error != MAPS_ERROR_NONE)
156 if (r->destination) {
157 error = maps_route_set_destination(*cloned, r->destination);
158 if (error != MAPS_ERROR_NONE)
162 if (r->bounding_box) {
163 error = maps_route_set_bounding_box(*cloned, r->bounding_box);
164 if (error != MAPS_ERROR_NONE)
168 error = maps_route_set_transport_mode(*cloned, r->transport_mode);
169 if (error != MAPS_ERROR_NONE)
172 error = maps_route_set_total_distance(*cloned, r->total_distance);
173 if (error != MAPS_ERROR_NONE)
176 error = maps_route_set_total_duration(*cloned, r->total_duration);
177 if (error != MAPS_ERROR_NONE)
180 error = maps_route_set_distance_unit(*cloned, r->distance_unit);
181 if (error != MAPS_ERROR_NONE)
185 error = maps_route_set_segments(*cloned, r->segments);
186 if (error != MAPS_ERROR_NONE)
191 error = maps_route_set_path(*cloned, r->path);
192 if (error != MAPS_ERROR_NONE)
197 error = maps_route_set_properties(*cloned, r->properties);
198 if (error != MAPS_ERROR_NONE)
202 if (r->supported_data) {
203 error = _maps_route_set_supported_data(*cloned, r->supported_data);
204 if (error != MAPS_ERROR_NONE)
208 return MAPS_ERROR_NONE;
212 maps_route_destroy(*cloned);
218 /*----------------------------------------------------------------------------*/
220 EXPORT_API int maps_route_get_route_id(const maps_route_h route,
223 if (!maps_condition_check_maps_feature())
224 return MAPS_ERROR_NOT_SUPPORTED;
225 if (!route || !route_id)
226 return MAPS_ERROR_INVALID_PARAMETER;
227 return maps_get_string(((maps_route_s *) route)->route_id,
228 _MAPS_ROUTE_ID_MAX_LENGTH, route_id);
231 EXPORT_API int maps_route_get_origin(const maps_route_h route,
232 maps_coordinates_h *origin)
234 if (!maps_condition_check_maps_feature())
235 return MAPS_ERROR_NOT_SUPPORTED;
236 if (!route || !origin)
237 return MAPS_ERROR_INVALID_PARAMETER;
238 maps_coordinates_clone(((maps_route_s *) route)->origin, origin);
239 return MAPS_ERROR_NONE;
242 EXPORT_API int maps_route_get_destination(const maps_route_h route,
243 maps_coordinates_h *destination)
245 if (!maps_condition_check_maps_feature())
246 return MAPS_ERROR_NOT_SUPPORTED;
247 if (!route || !destination)
248 return MAPS_ERROR_INVALID_PARAMETER;
249 return maps_coordinates_clone(((maps_route_s *) route)->destination,
253 EXPORT_API int maps_route_get_bounding_box(const maps_route_h route,
254 maps_area_h *bounding_box)
256 if (!maps_condition_check_maps_feature())
257 return MAPS_ERROR_NOT_SUPPORTED;
258 if (!route || !bounding_box)
259 return MAPS_ERROR_INVALID_PARAMETER;
260 return maps_area_clone(((maps_route_s *) route)->bounding_box,
264 EXPORT_API int maps_route_get_transport_mode(const maps_route_h route,
265 maps_route_transport_mode_e *transport_mode)
267 if (!maps_condition_check_maps_feature())
268 return MAPS_ERROR_NOT_SUPPORTED;
269 if (!route || !transport_mode)
270 return MAPS_ERROR_INVALID_PARAMETER;
271 *transport_mode = ((maps_route_s *) route)->transport_mode;
272 return MAPS_ERROR_NONE;
275 EXPORT_API int maps_route_get_total_distance(const maps_route_h route,
276 double *total_distance)
278 if (!maps_condition_check_maps_feature())
279 return MAPS_ERROR_NOT_SUPPORTED;
280 if (!route || !total_distance)
281 return MAPS_ERROR_INVALID_PARAMETER;
282 *total_distance = ((maps_route_s *) route)->total_distance;
283 return MAPS_ERROR_NONE;
286 EXPORT_API int maps_route_get_total_duration(const maps_route_h route,
287 long *total_duration)
289 if (!maps_condition_check_maps_feature())
290 return MAPS_ERROR_NOT_SUPPORTED;
291 if (!route || !total_duration)
292 return MAPS_ERROR_INVALID_PARAMETER;
293 *total_duration = ((maps_route_s *) route)->total_duration;
294 return MAPS_ERROR_NONE;
297 EXPORT_API int maps_route_foreach_path(const maps_route_h route,
298 maps_route_path_cb callback,
301 if (!maps_condition_check_maps_feature())
302 return MAPS_ERROR_NOT_SUPPORTED;
304 return MAPS_ERROR_INVALID_PARAMETER;
305 if (!__is_supported(route, MAPS_ROUTE_PATH))
306 return MAPS_ERROR_NOT_SUPPORTED;
308 return MAPS_ERROR_INVALID_PARAMETER;
309 if (!((maps_route_s *) route)->path)
310 return MAPS_ERROR_NOT_FOUND;
312 return maps_item_list_foreach(((maps_route_s *) route)->path,
313 maps_coordinates_clone, callback, user_data);
316 EXPORT_API int maps_route_foreach_segment(const maps_route_h route,
317 maps_route_segment_cb callback,
320 if (!maps_condition_check_maps_feature())
321 return MAPS_ERROR_NOT_SUPPORTED;
323 return MAPS_ERROR_INVALID_PARAMETER;
324 if (!__is_supported(route, MAPS_ROUTE_SEGMENTS_PATH)
325 && !__is_supported(route, MAPS_ROUTE_SEGMENTS_MANEUVERS))
326 return MAPS_ERROR_NOT_SUPPORTED;
328 return MAPS_ERROR_INVALID_PARAMETER;
329 if (!((maps_route_s *) route)->segments)
330 return MAPS_ERROR_NOT_FOUND;
332 return maps_item_list_foreach(((maps_route_s *) route)->segments,
333 maps_route_segment_clone, callback, user_data);
336 EXPORT_API int maps_route_foreach_property(const maps_route_h route,
337 maps_route_properties_cb callback,
340 if (!maps_condition_check_maps_feature())
341 return MAPS_ERROR_NOT_SUPPORTED;
342 if (!route || !callback)
343 return MAPS_ERROR_INVALID_PARAMETER;
344 if (!((maps_route_s *) route)->properties)
345 return MAPS_ERROR_NOT_FOUND;
346 return maps_item_hashtable_foreach(((maps_route_s *) route)->properties,
347 callback, user_data);
350 EXPORT_API int maps_route_get_distance_unit(const maps_route_h route,
351 maps_distance_unit_e *distance_unit)
353 if (!maps_condition_check_maps_feature())
354 return MAPS_ERROR_NOT_SUPPORTED;
355 if (!route || !distance_unit)
356 return MAPS_ERROR_INVALID_PARAMETER;
357 *distance_unit = ((maps_route_s *) route)->distance_unit;
358 return MAPS_ERROR_NONE;
361 int _maps_route_is_data_supported(const maps_route_h route,
362 maps_service_data_e data, bool *supported)
364 if (!maps_condition_check_maps_feature())
365 return MAPS_ERROR_NOT_SUPPORTED;
366 if (!route || !supported)
367 return MAPS_ERROR_INVALID_PARAMETER;
369 maps_route_s *r = (maps_route_s *)route;
371 if (!r->supported_data) {
372 /* This is a case when the "supported" flags are not set yet */
373 /* No need to limit access to fields */
375 return MAPS_ERROR_NONE;
379 return maps_int_hashtable_contains(r->supported_data, data, supported);
382 /*----------------------------------------------------------------------------*/
384 EXPORT_API int maps_route_set_route_id(const maps_route_h route,
385 const char *route_id)
387 if (!maps_condition_check_maps_feature())
388 return MAPS_ERROR_NOT_SUPPORTED;
389 if (!route || !route_id)
390 return MAPS_ERROR_INVALID_PARAMETER;
391 return maps_set_string(route_id, _MAPS_ROUTE_ID_MAX_LENGTH,
392 &((maps_route_s *) route)->route_id);
395 EXPORT_API int maps_route_set_origin(maps_route_h route,
396 const maps_coordinates_h origin)
398 if (!maps_condition_check_maps_feature())
399 return MAPS_ERROR_NOT_SUPPORTED;
400 if (!route || !origin)
401 return MAPS_ERROR_INVALID_PARAMETER;
402 maps_route_s *p = (maps_route_s *) route;
404 maps_coordinates_destroy(p->origin);
405 return maps_coordinates_clone(origin, &p->origin);
408 EXPORT_API int maps_route_set_destination(maps_route_h route,
409 const maps_coordinates_h destination)
411 if (!maps_condition_check_maps_feature())
412 return MAPS_ERROR_NOT_SUPPORTED;
413 if (!route || !destination)
414 return MAPS_ERROR_INVALID_PARAMETER;
415 maps_route_s *p = (maps_route_s *) route;
417 maps_coordinates_destroy(p->destination);
418 return maps_coordinates_clone(destination, &p->destination);
421 EXPORT_API int maps_route_set_bounding_box(maps_route_h route,
422 const maps_area_h bounding_box)
424 if (!maps_condition_check_maps_feature())
425 return MAPS_ERROR_NOT_SUPPORTED;
426 if (!route || !bounding_box)
427 return MAPS_ERROR_INVALID_PARAMETER;
428 maps_route_s *p = (maps_route_s *) route;
430 maps_area_destroy(p->bounding_box);
431 return maps_area_clone(bounding_box, &p->bounding_box);
434 EXPORT_API int maps_route_set_total_distance(maps_route_h route,
435 const double total_distance)
437 if (!maps_condition_check_maps_feature())
438 return MAPS_ERROR_NOT_SUPPORTED;
439 if (!route || total_distance < 0)
440 return MAPS_ERROR_INVALID_PARAMETER;
441 ((maps_route_s *) route)->total_distance = total_distance;
442 return MAPS_ERROR_NONE;
445 EXPORT_API int maps_route_set_total_duration(maps_route_h route,
446 const long total_duration)
448 if (!maps_condition_check_maps_feature())
449 return MAPS_ERROR_NOT_SUPPORTED;
450 if (!route || total_duration < 0)
451 return MAPS_ERROR_INVALID_PARAMETER;
452 ((maps_route_s *) route)->total_duration = total_duration;
453 return MAPS_ERROR_NONE;
456 EXPORT_API int maps_route_set_transport_mode(maps_route_h route,
457 const maps_route_transport_mode_e transport_mode)
459 if (!maps_condition_check_maps_feature())
460 return MAPS_ERROR_NOT_SUPPORTED;
462 return MAPS_ERROR_INVALID_PARAMETER;
463 if ((transport_mode < MAPS_ROUTE_TRANSPORT_MODE_CAR) ||
464 (transport_mode > MAPS_ROUTE_TRANSPORT_MODE_TRUCK))
465 return MAPS_ERROR_INVALID_PARAMETER;
466 ((maps_route_s *) route)->transport_mode = transport_mode;
467 return MAPS_ERROR_NONE;
470 EXPORT_API int maps_route_set_path(maps_route_h route,
471 const maps_item_list_h path)
473 if (!maps_condition_check_maps_feature())
474 return MAPS_ERROR_NOT_SUPPORTED;
476 return MAPS_ERROR_INVALID_PARAMETER;
477 maps_route_s *p = (maps_route_s *) route;
479 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
480 maps_item_list_destroy(p->path);
482 maps_item_list_clone(path, maps_coordinates_clone, &p->path);
483 return MAPS_ERROR_NONE;
486 EXPORT_API int maps_route_set_segments(maps_route_h route,
487 const maps_item_list_h segments)
489 if (!maps_condition_check_maps_feature())
490 return MAPS_ERROR_NOT_SUPPORTED;
491 if (!route || !segments)
492 return MAPS_ERROR_INVALID_PARAMETER;
493 maps_route_s *p = (maps_route_s *) route;
495 maps_item_list_remove_all(p->segments,
496 maps_route_segment_destroy);
497 maps_item_list_destroy(p->segments);
499 maps_item_list_clone(segments, maps_route_segment_clone, &p->segments);
500 return MAPS_ERROR_NONE;
503 EXPORT_API int maps_route_set_properties(maps_route_h route,
504 const maps_item_hashtable_h properties)
506 if (!maps_condition_check_maps_feature())
507 return MAPS_ERROR_NOT_SUPPORTED;
508 if (!route || !properties)
509 return MAPS_ERROR_INVALID_PARAMETER;
510 maps_route_s *p = (maps_route_s *) route;
512 maps_item_hashtable_destroy(p->properties);
513 return maps_item_hashtable_clone(properties, &p->properties);
516 EXPORT_API int maps_route_set_distance_unit(maps_route_h route,
517 const maps_distance_unit_e distance_unit)
519 if (!maps_condition_check_maps_feature())
520 return MAPS_ERROR_NOT_SUPPORTED;
522 return MAPS_ERROR_INVALID_PARAMETER;
523 if ((distance_unit < MAPS_DISTANCE_UNIT_M) ||
524 (distance_unit > MAPS_DISTANCE_UNIT_YD))
525 return MAPS_ERROR_INVALID_PARAMETER;
526 ((maps_route_s *) route)->distance_unit = distance_unit;
527 return MAPS_ERROR_NONE;
530 int _maps_route_set_supported_data(maps_route_h route,
531 const maps_int_hashtable_h supported_data)
533 if (!route || !supported_data)
534 return MAPS_ERROR_INVALID_PARAMETER;
535 maps_route_s *p = (maps_route_s *) route;
536 if (p->supported_data)
537 maps_int_hashtable_destroy(p->supported_data);
539 maps_int_hashtable_clone(supported_data, &p->supported_data);
540 if (error != MAPS_ERROR_NONE)
544 error = maps_item_list_foreach(p->segments, NULL,
545 __maps_route_set_supported_data_foreach_cb, supported_data);