4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7 * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
26 #include "decarta_log.h"
27 #include "xml_wrapper.h"
28 #include "decarta_xml.h"
29 #include "decarta_xml_internal.h"
32 get_route_pref (DecartaRoutePreference pref)
35 if (pref == DECARTA_ROUTE_PREF_FASTEST) ret = g_strdup ("fastest");
36 else if (pref == DECARTA_ROUTE_PREF_SHORTEST) ret = g_strdup ("shortest");
37 else if (pref == DECARTA_ROUTE_PREF_PEDESTRIAN) ret = g_strdup ("pedestrian");
38 else if (pref == DECARTA_ROUTE_PREF_AVOID_FREEWAYS) ret = g_strdup ("AvoidFreeways");
39 else if (pref == DECARTA_ROUTE_PREF_NO_FREEWAYS) ret = g_strdup ("NoFreeways");
40 else if (pref == DECARTA_ROUTE_PREF_MORE_FREEWAYS) ret = g_strdup ("MoreFreeways");
41 else if (pref == DECARTA_ROUTE_PREF_IGNORE_PIPES) ret = g_strdup ("IgnorePipes");
42 else if (pref == DECARTA_ROUTE_PREF_EASY) ret = g_strdup ("easy");
47 get_time_from_string (const char* str)
50 unsigned int time = 0;
52 gchar **part = g_strsplit_set (str, "S", 2);
55 gchar **part_s = g_strsplit_set (part[0], "M", 2);
57 time += g_ascii_strtoull (part_s[1], NULL, 10);
60 gchar **part_m = g_strsplit_set (part_s[0], "H", 2);
62 time += (g_ascii_strtoull (part_m[1], NULL, 10)*60);
65 gchar **part_h = g_strsplit_set (part_m[0], "DT", 2);
67 time += (g_ascii_strtoull (part_h[1], NULL, 10)*3600);
70 gchar **part_d = g_strsplit_set (part_h[0], "P", 2);
72 time += (g_ascii_strtoull (part_d [1], NULL, 10)*3600*24);
79 make_xml_waypoint_list (XmlWriterHandler handle,
80 const DecartaRouteRequest *request)
82 if (!handle || !request || !request->start || !request->end) return FALSE;
84 if (!xml_writer_all_start(handle, NS_XLS":WayPointList", NULL, NULL)) return FALSE;
85 if (!make_xml_point (handle, NS_XLS":StartPoint", request->start)) return FALSE;
86 if (!xml_writer_end(handle)) return FALSE;
88 if (request->via_geocode_list) {
89 const DecartaGeocode *via = NULL;
90 GList *via_geocode_list = decarta_geocode_list_next (request->via_geocode_list, &via);
92 if (!make_xml_point(handle, NS_XLS":ViaPoint", via)) return FALSE;
93 if (!xml_writer_end(handle)) return FALSE;
94 if (!via_geocode_list) break;
95 via_geocode_list = decarta_geocode_list_next(via_geocode_list, &via);
98 if (!make_xml_point (handle, NS_XLS":EndPoint", request->end)) return FALSE;
99 if (!xml_writer_end(handle)) return FALSE;
100 if (!xml_writer_end(handle)) return FALSE;
105 xml_route_request_get (const DecartaRouteRequest *request,
109 if (!request || !xml_request || !size) {
110 DECARTA_LOGW ("request or xml_request or size is NULL");
113 gboolean ret = FALSE;
114 XmlWriterHandler handle = xml_writer_open("UTF-8");
115 char *pref_str = get_route_pref (request->pref);
120 if (make_xml_header (handle, "DetermineRouteRequest", NULL, NULL) &&
121 xml_writer_all_start (handle, NS_XLS":DetermineRouteRequest", NULL, "provideRouteHandle", "false", "distanceUnit", request->dist_unit, NULL) &&
122 xml_writer_all_start (handle, NS_XLS":RoutePlan", NULL, NULL) &&
123 xml_writer_all_start (handle, NS_XLS":RoutePreference", pref_str, NULL) &&
124 xml_writer_end(handle) &&
125 make_xml_waypoint_list (handle, request) &&
126 xml_writer_end(handle)) {
128 if (request->instructions_map_needed) {
129 if (!xml_writer_all_start (handle, NS_XLS":RouteInstructionsRequest", NULL, "rules", request->rules, NULL) ||
130 !xml_writer_end(handle)) ret = FALSE;
132 if (request->pos_needed) {
133 if (request->resolution_needed && request->VR_needed) {
134 char resolution_str[32];
135 if (g_snprintf (resolution_str, 32, "%f", request->resolution) < 0) ret = FALSE;
136 if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "resolution", resolution_str, "routeGeometryFormat", "VR", NULL)) ret = FALSE;
137 } else if (request->resolution_needed && (request->VR_needed == FALSE)) {
138 char resolution_str[32];
139 if (g_snprintf (resolution_str, 32, "%f", request->resolution) < 0) ret = FALSE;
140 if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "resolution", resolution_str, NULL)) ret = FALSE;
141 } else if ((request->resolution_needed == FALSE) && request->VR_needed) {
142 if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "routeGeometryFormat", "VR", NULL)) ret = FALSE;
144 if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, NULL)) ret = FALSE;
146 if (request->bbox_needed) {
147 if (!xml_writer_all_start (handle, NS_XLS":BoundingBox", NULL, NULL)) ret = FALSE;
148 if (!make_xml_position(handle, request->bbox_pos1)) ret = FALSE;
149 if (!make_xml_position(handle, request->bbox_pos2)) ret = FALSE;
150 if (!xml_writer_end(handle)) ret = FALSE;
152 if (!xml_writer_end(handle)) ret = FALSE;
154 if (request->instructions_map_needed) {
155 if (!xml_writer_all_start (handle, NS_XLS":RouteMapRequest", NULL, NULL) ||
156 !xml_writer_all_start (handle, NS_XLS":Output", NULL, "width", "500", "height", "500", "style", "Overview", "format", IMG_FORMAT, NULL) ||
157 !xml_writer_end(handle) ||
158 !xml_writer_all_start (handle, NS_XLS":Output", NULL, "width", TILE_SIZE, "height", TILE_SIZE, "style", "Maneuver", "format", IMG_FORMAT, NULL) ||
159 !xml_writer_end(handle) ||
160 !xml_writer_end(handle)) ret = FALSE;
163 if (!xml_writer_close(handle, xml_request, size)) ret = FALSE;
168 static void __route_geo_addr_list_free_cb (gpointer data)
170 g_return_if_fail (data);
172 decarta_geo_addr_s *addr_item = (decarta_geo_addr_s *)data;
173 if (addr_item->building_num) {
174 g_free(addr_item->building_num);
176 if (addr_item->country_2_subdivision) {
177 g_free(addr_item->country_2_subdivision);
179 if (addr_item->country_code) {
180 g_free(addr_item->country_code);
182 if (addr_item->country_subdivision) {
183 g_free(addr_item->country_subdivision);
185 if (addr_item->freeform_addr) {
186 g_free(addr_item->freeform_addr);
188 if (addr_item->landmark_name) {
189 g_free(addr_item->landmark_name);
191 if (addr_item->landmark_type) {
192 g_free(addr_item->landmark_type);
194 if (addr_item->lang_code) {
195 g_free(addr_item->lang_code);
197 if (addr_item->municipality) {
198 g_free(addr_item->municipality);
200 if (addr_item->municipality_subdivision) {
201 g_free(addr_item->municipality_subdivision);
203 if (addr_item->pos) {
204 g_free(addr_item->pos);
206 if (addr_item->postcode) {
207 g_free(addr_item->postcode);
209 if (addr_item->street) {
210 g_free(addr_item->street);
214 static void __route_instruction_list_free_cb (gpointer data)
216 g_return_if_fail (data);
218 decarta_route_inst_str_s *inst_item = (decarta_route_inst_str_s *)data;
219 if (inst_item->duration) {
220 g_free(inst_item->duration);
222 if (inst_item->distance) {
223 g_free(inst_item->distance);
225 if (inst_item->tour) {
226 g_free(inst_item->tour);
228 if (inst_item->instruction) {
229 g_free(inst_item->instruction);
231 if (inst_item->description) {
232 g_free(inst_item->description);
236 static void __route_map_list_free_cb (gpointer data)
238 g_return_if_fail (data);
240 decarta_route_map_str_s *map_item = (decarta_route_map_str_s *)data;
242 g_free(map_item->url);
244 if (map_item->description) {
245 g_free(map_item->description);
247 if (map_item->pos1) {
248 g_free(map_item->pos1);
250 if (map_item->pos2) {
251 g_free(map_item->pos2);
255 static void __sax_parse_route(void *user_data, DecartaRoute **route)
257 DECARTA_LOGD("_sax_parse_route enter ");
259 if (!user_data || !route) {
260 DECARTA_LOGW ("user_data or route is NULL");
265 GList *start_geo_list = NULL;
266 GList *end_geo_list = NULL;
267 unsigned int total_time = 0;
268 double total_distance = 0;
269 DecartaPosition *box_corner1 = NULL;
270 DecartaPosition *box_corner2 = NULL;
271 GList *line_pos_list = NULL;
272 GList *instructions_list = NULL;
273 DecartaMap *overview_map = NULL;
276 sax_route_data_s *route_data = (sax_route_data_s *)user_data;
277 if (route_data->route_geometry_str) {
278 gchar **part = g_strsplit_set(route_data->route_geometry_str, ",", 0);
279 int n_route_geomoetry = 0;
280 GArray *garray = NULL;
281 garray = g_array_new(FALSE, FALSE, sizeof(long));
283 while (part[n_route_geomoetry]) {
284 long tmp_long = g_ascii_strtoll(part[n_route_geomoetry], NULL, 10);
285 g_array_append_val(garray, tmp_long);
290 DECARTA_LOGD("verify the array:---------number[%d]----------\n", n_route_geomoetry);
294 DecartaPosition *pos = NULL;
295 for (i = 0; i < n_route_geomoetry; i++) {
296 DECARTA_LOGD("No. [%d]", i);
298 // save the geometry locations number
299 int n_geometry = g_array_index(garray, long, i);
300 DECARTA_LOGD(" the summary number of route geometry is [%d]\n", n_geometry);
302 long lat_l = g_array_index(garray, long, i - 1);
303 long lon_l = g_array_index(garray, long, i);
306 double lat_d = ((double)lat_l) / 100000;
307 double lon_d = ((double)lon_l) / 100000;
308 DECARTA_LOGD("first lat [%.5f], lon [%.5f]\n", lat_d, lon_d);
310 pos = decarta_position_new(lat_d, lon_d);
311 line_pos_list = decarta_position_list_append(line_pos_list, pos);
312 } else if ((i % 2) == 0) {
313 long lat_diff_l = g_array_index(garray, long, i - 1);
314 long lon_diff_l = g_array_index(garray, long, i);
315 DECARTA_LOGD("lat_diff_l [%ld], lon_diff_l [%ld]\n", lat_diff_l, lon_diff_l);
316 long lat_l = lat_diff_l + prev_lat_l;
317 long lon_l = lon_diff_l + prev_lon_l;
320 double lat_d = ((double)lat_l) / 100000;
321 double lon_d = ((double)lon_l) / 100000;
322 DECARTA_LOGD("lat [%.5f], lon [%.5f]\n", lat_d, lon_d);
324 pos = decarta_position_new(lat_d, lon_d);
325 line_pos_list = decarta_position_list_append(line_pos_list, pos);
329 g_array_free(garray, TRUE);
331 g_free(route_data->route_geometry_str);
332 route_data->route_geometry_str = NULL;
336 if (route_data->route_totaltime_str) {
337 total_time = get_time_from_string(route_data->route_totaltime_str);
338 g_free(route_data->route_totaltime_str);
342 if (route_data->route_totaldist_str) {
343 total_distance = g_ascii_strtod(route_data->route_totaldist_str, NULL);
344 g_free(route_data->route_totaldist_str);
348 if (route_data->route_bbox_pos1_str) {
349 box_corner1 = get_position_from_string (route_data->route_bbox_pos1_str);
350 g_free (route_data->route_bbox_pos1_str);
352 if (route_data->route_bbox_pos2_str) {
353 box_corner2 = get_position_from_string (route_data->route_bbox_pos2_str);
354 g_free (route_data->route_bbox_pos2_str);
357 /** StartAddressCandidates*/
358 DecartaPosition *pos = NULL;
359 DecartaAddress *addr = NULL;
360 DecartaFormedAddress *formed_addr = NULL;
361 gboolean is_freeformed = FALSE;
362 GList *start_addr_list = g_list_first(route_data->route_start_addr_list);
363 while (start_addr_list) {
364 decarta_geo_addr_s *start_item = (decarta_geo_addr_s *)start_addr_list->data;
366 DECARTA_LOGD("start_item NULL, break the start list loop\n");
369 if (start_item->pos) {
370 DECARTA_LOGD("start pos [%s]\n", start_item->pos);
371 pos = get_position_from_string(start_item->pos);
373 if (start_item->is_freeform) {
374 DECARTA_LOGD("start freeform address [%s]\n", start_item->freeform_addr);
375 is_freeformed = TRUE;
377 formed_addr = decarta_formed_address_new(start_item->building_num, start_item->street, start_item->country_subdivision,
378 start_item->country_2_subdivision, start_item->municipality, start_item->municipality_subdivision,
379 start_item->postcode, start_item->landmark_type, start_item->landmark_name);
381 addr = decarta_address_new(start_item->country_code, start_item->lang_code, is_freeformed, start_item->freeform_addr, formed_addr);
383 decarta_formed_address_free(formed_addr);
385 /** create the start address list */
386 start_geo_list = decarta_geocode_list_append(start_geo_list, decarta_geocode_new(pos, addr));
388 decarta_position_free(pos);
391 decarta_address_free(addr);
393 start_addr_list = g_list_next(start_addr_list);
396 if (route_data->route_start_addr_list) {
397 g_list_free_full(route_data->route_start_addr_list, __route_geo_addr_list_free_cb);
398 route_data->route_start_addr_list = NULL;
401 /** EndAddressCandidates*/
405 is_freeformed = FALSE;
406 GList *end_addr_list = g_list_first(route_data->route_end_addr_list);
407 while (end_addr_list) {
408 decarta_geo_addr_s *end_item = (decarta_geo_addr_s *)end_addr_list->data;
410 DECARTA_LOGD("start_item NULL, break the end list loop\n");
414 DECARTA_LOGD("end pos [%s]\n", end_item->pos);
415 pos = get_position_from_string(end_item->pos);
417 if (end_item->is_freeform) {
418 DECARTA_LOGD("end freeform address [%s]\n", end_item->freeform_addr);
419 is_freeformed = TRUE;
421 formed_addr = decarta_formed_address_new(end_item->building_num, end_item->street, end_item->country_subdivision,
422 end_item->country_2_subdivision, end_item->municipality, end_item->municipality_subdivision,
423 end_item->postcode, end_item->landmark_type, end_item->landmark_name);
425 addr = decarta_address_new(end_item->country_code, end_item->lang_code, is_freeformed, end_item->freeform_addr, formed_addr);
427 decarta_formed_address_free(formed_addr);
429 /** create the start address list */
430 end_geo_list = decarta_geocode_list_append(end_geo_list, decarta_geocode_new (pos, addr));
432 decarta_position_free(pos);
435 decarta_address_free(addr);
437 end_addr_list = g_list_next(end_addr_list);
440 if (route_data->route_end_addr_list) {
441 g_list_free_full(route_data->route_end_addr_list, __route_geo_addr_list_free_cb);
442 route_data->route_end_addr_list = NULL;
446 DecartaPosition *box_corner1_02 = get_position_from_string(route_data->route_ov_pos1_str);
447 DecartaPosition *box_corner2_02 = get_position_from_string(route_data->route_ov_pos2_str);
448 overview_map = decarta_map_new(NULL, box_corner1_02, box_corner2_02, route_data->route_ov_tile_url_str, 0);
449 if (box_corner1_02) {
450 decarta_position_free (box_corner1_02);
452 if (box_corner2_02) {
453 decarta_position_free (box_corner2_02);
455 if (route_data->route_ov_tile_url_str) {
456 g_free(route_data->route_ov_tile_url_str);
460 unsigned int duration= 0;
462 DecartaMap *map = NULL;
463 GList *inst_list = g_list_first(route_data->route_inst_str_list);
465 decarta_route_inst_str_s *inst_item = (decarta_route_inst_str_s *)inst_list->data;
467 DECARTA_LOGD("inst_item NULL, break the inst list loop\n");
470 if (inst_item->instruction) {
471 DECARTA_LOGD("instruction [%s]\n", inst_item->instruction);
474 if (inst_item->duration) {
475 duration = get_time_from_string(inst_item->duration);
477 if (inst_item->distance) {
478 distance = g_ascii_strtod(inst_item->distance, NULL);
481 /** find the description matched map item */
482 GList *map_list = g_list_first(route_data->route_map_str_list);
484 decarta_route_map_str_s *map_item = (decarta_route_map_str_s *)map_list->data;
486 if (!g_strcmp0(inst_item->description, map_item->description)) {
487 DECARTA_LOGD("---------inst & map description matched---------\n");
488 DecartaPosition *box_corner1_03 = get_position_from_string(map_item->pos1);
489 DecartaPosition *box_corner2_03 = get_position_from_string(map_item->pos2);
490 map = decarta_map_new(NULL, box_corner1_03, box_corner2_03, map_item->url, 0);
491 if (box_corner1_03) {
492 decarta_position_free (box_corner1_03);
494 if (box_corner2_03) {
495 decarta_position_free (box_corner2_03);
497 /** break when matched map_item found */
501 DECARTA_LOGD("map_item NULL \n");
503 map_list = g_list_next(map_list);
506 /** create the instruction list */
507 instructions_list = decarta_route_instructions_list_append(instructions_list, decarta_route_instructions_new(inst_item->tour, duration, distance, inst_item->instruction, map));
508 inst_list = g_list_next(inst_list);
511 if (route_data->route_inst_str_list) {
512 g_list_free_full(route_data->route_inst_str_list, __route_instruction_list_free_cb);
513 route_data->route_inst_str_list = NULL;
516 if (route_data->route_map_str_list) {
517 g_list_free_full(route_data->route_map_str_list, __route_map_list_free_cb);
518 route_data->route_map_str_list = NULL;
522 *route = decarta_route_new(start_geo_list, end_geo_list, total_time, total_distance, box_corner1, box_corner2, overview_map, line_pos_list, instructions_list);
526 xml_route_parse (const char* xml_response,
527 DecartaRoute **route,
532 DECARTA_LOGD ("xml_route_parse");
533 if (!xml_response || !route) {
534 DECARTA_LOGW ("xml_response or route is NULL");
538 sax_route_data_s *route_data = g_new0(sax_route_data_s, 1);
540 _xml_sax_read(xml_response, route_data);
542 /** check the error code & DetermineRouteResponse */
543 if (route_data->has_error) {
544 *error_code = g_strdup(route_data->error_code_str);
545 *message = g_strdup(route_data->error_message_str);
547 g_free(route_data->error_code_str);
548 g_free(route_data->error_message_str);
549 g_free(route_data->error_severity_str);
553 if (!route_data->has_route_resp) {
557 __sax_parse_route(route_data, route);
561 if (*route == NULL) {
562 DECARTA_LOGW("[ERROR]xml_route_parse: route is NULL");