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"
26 static bool __is_supported(const maps_route_h route, maps_service_data_e data)
28 bool supported = false;
29 _maps_route_is_data_supported(route, data, &supported);
33 static bool __maps_route_set_supported_data_foreach_cb(int index, int total,
37 _maps_route_segment_set_supported_data(data, user_data);
41 static int __maps_route_set_supported_data_clone_cb(void *origin, void **cloned)
43 *cloned = origin; /* No clonning, please */
44 return MAPS_ERROR_NONE;
47 /*----------------------------------------------------------------------------*/
52 typedef struct _maps_route_s
54 char *route_id; /*< route_id */
55 maps_coordinates_h origin; /*< Coordinate StartCoord */
56 maps_coordinates_h destination; /*< Coordinates destCoord */
57 maps_area_h bounding_box; /*< A rectangular geographical area */
58 maps_route_transport_mode_e transport_mode; /*< The transport mode
60 double total_distance; /*< Total distance */
61 long total_duration; /*< Total duration */
62 maps_distance_unit_e distance_unit; /*< Distance units */
63 maps_item_list_h segments; /*< List of segments,
64 maps_route_segment_h */
65 maps_item_list_h path; /*< Path, list of maps_coordinates_h */
66 maps_item_hashtable_h properties; /*< Key/Value> */
68 /* The table of available data features */
69 maps_string_hashtable_h supported_data;
70 /* TODO: implement hashtable<int, int> */
73 const gsize _MAPS_ROUTE_ID_MAX_LENGTH = 32;
75 /*----------------------------------------------------------------------------*/
77 EXPORT_API int maps_route_create(maps_route_h *route)
80 return MAPS_ERROR_INVALID_PARAMETER;
81 *route = (maps_route_h) g_slice_new0(maps_route_s);
84 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
85 return MAPS_ERROR_OUT_OF_MEMORY;
88 return MAPS_ERROR_NONE;
91 EXPORT_API int maps_route_destroy(maps_route_h route)
94 return MAPS_ERROR_INVALID_PARAMETER;
96 maps_route_s *p = (maps_route_s *) route;
101 maps_coordinates_destroy(p->origin);
103 maps_coordinates_destroy(p->destination);
105 maps_area_destroy(p->bounding_box);
107 maps_item_hashtable_destroy(p->properties);
110 maps_item_list_remove_all(p->segments,
111 maps_route_segment_destroy);
112 maps_item_list_destroy(p->segments);
116 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
117 maps_item_list_destroy(p->path);
120 if (p->supported_data)
121 maps_item_hashtable_destroy(p->supported_data);
123 g_slice_free(maps_route_s, route);
124 return MAPS_ERROR_NONE;
127 EXPORT_API int maps_route_clone(const maps_route_h origin,
128 maps_route_h *cloned)
130 if (!cloned || !origin)
131 return MAPS_ERROR_INVALID_PARAMETER;
133 int error = MAPS_ERROR_NONE;
135 error = maps_route_create(cloned);
136 if (!(*cloned) || (error != MAPS_ERROR_NONE))
139 maps_route_s *r = (maps_route_s *) origin;
142 error = maps_route_set_route_id(*cloned, r->route_id);
143 if (error != MAPS_ERROR_NONE)
148 error = maps_route_set_origin(*cloned, r->origin);
149 if (error != MAPS_ERROR_NONE)
153 if (r->destination) {
154 error = maps_route_set_destination(*cloned,
156 if (error != MAPS_ERROR_NONE)
160 if (r->bounding_box) {
161 error = maps_route_set_bounding_box(*cloned,
163 if (error != MAPS_ERROR_NONE)
167 error = maps_route_set_transport_mode(*cloned,
169 if (error != MAPS_ERROR_NONE)
172 error = maps_route_set_total_distance(*cloned,
174 if (error != MAPS_ERROR_NONE)
177 error = maps_route_set_total_duration(*cloned,
179 if (error != MAPS_ERROR_NONE)
182 error = maps_route_set_distance_unit(*cloned, r->distance_unit);
183 if (error != MAPS_ERROR_NONE)
187 error = maps_route_set_segments(*cloned, r->segments);
188 if (error != MAPS_ERROR_NONE)
193 error = maps_route_set_path(*cloned, r->path);
194 if (error != MAPS_ERROR_NONE)
199 error = maps_route_set_properties(*cloned,
201 if (error != MAPS_ERROR_NONE)
205 if (r->supported_data) {
206 error = _maps_route_set_supported_data(*cloned,
208 if (error != MAPS_ERROR_NONE)
212 return MAPS_ERROR_NONE;
215 maps_route_destroy(*cloned);
220 /*----------------------------------------------------------------------------*/
222 EXPORT_API int maps_route_get_route_id(const maps_route_h route,
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 (!route || !origin)
235 return MAPS_ERROR_INVALID_PARAMETER;
236 maps_coordinates_clone(((maps_route_s *) route)->origin, origin);
237 return MAPS_ERROR_NONE;
240 EXPORT_API int maps_route_get_destination(const maps_route_h route,
241 maps_coordinates_h *destination)
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 (!route || !bounding_box)
253 return MAPS_ERROR_INVALID_PARAMETER;
254 return maps_area_clone(((maps_route_s *) route)->bounding_box,
258 EXPORT_API int maps_route_get_transport_mode(const maps_route_h route,
259 maps_route_transport_mode_e *
262 if (!route || !transport_mode)
263 return MAPS_ERROR_INVALID_PARAMETER;
264 *transport_mode = ((maps_route_s *) route)->transport_mode;
265 return MAPS_ERROR_NONE;
268 EXPORT_API int maps_route_get_total_distance(const maps_route_h route,
269 double *total_distance)
271 if (!route || !total_distance)
272 return MAPS_ERROR_INVALID_PARAMETER;
273 *total_distance = ((maps_route_s *) route)->total_distance;
274 return MAPS_ERROR_NONE;
277 EXPORT_API int maps_route_get_total_duration(const maps_route_h route,
278 long *total_duration)
280 if (!route || !total_duration)
281 return MAPS_ERROR_INVALID_PARAMETER;
282 *total_duration = ((maps_route_s *) route)->total_duration;
283 return MAPS_ERROR_NONE;
286 EXPORT_API int maps_route_foreach_path(const maps_route_h route,
287 maps_route_path_cb callback,
290 /* Check if the handle of the Route is valid */
292 return MAPS_ERROR_INVALID_PARAMETER;
294 /* Check if this API feature available */
295 if (!__is_supported(route, MAPS_ROUTE_PATH))
296 return MAPS_ERROR_NOT_SUPPORTED;
298 /* Check if parameters are valid */
300 return MAPS_ERROR_INVALID_PARAMETER;
302 return maps_item_list_foreach(((maps_route_s *) route)->path,
303 maps_coordinates_clone, callback, user_data);
306 EXPORT_API int maps_route_foreach_segment(const maps_route_h route,
307 maps_route_segment_cb callback,
310 /* Check if the handle of the Route is valid */
312 return MAPS_ERROR_INVALID_PARAMETER;
314 /* Check if this API feature available */
315 if (!__is_supported(route, MAPS_ROUTE_SEGMENTS_PATH)
316 && !__is_supported(route, MAPS_ROUTE_SEGMENTS_MANEUVERS))
317 return MAPS_ERROR_NOT_SUPPORTED;
319 /* Check if parameters are valid */
321 return MAPS_ERROR_INVALID_PARAMETER;
323 return maps_item_list_foreach(((maps_route_s *) route)->segments,
324 maps_route_segment_clone, callback, user_data);
327 EXPORT_API int maps_route_foreach_property(const maps_route_h route,
328 maps_route_properties_cb callback,
331 if (!route || !callback)
332 return MAPS_ERROR_INVALID_PARAMETER;
333 return maps_item_hashtable_foreach(((maps_route_s *) route)->properties,
334 callback, user_data);
337 EXPORT_API int maps_route_get_distance_unit(const maps_route_h route,
338 maps_distance_unit_e *distance_unit)
340 if (!route || !distance_unit)
341 return MAPS_ERROR_INVALID_PARAMETER;
342 *distance_unit = ((maps_route_s *) route)->distance_unit;
343 return MAPS_ERROR_NONE;
346 int _maps_route_is_data_supported(const maps_route_h route,
347 maps_service_data_e data, bool *supported)
349 if (!route || !supported)
350 return MAPS_ERROR_INVALID_PARAMETER;
352 if (!((maps_route_s *) route)->supported_data) {
353 /* This is a case when the "supported" flags are not set yet */
354 /* No need to limit access to fields */
356 return MAPS_ERROR_NONE;
362 case MAPS_ROUTE_PATH:
363 data_feature = _S(MAPS_ROUTE_PATH);
365 case MAPS_ROUTE_SEGMENTS_PATH:
366 data_feature = _S(MAPS_ROUTE_SEGMENTS_PATH);
368 case MAPS_ROUTE_SEGMENTS_MANEUVERS:
369 data_feature = _S(MAPS_ROUTE_SEGMENTS_MANEUVERS);
372 return MAPS_ERROR_NOT_SUPPORTED;
374 return maps_string_hashtable_contains(((maps_route_s *) route)->
375 supported_data, data_feature.c_str(), supported);
378 /*----------------------------------------------------------------------------*/
380 EXPORT_API int maps_route_set_route_id(const maps_route_h route,
381 const char *route_id)
383 if (!route || !route_id)
384 return MAPS_ERROR_INVALID_PARAMETER;
385 return maps_set_string(route_id, _MAPS_ROUTE_ID_MAX_LENGTH,
386 &((maps_route_s *) route)->route_id);
389 EXPORT_API int maps_route_set_origin(maps_route_h route,
390 const maps_coordinates_h origin)
392 if (!route || !origin)
393 return MAPS_ERROR_INVALID_PARAMETER;
394 maps_route_s *p = (maps_route_s *) route;
396 maps_coordinates_destroy(p->origin);
397 return maps_coordinates_clone(origin, &p->origin);
400 EXPORT_API int maps_route_set_destination(maps_route_h route,
401 const maps_coordinates_h destination)
403 if (!route || !destination)
404 return MAPS_ERROR_INVALID_PARAMETER;
405 maps_route_s *p = (maps_route_s *) route;
407 maps_coordinates_destroy(p->destination);
408 return maps_coordinates_clone(destination, &p->destination);
411 EXPORT_API int maps_route_set_bounding_box(maps_route_h route,
412 const maps_area_h bounding_box)
414 if (!route || !bounding_box)
415 return MAPS_ERROR_INVALID_PARAMETER;
416 maps_route_s *p = (maps_route_s *) route;
418 maps_area_destroy(p->bounding_box);
419 return maps_area_clone(bounding_box, &p->bounding_box);
422 EXPORT_API int maps_route_set_total_distance(maps_route_h route,
423 const double total_distance)
425 if (!route || total_distance < 0)
426 return MAPS_ERROR_INVALID_PARAMETER;
427 ((maps_route_s *) route)->total_distance = total_distance;
428 return MAPS_ERROR_NONE;
431 EXPORT_API int maps_route_set_total_duration(maps_route_h route,
432 const long total_duration)
434 if (!route || total_duration < 0)
435 return MAPS_ERROR_INVALID_PARAMETER;
436 ((maps_route_s *) route)->total_duration = total_duration;
437 return MAPS_ERROR_NONE;
440 EXPORT_API int maps_route_set_transport_mode(maps_route_h route,
441 const maps_route_transport_mode_e
445 return MAPS_ERROR_INVALID_PARAMETER;
446 if ((transport_mode < MAPS_ROUTE_TRANSPORT_MODE_CAR) ||
447 (transport_mode > MAPS_ROUTE_TRANSPORT_MODE_TRUCK))
448 return MAPS_ERROR_INVALID_PARAMETER;
449 ((maps_route_s *) route)->transport_mode = transport_mode;
450 return MAPS_ERROR_NONE;
453 EXPORT_API int maps_route_set_path(maps_route_h route,
454 const maps_item_list_h path)
457 return MAPS_ERROR_INVALID_PARAMETER;
458 maps_route_s *p = (maps_route_s *) route;
460 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
461 maps_item_list_destroy(p->path);
463 maps_item_list_clone(path, maps_coordinates_clone, &p->path);
464 return MAPS_ERROR_NONE;
467 EXPORT_API int maps_route_set_segments(maps_route_h route,
468 const maps_item_list_h segments)
470 if (!route || !segments)
471 return MAPS_ERROR_INVALID_PARAMETER;
472 maps_route_s *p = (maps_route_s *) route;
474 maps_item_list_remove_all(p->segments,
475 maps_route_segment_destroy);
476 maps_item_list_destroy(p->segments);
478 maps_item_list_clone(segments, maps_route_segment_clone, &p->segments);
479 return MAPS_ERROR_NONE;
482 EXPORT_API int maps_route_set_properties(maps_route_h route,
483 const maps_item_hashtable_h properties)
485 if (!route || !properties)
486 return MAPS_ERROR_INVALID_PARAMETER;
487 maps_route_s *p = (maps_route_s *) route;
489 maps_item_hashtable_destroy(p->properties);
490 return maps_item_hashtable_clone(properties, &p->properties);
493 EXPORT_API int maps_route_set_distance_unit(maps_route_h route,
494 const maps_distance_unit_e
498 return MAPS_ERROR_INVALID_PARAMETER;
499 if ((distance_unit < MAPS_DISTANCE_UNIT_M) ||
500 (distance_unit > MAPS_DISTANCE_UNIT_YD))
501 return MAPS_ERROR_INVALID_PARAMETER;
502 ((maps_route_s *) route)->distance_unit = distance_unit;
503 return MAPS_ERROR_NONE;
506 int _maps_route_set_supported_data(maps_route_h route,
507 const maps_string_hashtable_h supported_data)
509 if (!route || !supported_data)
510 return MAPS_ERROR_INVALID_PARAMETER;
511 maps_route_s *p = (maps_route_s *) route;
512 if (p->supported_data)
513 maps_string_hashtable_destroy(p->supported_data);
515 maps_string_hashtable_clone(supported_data, &p->supported_data);
516 if (error != MAPS_ERROR_NONE)
522 return maps_item_list_foreach(p->segments,
523 __maps_route_set_supported_data_clone_cb,
524 __maps_route_set_supported_data_foreach_cb, supported_data);