0e1e5f07bd334bc75089ac8a07cf302cc490e6e4
[platform/core/api/maps-service.git] / src / api / maps_route_segment.cpp
1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
2  *
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 <glib.h>
18 #include "maps_error.h"
19 #include "maps_route_segment_plugin.h"
20 #include "maps_route_maneuver_plugin.h"
21 #include "maps_extra_types.h"
22 #include "maps_util.h"
23 #include "maps_route_segment_private.h"
24 #include "maps_condition.h"
25
26 static bool __is_supported(const maps_route_segment_h route_segment,
27                                                                 maps_service_data_e data)
28 {
29         bool supported = false;
30         _maps_route_segment_is_data_supported(route_segment, data, &supported);
31         return supported;
32 }
33
34 /*----------------------------------------------------------------------------*/
35
36 typedef struct _maps_route_segment_s
37 {
38         maps_coordinates_h origin;
39         maps_coordinates_h destination;
40         maps_area_h bounding_box;
41         double distance;
42         long duration;
43         maps_item_list_h path;  /*< path, list of maps_coordinates_h */
44         maps_item_list_h maneuvers;     /*< list of maneuvers,
45                                           maps_route_maneuver_h */
46
47         /* The table of available data features */
48         maps_int_hashtable_h supported_data;
49 } maps_route_segment_s;
50
51 /*----------------------------------------------------------------------------*/
52
53 EXPORT_API int maps_route_segment_create(maps_route_segment_h *segment)
54 {
55         if (!maps_condition_check_maps_feature())
56                 return MAPS_ERROR_NOT_SUPPORTED;
57         if (!segment)
58                 return MAPS_ERROR_INVALID_PARAMETER;
59         *segment = (maps_route_segment_h) g_slice_new0(maps_route_segment_s);
60
61         if (*segment == NULL) {
62                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
63                 return MAPS_ERROR_OUT_OF_MEMORY;
64         }
65
66         return MAPS_ERROR_NONE;
67 }
68
69 EXPORT_API int maps_route_segment_destroy(maps_route_segment_h segment)
70 {
71         if (!maps_condition_check_maps_feature())
72                 return MAPS_ERROR_NOT_SUPPORTED;
73         if (!segment)
74                 return MAPS_ERROR_INVALID_PARAMETER;
75
76         maps_route_segment_s *p = (maps_route_segment_s *) segment;
77
78         if (p->origin)
79                 maps_coordinates_destroy(p->origin);
80         if (p->destination)
81                 maps_coordinates_destroy(p->destination);
82         if (p->bounding_box)
83                 maps_area_destroy(p->bounding_box);
84         if (p->path) {
85                 maps_item_list_remove_all(p->path, maps_coordinates_destroy);
86                 maps_item_list_destroy(p->path);
87         }
88         if (p->maneuvers) {
89                 maps_item_list_remove_all(p->maneuvers, maps_route_maneuver_destroy);
90                 maps_item_list_destroy(p->maneuvers);
91         }
92
93         if (p->supported_data)
94                 maps_int_hashtable_destroy(p->supported_data);
95
96         g_slice_free(maps_route_segment_s, segment);
97         return MAPS_ERROR_NONE;
98 }
99
100 EXPORT_API int maps_route_segment_clone(const maps_route_segment_h segment,
101                                                                 maps_route_segment_h *cloned)
102 {
103         if (!maps_condition_check_maps_feature())
104                 return MAPS_ERROR_NOT_SUPPORTED;
105         if (!cloned || !segment)
106                 return MAPS_ERROR_INVALID_PARAMETER;
107
108         int error = MAPS_ERROR_NONE;
109         do {
110                 error = maps_route_segment_create(cloned);
111                 if (!(*cloned) || (error != MAPS_ERROR_NONE))
112                         break;
113
114                 maps_route_segment_s *p = (maps_route_segment_s *) segment;
115
116                 if (p->origin) {
117                         error = maps_route_segment_set_origin(*cloned, p->origin);
118                         if (error != MAPS_ERROR_NONE)
119                                 break;
120                 }
121
122                 if (p->destination) {
123                         error = maps_route_segment_set_destination(*cloned, p->destination);
124                         if (error != MAPS_ERROR_NONE)
125                                 break;
126                 }
127
128                 if (p->bounding_box) {
129                         error = maps_route_segment_set_bounding_box(*cloned, p->bounding_box);
130                         if (error != MAPS_ERROR_NONE)
131                                 break;
132                 }
133
134                 error = maps_route_segment_set_distance(*cloned, p->distance);
135                 if (error != MAPS_ERROR_NONE)
136                         break;
137
138                 error = maps_route_segment_set_duration(*cloned, p->duration);
139                 if (error != MAPS_ERROR_NONE)
140                         break;
141
142                 if (p->path) {
143                         error = maps_route_segment_set_path(*cloned, p->path);
144                         if (error != MAPS_ERROR_NONE)
145                                 break;
146                 }
147
148                 if (p->maneuvers) {
149                         error = maps_route_segment_set_maneuvers(*cloned, p->maneuvers);
150                         if (error != MAPS_ERROR_NONE)
151                                 break;
152                 }
153
154                 if (p->supported_data) {
155                         error = _maps_route_segment_set_supported_data(*cloned, p->supported_data);
156                         if (error != MAPS_ERROR_NONE)
157                                 break;
158                 }
159
160                 return MAPS_ERROR_NONE;
161         } while (false);
162
163         maps_route_segment_destroy(*cloned);
164         *cloned = NULL;
165         return error;
166 }
167
168 /*----------------------------------------------------------------------------*/
169
170 EXPORT_API int maps_route_segment_get_origin(const maps_route_segment_h segment,
171                                                                 maps_coordinates_h *origin)
172 {
173         if (!maps_condition_check_maps_feature())
174                 return MAPS_ERROR_NOT_SUPPORTED;
175         if (!segment || !origin)
176                 return MAPS_ERROR_INVALID_PARAMETER;
177         if (!((maps_route_segment_s *) segment)->origin)
178                 return MAPS_ERROR_NOT_FOUND;
179         return maps_coordinates_clone(((maps_route_segment_s *) segment)->origin, origin);
180 }
181
182 EXPORT_API int maps_route_segment_get_destination(const maps_route_segment_h segment,
183                                                                 maps_coordinates_h *destination)
184 {
185         if (!maps_condition_check_maps_feature())
186                 return MAPS_ERROR_NOT_SUPPORTED;
187         if (!segment || !destination)
188                 return MAPS_ERROR_INVALID_PARAMETER;
189         if (!((maps_route_segment_s *) segment)->destination)
190                 return MAPS_ERROR_NOT_FOUND;
191         return maps_coordinates_clone(((maps_route_segment_s *) segment)->destination, destination);
192 }
193
194 EXPORT_API int maps_route_segment_get_bounding_box(const maps_route_segment_h segment,
195                                                                 maps_area_h *bounding_box)
196 {
197         if (!maps_condition_check_maps_feature())
198                 return MAPS_ERROR_NOT_SUPPORTED;
199         if (!segment || !bounding_box)
200                 return MAPS_ERROR_INVALID_PARAMETER;
201         if (!((maps_route_segment_s *) segment)->bounding_box)
202                 return MAPS_ERROR_NOT_FOUND;
203         return maps_area_clone(((maps_route_segment_s *) segment)->bounding_box, bounding_box);
204 }
205
206 EXPORT_API int maps_route_segment_get_distance(const maps_route_segment_h segment,
207                                                                 double *distance)
208 {
209         if (!maps_condition_check_maps_feature())
210                 return MAPS_ERROR_NOT_SUPPORTED;
211         if (!segment || !distance)
212                 return MAPS_ERROR_INVALID_PARAMETER;
213         *distance = ((maps_route_segment_s *) segment)->distance;
214         return MAPS_ERROR_NONE;
215 }
216
217 EXPORT_API int maps_route_segment_get_duration(const maps_route_segment_h segment,
218                                                                 long *duration)
219 {
220         if (!maps_condition_check_maps_feature())
221                 return MAPS_ERROR_NOT_SUPPORTED;
222         if (!segment || !duration)
223                 return MAPS_ERROR_INVALID_PARAMETER;
224         *duration = ((maps_route_segment_s *) segment)->duration;
225         return MAPS_ERROR_NONE;
226 }
227
228 EXPORT_API int maps_route_segment_foreach_path(const maps_route_segment_h segment,
229                                                                 maps_route_segment_path_cb callback,
230                                                                 void *user_data)
231 {
232         if (!maps_condition_check_maps_feature())
233                 return MAPS_ERROR_NOT_SUPPORTED;
234         if (!segment)
235                 return MAPS_ERROR_INVALID_PARAMETER;
236         if (!__is_supported(segment, MAPS_ROUTE_SEGMENTS_PATH))
237                 return MAPS_ERROR_NOT_SUPPORTED;
238         if (!callback)
239                 return MAPS_ERROR_INVALID_PARAMETER;
240         if (!((maps_route_segment_s *) segment)->path)
241                 return MAPS_ERROR_NOT_FOUND;
242
243         return maps_item_list_foreach(((maps_route_segment_s *) segment)->path,
244                 maps_coordinates_clone, callback, user_data);
245 }
246
247 EXPORT_API int maps_route_segment_foreach_maneuver(const maps_route_segment_h segment,
248                                                                 maps_route_segment_maneuver_cb callback,
249                                                                 void *user_data)
250 {
251         if (!maps_condition_check_maps_feature())
252                 return MAPS_ERROR_NOT_SUPPORTED;
253         if (!segment)
254                 return MAPS_ERROR_INVALID_PARAMETER;
255         if (!__is_supported(segment, MAPS_ROUTE_SEGMENTS_MANEUVERS))
256                 return MAPS_ERROR_NOT_SUPPORTED;
257         if (!callback)
258                 return MAPS_ERROR_INVALID_PARAMETER;
259         if (!((maps_route_segment_s *) segment)->maneuvers)
260                 return MAPS_ERROR_NOT_FOUND;
261
262         return maps_item_list_foreach(((maps_route_segment_s *) segment)->maneuvers,
263                 maps_route_maneuver_clone, callback, user_data);
264 }
265
266 int _maps_route_segment_is_data_supported(const maps_route_segment_h segment,
267                                                                 maps_service_data_e data,
268                                                                 bool *supported)
269 {
270         if (!segment || !supported)
271                 return MAPS_ERROR_INVALID_PARAMETER;
272
273         maps_route_segment_s *s = (maps_route_segment_s *)segment;
274         if (!s->supported_data) {
275                 /* This is a case when the "supported" flags are not set yet */
276                 /* No need to limit access to fields */
277                 *supported = true;
278                 return MAPS_ERROR_NONE;
279         }
280
281         *supported = false;
282         return maps_int_hashtable_contains(s->supported_data, data, supported);
283 }
284
285 /*----------------------------------------------------------------------------*/
286
287 EXPORT_API int maps_route_segment_set_origin(maps_route_segment_h segment,
288                                                                 const maps_coordinates_h origin)
289 {
290         if (!maps_condition_check_maps_feature())
291                 return MAPS_ERROR_NOT_SUPPORTED;
292         if (!segment || !origin)
293                 return MAPS_ERROR_INVALID_PARAMETER;
294         maps_route_segment_s *p = (maps_route_segment_s *) segment;
295         if (p->origin)
296                 maps_coordinates_destroy(p->origin);
297         return maps_coordinates_clone(origin, &p->origin);
298 }
299
300 EXPORT_API int maps_route_segment_set_destination(maps_route_segment_h segment,
301                                                                 const maps_coordinates_h destination)
302 {
303         if (!maps_condition_check_maps_feature())
304                 return MAPS_ERROR_NOT_SUPPORTED;
305         if (!segment || !destination)
306                 return MAPS_ERROR_INVALID_PARAMETER;
307         maps_route_segment_s *p = (maps_route_segment_s *) segment;
308         if (p->destination)
309                 maps_coordinates_destroy(p->destination);
310         return maps_coordinates_clone(destination, &p->destination);
311 }
312
313 EXPORT_API int maps_route_segment_set_bounding_box(maps_route_segment_h segment,
314                                                                 const maps_area_h bounding_box)
315 {
316         if (!maps_condition_check_maps_feature())
317                 return MAPS_ERROR_NOT_SUPPORTED;
318         if (!segment || !bounding_box)
319                 return MAPS_ERROR_INVALID_PARAMETER;
320         maps_route_segment_s *p = (maps_route_segment_s *) segment;
321         if (p->bounding_box)
322                 maps_area_destroy(p->bounding_box);
323         return maps_area_clone(bounding_box, &p->bounding_box);
324 }
325
326 EXPORT_API int maps_route_segment_set_distance(maps_route_segment_h segment,
327                                                                 const double distance)
328 {
329         if (!maps_condition_check_maps_feature())
330                 return MAPS_ERROR_NOT_SUPPORTED;
331         if (!segment || distance < 0)
332                 return MAPS_ERROR_INVALID_PARAMETER;
333         ((maps_route_segment_s *) segment)->distance = distance;
334         return MAPS_ERROR_NONE;
335 }
336
337 EXPORT_API int maps_route_segment_set_duration(maps_route_segment_h segment,
338                                                                 const long duration)
339 {
340         if (!maps_condition_check_maps_feature())
341                 return MAPS_ERROR_NOT_SUPPORTED;
342         if (!segment || duration < 0)
343                 return MAPS_ERROR_INVALID_PARAMETER;
344         ((maps_route_segment_s *) segment)->duration = duration;
345         return MAPS_ERROR_NONE;
346 }
347
348 EXPORT_API int maps_route_segment_set_path(maps_route_segment_h segment,
349                                                                 const maps_item_list_h path)
350 {
351         if (!maps_condition_check_maps_feature())
352                 return MAPS_ERROR_NOT_SUPPORTED;
353         if (!segment || !path)
354                 return MAPS_ERROR_INVALID_PARAMETER;
355         maps_route_segment_s *s = (maps_route_segment_s *) segment;
356         if (s->path) {
357                 maps_item_list_remove_all(s->path, maps_coordinates_destroy);
358                 maps_item_list_destroy(s->path);
359         }
360         maps_item_list_clone(path, maps_coordinates_clone, &s->path);
361         return MAPS_ERROR_NONE;
362 }
363
364 EXPORT_API int maps_route_segment_set_maneuvers(maps_route_segment_h segment,
365                                                                 const maps_item_list_h maneuvers)
366 {
367         if (!maps_condition_check_maps_feature())
368                 return MAPS_ERROR_NOT_SUPPORTED;
369         if (!segment || !maneuvers)
370                 return MAPS_ERROR_INVALID_PARAMETER;
371         maps_route_segment_s *s = (maps_route_segment_s *) segment;
372         if (s->maneuvers) {
373                 maps_item_list_remove_all(s->maneuvers,
374                         maps_route_maneuver_destroy);
375                 maps_item_list_destroy(s->maneuvers);
376         }
377         maps_item_list_clone(maneuvers, maps_route_maneuver_clone,
378                 &s->maneuvers);
379         return MAPS_ERROR_NONE;
380 }
381
382 int _maps_route_segment_set_supported_data(maps_route_segment_h segment,
383                                                                 const maps_int_hashtable_h supported_data)
384 {
385         if (!maps_condition_check_maps_feature())
386                 return MAPS_ERROR_NOT_SUPPORTED;
387         if (!segment || !supported_data)
388                 return MAPS_ERROR_INVALID_PARAMETER;
389         maps_route_segment_s *p = (maps_route_segment_s *) segment;
390         if (p->supported_data)
391                 maps_int_hashtable_destroy(p->supported_data);
392         return maps_int_hashtable_clone(supported_data, &p->supported_data);
393 }