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.
23 #include <glib/gprintf.h>
30 #include <location-module.h>
31 #include <location-poi.h>
33 #include <decarta_log.h>
35 #include <location-map-service.h>
36 #include <location-map-service-ext.h>
37 #include <decarta_config.h>
39 #include "location_decarta.h"
41 static char* service_name = "decarta";
42 GSList * async_request_queue;
45 TRUE, //MAP_SERVICE_PREF_LANGUAGE
46 TRUE, //MAP_SERVICE_PREF_DISTANCE_UNIT
48 TRUE, //MAP_SERVICE_PREF_PROPERTY
50 TRUE, //MAP_SERVICE_GEOCODE_TYPE
51 TRUE, //MAP_SERVICE_REVERSE_GEOCODE_TYPE
53 TRUE, //MAP_SERVICE_POI_TYPE
54 TRUE, //MAP_SERVICE_POI_SEARCH_BY_ADDRESS
55 TRUE, //MAP_SERVICE_POI_SEARCH_BY_FREEFORM_ADDRESS
56 TRUE, //MAP_SERVICE_POI_SEARCH_BY_CIRCLE_BOUNDARY
57 FALSE, //MAP_SERVICE_POI_SEARCH_BY_RECT_BOUNDARY
58 FALSE, //MAP_SERVICE_POI_SEARCH_BY_POLYGON_BOUNDARY
59 TRUE, //MAP_SERVICE_POI_PREF_SORT_BY
60 TRUE, //MAP_SERVICE_POI_PREF_PROPERTY
61 TRUE, //MAP_SERVICE_POI_FILTER,
62 TRUE, //MAP_SERVICE_POI_FILTER_CATEGORY
64 TRUE, //MAP_SERVICE_ROUTE_REQUEST_FREEFORM_ADDR_TO_AVOID
65 TRUE, //MAP_SERVICE_ROUTE_REQUEST_STRUCTED_ADDR_TO_AVOID
66 TRUE, //MAP_SERVICE_ROUTE_REQUEST_CIRCLE_AREA_TO_AVOID
67 FALSE, //MAP_SERVICE_ROUTE_REQUEST_RECT_AREA_TO_AVOID
68 FALSE, //MAP_SERVICE_ROUTE_REQUEST_POLYGON_AREA_TO_AVOID
69 TRUE, //MAP_SERVICE_ROUTE_REQUEST_FEATURE_TO_AVOID
70 TRUE, //MAP_SERVICE_ROUTE_PREF_TYPE
71 TRUE, //MAP_SERVICE_ROUTE_PREF_TRANSPORT_MODE
72 TRUE, //MAP_SERVICE_ROUTE_PREF_GEOMETRY_BOUNDING_BOX
73 TRUE, //MAP_SERVICE_ROUTE_PREF_GEOMETRY_RETRIEVAL
74 TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_GEOMETRY
75 TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_BOUNDING_BOX
76 TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_RETRIEVAL
77 TRUE, //MAP_SERVICE_ROUTE_PREF_REALTIME_TRAFFIC
78 FALSE, //MAP_SERVICE_ROUTE_PREF_PROPERTY
79 TRUE, //MAP_SERVICE_ROUTE_DISTANCE_UNIT
80 FALSE, //MAP_SERVICE_ROUTE_PROPERTY
81 FALSE, //MAP_SERVICE_ROUTE_SEGMENT_PROPERTY
82 FALSE //MAP_SERVICE_ROUTE_STEP_PROPERTY
86 __pos_list_item_free(gpointer data)
88 g_return_if_fail(data);
89 LocationPosition *position = (LocationPosition *)data;
90 location_position_free(position);
94 decarta_position_free_list(GList *position_list)
96 g_return_if_fail(position_list);
97 g_list_free_full(position_list, (GDestroyNotify)__pos_list_item_free);
101 __acc_list_item_free(gpointer data)
103 g_return_if_fail(data);
104 LocationAccuracy *accuracy = (LocationAccuracy *)data;
105 location_accuracy_free(accuracy);
109 decarta_accuracy_free_list(GList *accuracy_list)
111 g_return_if_fail(accuracy_list);
112 g_list_free_full(accuracy_list, (GDestroyNotify)__acc_list_item_free);
116 convert_decarta_error_to_location_error (int err)
119 case DECARTA_ERROR_NONE:
120 return LOCATION_ERROR_NONE;
121 case DECARTA_ERROR_CONFIGURATION_FILE:
122 return LOCATION_ERROR_CONFIGURATION;
123 case DECARTA_ERROR_HTTP:
124 return LOCATION_ERROR_NETWORK_FAILED;
125 case DECARTA_ERROR_NOT_FOUND:
126 return LOCATION_ERROR_NOT_FOUND;
127 case DECARTA_ERROR_XML:
129 return LOCATION_ERROR_UNKNOWN;
133 static DecartaFormedAddress*
134 get_decarta_addr_from_location_addr (const LocationAddress *address)
136 if (!address) return NULL;
137 return decarta_formed_address_new (address->building_number,
139 address->state, NULL,
142 address->postal_code, NULL, NULL);
145 static LocationAddress *
146 get_location_addr_from_decarta_addr (const DecartaAddress *deca_addr)
148 if (!deca_addr) return NULL;
149 LocationAddress* addr = NULL;
150 if (deca_addr->is_freerorm) {
151 //FIXME: how to convert free to formed...??
152 addr = location_address_new (NULL, NULL, NULL, NULL, NULL, NULL, NULL);
153 } else if (deca_addr->formed_addr) {
154 addr = location_address_new (deca_addr->formed_addr->street_number,
155 deca_addr->formed_addr->street_name,
156 deca_addr->formed_addr->district,
157 deca_addr->formed_addr->city,
158 deca_addr->formed_addr->state,
159 deca_addr->country_code,
160 deca_addr->formed_addr->postal_code);
165 static LocationPosition *
166 get_location_pos_from_decarta_pos (const DecartaPosition *deca_pos)
168 if (!deca_pos) return NULL;
169 return location_position_new (0, deca_pos->latitude, deca_pos->longitude, 0, LOCATION_STATUS_2D_FIX);
172 static LocationAccuracy *
173 get_location_acc_from_free_addr (const char *free_addr)
175 if (!free_addr) return NULL;
176 //FIXME: how to convert free to formed...??
177 return location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0);
180 static LocationAccuracy *
181 get_location_acc_from_location_addr (const LocationAddress *addr)
183 if (!addr) return NULL;
184 LocationAccuracy *accuracy = NULL;
186 if (addr->building_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
187 else if (addr->street) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, 0, 0);
188 else if (addr->postal_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0);
189 else if (addr->district ||
190 addr->city) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, 0, 0);
191 else if (addr->state) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, 0, 0);
192 else if (addr->country_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, 0, 0);
193 else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
198 static LocationAccuracy *
199 get_location_acc_from_decarta_addr (const DecartaAddress *addr)
201 if (!addr) return NULL;
202 LocationAccuracy *accuracy = NULL;
203 if (addr->is_freerorm && addr->freeform_address) {
204 //FIXME: how to convert free to formed...??
205 accuracy = get_location_acc_from_free_addr(addr->freeform_address);
206 } else if (addr->formed_addr) {
207 DecartaFormedAddress *formed_addr = addr->formed_addr;
208 if (formed_addr->street_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
209 else if (formed_addr->street_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, 0, 0);
210 else if (formed_addr->postal_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0);
211 else if (formed_addr->district ||
212 formed_addr->city) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, 0, 0);
213 else if (formed_addr->state) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, 0, 0);
214 else if (addr->country_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, 0, 0);
215 else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
223 get_lang (gchar country_code[3], gchar lang_code[3])
225 if (!country_code || !lang_code) return;
226 gchar* langset = vconf_get_str(VCONFKEY_LANGSET);
227 DECARTA_LOGD("getenv: %s", langset);
233 country_code[0] = 'U';
234 country_code[1] = 'S';
235 country_code[2] = '\0';
237 gchar* langset_upper = g_ascii_strup(langset, -1);
238 lang_code[0] = langset_upper[0];
239 lang_code[1] = langset_upper[1];
241 country_code[0] = langset_upper[3];
242 country_code[1] = langset_upper[4];
243 country_code[2] = '\0';
244 g_free(langset_upper);
246 DECARTA_LOGD("Language: %s, Country: %s", lang_code, country_code);
250 get_service_name (gpointer handle,
251 gchar **_service_name)
253 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
254 g_return_val_if_fail(_service_name, LOCATION_ERROR_PARAMETER);
255 *_service_name = g_strdup(service_name);
256 return LOCATION_ERROR_NONE;
260 address_cb (DecartaError deca_err,
261 const DecartaGeocode *geocode,
264 LocationAddress *addr = NULL;
265 LocationAccuracy *acc = NULL;
266 LocationError error = LOCATION_ERROR_NONE;
267 DecartaData* data = (DecartaData*)userdata;
268 g_return_if_fail(data);
270 async_request_queue = g_slist_remove(async_request_queue , data->handle);
272 if (deca_err == DECARTA_ERROR_NONE && geocode && geocode->addr) {
273 DECARTA_LOGD("address_cb: success");
274 addr = get_location_addr_from_decarta_addr (geocode->addr);
275 acc = get_location_acc_from_decarta_addr (geocode->addr);
277 DECARTA_LOGD("address_cb: failed");
278 error = convert_decarta_error_to_location_error (deca_err);
280 if (data->addr_cb) data->addr_cb (error, addr, acc, data->userdata);
281 if (addr) location_address_free (addr);
282 if (acc) location_accuracy_free (acc);
287 position_cb (DecartaError deca_err,
288 const GList *geocode_list,
291 LocationPosition *pos = NULL;
292 LocationAccuracy *acc = NULL;
293 GList *position_list = NULL;
294 GList *accuracy_list = NULL;
295 LocationError error = LOCATION_ERROR_NONE;
296 DecartaData* data = (DecartaData*)userdata;
297 g_return_if_fail(data);
301 async_request_queue = g_slist_remove(async_request_queue , data->handle);
303 if (deca_err == DECARTA_ERROR_NONE) {
304 DECARTA_LOGD("position_cb: success");
307 GList *tmp_geocode_list = (GList *)geocode_list;
309 const DecartaGeocode *geocode = NULL;
310 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
314 // Fixme: geocode->pos NULL case ?
315 pos = get_location_pos_from_decarta_pos (geocode->pos);
316 acc = location_accuracy_copy ((LocationAccuracy *)(data->userdata2));
320 location_accuracy_free(acc);
325 DECARTA_LOGD("location decarta plugin: position_cb %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
327 position_list = g_list_append (position_list, (gpointer)pos);
328 accuracy_list = g_list_append (accuracy_list, (gpointer)acc);
330 if (!tmp_geocode_list) break;
331 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
334 error = LOCATION_ERROR_NOT_FOUND;
337 DECARTA_LOGD("position_cb: failed");
338 error = convert_decarta_error_to_location_error (deca_err);
341 if (position_list == NULL) error = LOCATION_ERROR_NOT_FOUND;
342 data->pos_cb(error, position_list, accuracy_list, data->userdata);
345 if(position_list) decarta_position_free_list(position_list);
346 if(accuracy_list) decarta_accuracy_free_list(accuracy_list);
348 location_accuracy_free ((LocationAccuracy *)data->userdata2);
353 __decarta_append_landmark_list (gpointer data,
356 DecartaPOI *poi = (DecartaPOI *)data;
357 GList **landmark_list = (GList **)user_data;
358 LocationPosition *loc_position = NULL;
359 LocationAddress *loc_address = NULL;
361 LocationLandmark *landmark = location_landmark_new();
363 DECARTA_LOGD("name:%s id:%s phone_number:%s\n", poi->name, poi->id, poi->phone_number);
364 guint id_uint = g_ascii_strtoull(poi->id, NULL, 10);
365 location_landmark_set_id(landmark, id_uint);
366 location_landmark_set_name(landmark, poi->name);
367 location_landmark_set_phone_number(landmark, poi->phone_number);
371 decarta_poi_info_table_iter_init (poi->info_list);
372 while (decarta_poi_info_list_table_next (poi->info_list, &key, &value))
374 DECARTA_LOGD("%s=%s\n", key, value);
375 location_landmark_set_property(landmark, key, value);
378 DECARTA_LOGD("Position: %lf %lf\n", poi->pos->latitude, poi->pos->longitude);
379 loc_position = get_location_pos_from_decarta_pos (poi->pos);
380 location_landmark_set_position(landmark, loc_position);
383 loc_address = get_location_addr_from_decarta_addr (poi->addr);
384 location_landmark_set_address(landmark, loc_address);
387 *landmark_list = g_list_append(*landmark_list, landmark);
392 __decarta_free_landmark_list (gpointer data,
395 LocationLandmark* landmark = (LocationLandmark*)data;
396 location_landmark_free(landmark);
400 decarta_landmark_free_list(GList *landmark_list)
402 g_return_if_fail(landmark_list);
403 g_list_foreach(landmark_list, (GFunc)__decarta_free_landmark_list, NULL);
404 g_list_free(landmark_list);
405 landmark_list = NULL;
410 void landmark_cb (DecartaError error,
411 const gchar *req_id_str,
412 const GList* poi_list,
413 const gchar *error_code,
414 const gchar *error_msg,
417 LocationError loc_error = LOCATION_ERROR_NONE;
418 DecartaData* data = (DecartaData*)userdata;
419 g_return_if_fail(data);
421 GList *landmark_list = NULL;
423 if (error == DECARTA_ERROR_NONE) {
424 DECARTA_LOGD("landmark_cb: success, req_id %s", req_id_str);
426 GList *tmp_poi_list = (GList *)poi_list;
427 g_list_foreach(tmp_poi_list, (GFunc)__decarta_append_landmark_list, &landmark_list);
429 DECARTA_LOGD("landmark_cb: failed, req_id %s, error code %s, msg %s", req_id_str, error_code, error_msg);
431 loc_error = convert_decarta_error_to_location_error (error);
434 req_id = g_ascii_strtoull(req_id_str, NULL, 10);
435 gchar *code = g_strdup(error_code);
436 gchar *msg = g_strdup(error_msg);
437 data->poi_cb(loc_error, req_id, landmark_list, code, msg, data->userdata);
441 if (landmark_list) decarta_landmark_free_list(landmark_list);
446 // used to split the step into segments
447 static DecartaBoundary *
448 __decarta_route_boundary_new_for_rect (DecartaPosition* left_top,
449 DecartaPosition* right_bottom)
451 g_return_val_if_fail(left_top, NULL);
452 g_return_val_if_fail(right_bottom, NULL);
454 DecartaBoundary* boundary = g_slice_new0 (DecartaBoundary);
455 boundary->type = DECARTA_BOUNDARY_RECT;
456 boundary->rect.left_top = decarta_position_copy(left_top);
457 boundary->rect.right_bottom = decarta_position_copy(right_bottom);
461 // postion's latitude & longitude between the boundary
463 __decarta_route_boundary_if_inside (DecartaBoundary* boundary,
464 const DecartaPosition* position)
466 g_return_val_if_fail(boundary, FALSE);
467 g_return_val_if_fail(position, FALSE);
469 gboolean is_inside = FALSE;
471 switch(boundary->type) {
473 case DECARTA_BOUNDARY_RECT: {
474 gdouble y = position->latitude;
475 gdouble x = position->longitude;
476 gdouble y_min, y_max;
477 gdouble x_min, x_max;
479 if (boundary->rect.left_top->latitude < boundary->rect.right_bottom->latitude) {
480 y_min = boundary->rect.left_top->latitude;
481 y_max = boundary->rect.right_bottom->latitude;
483 y_max = boundary->rect.left_top->latitude;
484 y_min = boundary->rect.right_bottom->latitude;
487 if (boundary->rect.left_top->longitude < boundary->rect.right_bottom->longitude) {
488 x_min = boundary->rect.left_top->longitude;
489 x_max = boundary->rect.right_bottom->longitude;
491 x_max = boundary->rect.left_top->longitude;
492 x_min = boundary->rect.right_bottom->longitude;
495 if (x > x_min && x < x_max && y > y_min && y < y_max) {
496 DECARTA_LOGD("\tInside of Rectangular boundary");
502 case DECARTA_BOUNDARY_CIRCLE: {
503 DECARTA_LOGW("\tCircle boundary type is TBD.");
507 case DECARTA_BOUNDARY_POLYGON: {
508 DECARTA_LOGW("\tPolygon boundary type is TBD.");
513 DECARTA_LOGW("\tboundary type is undefined.[%d]", boundary->type);
523 __route_step_foreach_free (gpointer data)
525 g_return_if_fail (data);
526 LocationRouteStep *step = (LocationRouteStep *) data;
527 location_route_step_free(step);
531 __route_segment_foreach_free (gpointer data)
533 g_return_if_fail (data);
534 LocationRouteSegment *segment = (LocationRouteSegment *)data;
535 location_route_segment_free(segment);
538 static LocationBoundary *
539 get_location_boundary_from_decarta_bbox(LocationPosition *pos1,
540 LocationPosition *pos2)
542 g_return_val_if_fail(pos1, NULL);
543 g_return_val_if_fail(pos2, NULL);
544 LocationPosition *right_bottom = NULL;
545 LocationPosition *left_top = NULL;
547 // determine the right_bottom & left_top postion
548 gdouble lon_interval = pos2->longitude - pos1->longitude;
549 if(lon_interval < 180 && lon_interval > -180) {
550 if(pos2->longitude <= pos1->longitude || pos2->latitude >= pos1->latitude) {
559 if(pos2->longitude >= pos1->longitude || pos2->latitude >= pos1->latitude) {
568 LocationBoundary *bbox = location_boundary_new_for_rect(left_top, right_bottom);
570 g_printf("ERROR: get_location_boundary_from_decarta_bbox failed\n");
578 get_location_route_list_from_decarta_route (const DecartaRoute *route,
579 const LocationPosition *origin,
580 const LocationPosition *destination)
582 GList *route_list = NULL;
583 LocationRoute *loc_route = location_route_new();
584 GList *seg_list = NULL;
585 GList *step_list = NULL;
587 // set the route origin & destination
588 location_route_set_origin(loc_route, origin);
589 location_route_set_destination(loc_route, destination);
591 // set the duration, distance
592 location_route_set_total_distance(loc_route, route->total_distance);
593 location_route_set_distance_unit(loc_route, "M");
594 location_route_set_total_duration(loc_route, route->total_time);
596 // set the rout rect area
597 LocationPosition *pos1 = get_location_pos_from_decarta_pos(route->box_corner1);
598 LocationPosition *pos2 = get_location_pos_from_decarta_pos(route->box_corner2);
599 // Fixme: can't create the boundary?
600 LocationBoundary *bbox = get_location_boundary_from_decarta_bbox(pos1, pos2);
601 location_position_free(pos1);
602 location_position_free(pos2);
603 location_route_set_bounding_box(loc_route, bbox);
605 //set the segments for route
606 if (route->instructions_list) {
607 GList *inst_list = (GList *)route->instructions_list;
608 const DecartaRouteInstructions *inst = NULL;
609 inst_list = decarta_route_instructions_list_next( inst_list, &inst);
611 GList *pos_list = (GList *)route->line_pos_list;
612 DecartaPosition *pos_prev = NULL;
613 // for each instruction
615 LocationRouteSegment *seg = location_route_segment_new();
616 location_route_segment_set_distance(seg, inst->distance);
617 location_route_segment_set_duration(seg, inst->duration);
620 g_list_free_full (step_list, __route_step_foreach_free);
624 DecartaBoundary *instuct_rect = __decarta_route_boundary_new_for_rect(inst->map->box_corner1, inst->map->box_corner2);
627 const DecartaPosition *pos = NULL;
628 pos_list = decarta_position_list_next(pos_list, &pos);
630 // search the whole pos list for each instruction
631 if (__decarta_route_boundary_if_inside(instuct_rect, pos)) {
632 LocationRouteStep *step = location_route_step_new();
634 location_route_step_set_start_point(step, get_location_pos_from_decarta_pos(pos_prev));
636 // set geometry for location step
637 GList *geometry_list = NULL;
638 geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos_prev));
639 geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos));
640 location_route_step_set_geometry(step, geometry_list);
642 decarta_position_free(pos_prev);
645 // the first segment's first position should be Origin
646 location_route_step_set_start_point(step, origin);
648 location_route_step_set_instruction(step, inst->instruction);
649 location_route_step_set_end_point(step, get_location_pos_from_decarta_pos(pos));
651 step_list = g_list_append(step_list, step);
652 pos_prev = decarta_position_copy(pos);
655 if (!pos_list) break;
656 pos_list = decarta_position_list_next(pos_list, &pos);
660 // search from beginning of the pos list
661 pos_list = (GList *)route->line_pos_list;
665 location_route_segment_set_route_step(seg, step_list);
666 GList *seg_first = g_list_first(step_list);
668 LocationRouteStep *seg_first_step = (LocationRouteStep *)seg_first->data;
669 const LocationPosition *seg_start_pos = location_route_step_get_start_point(seg_first_step);
670 location_route_segment_set_start_point(seg, seg_start_pos);
672 GList *seg_last = g_list_last(step_list);
674 LocationRouteStep *seg_last_step = (LocationRouteStep *)seg_last->data;
675 const LocationPosition *seg_end_pos = location_route_step_get_end_point(seg_last_step);
676 location_route_segment_set_end_point(seg, seg_end_pos);
680 seg_list = g_list_append(seg_list, seg);
682 if (!inst_list) break;
683 inst_list = decarta_route_instructions_list_next (inst_list, &inst);
688 location_route_set_route_segment(loc_route, seg_list);
689 g_list_free_full (seg_list, __route_segment_foreach_free);
693 route_list = g_list_append(route_list, loc_route);
699 __decarta_free_route_list (gpointer data,
702 LocationRoute *route = (LocationRoute *)data;
703 GList *seg_list = (GList *)location_route_get_route_segment(route);
705 g_list_foreach(seg_list, (GFunc)__route_segment_foreach_free, NULL);
710 decarta_route_free_list(GList *route_list)
712 g_return_if_fail(route_list);
713 g_list_foreach(route_list, (GFunc)__decarta_free_route_list, NULL);
714 g_list_free(route_list);
719 void route_callback(DecartaError error,
720 const gchar *req_id_str,
721 const DecartaRoute *route,
722 const gchar * error_code,
723 const gchar * error_msg,
726 LocationError loc_error = LOCATION_ERROR_NONE;
727 DecartaData* data = (DecartaData*)user_data;
728 g_return_if_fail(data);
730 GList *route_list = NULL;
731 LocationPosition *origin = (LocationPosition *)data->userdata2;
732 LocationPosition *destination = (LocationPosition *)data->userdata3;
734 if (error == DECARTA_ERROR_NONE) {
735 DECARTA_LOGD("route_callback: success");
736 route_list = get_location_route_list_from_decarta_route(route, origin, destination);
739 DECARTA_LOGD("route_callback: failed");
740 loc_error = convert_decarta_error_to_location_error (error);
742 if (data->route_cb) {
743 gchar *code = g_strdup(error_code);
744 gchar *msg = g_strdup(error_msg);
745 data->route_cb(loc_error, req_id, route_list, code, msg, data->userdata);
749 if (route_list) decarta_route_free_list(route_list);
750 if (origin) location_position_free(origin);
751 if (destination) location_position_free(destination);
756 get_geocode (gpointer handle,
757 const LocationAddress *addr,
758 const LocationMapPref *svc_pref,
759 GList **position_list,
760 GList **accuracy_list)
762 DECARTA_LOGD("get_geocode");
763 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
764 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
765 g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER);
766 g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER);
769 GList *geocode_list = NULL;
770 LocationPosition *pos = NULL;
771 LocationAccuracy *acc = NULL;
774 char *password = NULL;
775 ID = location_map_pref_get_property(svc_pref, "ID");
776 password = location_map_pref_get_property(svc_pref, "PASSWORD");
777 set_config(ID, password, NULL, NULL);
779 char *language_code = NULL;
780 char *country_code = NULL;
781 language_code = location_map_pref_get_language(svc_pref);
782 country_code = location_map_pref_get_country(svc_pref);
783 if (language_code == NULL || country_code == NULL) {
784 gchar tmp_country[3] = "";
785 gchar tmp_language[3] = "";
786 get_lang(tmp_country, tmp_language);
787 if (country_code == NULL) {
788 country_code = g_strdup(tmp_country);
790 if (language_code == NULL) {
791 language_code = g_strdup(tmp_language);
795 DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr);
796 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr);
797 decarta_formed_address_free (deca_formed_addr);
798 int ret = decarta_search_geocode(deca_addr, &geocode_list);
799 decarta_address_free (deca_addr);
801 if (ret == DECARTA_ERROR_NONE) {
802 // libslp-location getting multi addresses.
803 /* can't change the geocode_list for del */
804 GList *tmp_geocode_list = (GList *)geocode_list;
805 const DecartaGeocode *geocode = NULL;
806 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
809 pos = get_location_pos_from_decarta_pos (geocode->pos);
810 acc = get_location_acc_from_location_addr (addr);
812 DECARTA_LOGD("location decarta plugin: get_geocode %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
814 *position_list = g_list_append (*position_list, (gpointer)pos);
815 *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc);
817 if (!tmp_geocode_list) break;
818 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
820 decarta_geocode_list_free (geocode_list);
822 return convert_decarta_error_to_location_error (ret);
826 decarta_idle_geocode_cb (gpointer data)
828 decarta_IdleData* idle_data = (decarta_IdleData*)data;
829 if (idle_data == NULL || idle_data->decarta_data == NULL) {
830 g_printf("idle_data or decarta_data is NULL\n");
834 DecartaData *deca_data = (DecartaData *)idle_data->decarta_data;
835 int err = decarta_search_geocode_async(idle_data->addr, idle_data->geocode_cb, deca_data, &deca_data->handle);
836 async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle);
837 if (DECARTA_ERROR_NONE != err) {
838 g_printf("Decarta Geocode Failed: %d\n", err);
840 // call position_cb() to return the error code, and free DecartaData
841 if (idle_data->geocode_cb) {
842 idle_data->geocode_cb (err, NULL, idle_data->decarta_data);
845 decarta_address_free (idle_data->addr);
852 get_geocode_async (gpointer handle,
853 const LocationAddress * addr,
854 const LocationMapPref *svc_pref,
855 LocationPositionCB callback,
858 DECARTA_LOGD("get_geocode_async");
859 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
860 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
861 g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER);
864 char *password = NULL;
865 ID = location_map_pref_get_property(svc_pref, "ID");
866 password = location_map_pref_get_property(svc_pref, "PASSWORD");
867 set_config(ID, password, NULL, NULL);
869 DecartaData* data = g_new0(DecartaData, 1);
871 char *language_code = NULL;
872 char *country_code = NULL;
873 language_code = location_map_pref_get_language(svc_pref);
874 country_code = location_map_pref_get_country(svc_pref);
875 if (language_code == NULL || country_code == NULL) {
876 gchar tmp_country[3] = "";
877 gchar tmp_language[3] = "";
878 get_lang(tmp_country, tmp_language);
879 if (country_code == NULL) {
880 country_code = g_strdup(tmp_country);
882 if (language_code == NULL) {
883 language_code = g_strdup(tmp_language);
887 DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr);
888 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr);
889 decarta_formed_address_free (deca_formed_addr);
890 data->pos_cb = callback;
891 data->userdata = (gpointer)userdata;
892 data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr);
894 // should call decarta_search_geocode_async in idle, OR request may be missed
895 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
896 idle_data->addr = deca_addr;
897 idle_data->geocode_cb = position_cb;
898 idle_data->decarta_data = data;
899 g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data);
901 return LOCATION_ERROR_NONE;
905 get_geocode_freetext(gpointer handle,
907 const LocationMapPref *svc_pref,
908 GList **position_list,
909 GList **accuracy_list)
911 DECARTA_LOGD ("get_geocode_freetext");
912 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
913 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
914 g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER);
915 g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER);
918 GList *geocode_list = NULL;
919 LocationPosition *pos = NULL;
920 LocationAccuracy *acc = NULL;
923 char *password = NULL;
924 ID = location_map_pref_get_property(svc_pref, "ID");
925 password = location_map_pref_get_property(svc_pref, "PASSWORD");
926 set_config(ID, password, NULL, NULL);
928 char *language_code = NULL;
929 char *country_code = NULL;
930 language_code = location_map_pref_get_language(svc_pref);
931 country_code = location_map_pref_get_country(svc_pref);
932 if (language_code == NULL || country_code == NULL) {
933 gchar tmp_country[3] = "";
934 gchar tmp_language[3] = "";
935 get_lang(tmp_country, tmp_language);
936 if (country_code == NULL) {
937 country_code = g_strdup(tmp_country);
939 if (language_code == NULL) {
940 language_code = g_strdup(tmp_language);
944 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL);
945 int ret = decarta_search_geocode(deca_addr, &geocode_list);
946 decarta_address_free (deca_addr);
948 if (ret == DECARTA_ERROR_NONE) {
949 // libslp-location getting multi addresses.
950 /* can't change the geocode_list for del */
951 GList *tmp_geocode_list = (GList *)geocode_list;
952 const DecartaGeocode *geocode = NULL;
953 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
956 pos = get_location_pos_from_decarta_pos (geocode->pos);
957 if (geocode->addr) acc = get_location_acc_from_decarta_addr (geocode->addr);
958 else acc = get_location_acc_from_free_addr (addr);
960 DECARTA_LOGD("location decarta plugin: get_geocode_freetext %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
962 *position_list = g_list_append (*position_list, (gpointer)pos);
963 *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc);
965 if (!tmp_geocode_list) break;
966 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
968 decarta_geocode_list_free (geocode_list);
970 return convert_decarta_error_to_location_error (ret);
975 get_geocode_freetext_async (gpointer handle,
977 const LocationMapPref *svc_pref,
978 LocationPositionCB callback,
981 DECARTA_LOGD("get_geocode_freetext_async");
982 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
983 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
984 g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER);
987 char *password = NULL;
988 ID = location_map_pref_get_property(svc_pref, "ID");
989 password = location_map_pref_get_property(svc_pref, "PASSWORD");
990 set_config(ID, password, NULL, NULL);
992 char *language_code = NULL;
993 char *country_code = NULL;
994 language_code = location_map_pref_get_language(svc_pref);
995 country_code = location_map_pref_get_country(svc_pref);
996 if (language_code == NULL || country_code == NULL) {
997 gchar tmp_country[3] = "";
998 gchar tmp_language[3] = "";
999 get_lang(tmp_country, tmp_language);
1000 if (country_code == NULL) {
1001 country_code = g_strdup(tmp_country);
1003 if (language_code == NULL) {
1004 language_code = g_strdup(tmp_language);
1008 DecartaData* data = g_new0(DecartaData, 1);
1009 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL);
1010 data->pos_cb = callback;
1011 data->userdata = (gpointer)userdata;
1012 data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr);
1014 // should call decarta_search_geocode_async in idle, OR request may be missed
1015 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1016 idle_data->addr = deca_addr;
1017 idle_data->geocode_cb = position_cb;
1018 idle_data->decarta_data = data;
1019 g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data);
1021 return LOCATION_ERROR_NONE;
1025 get_reverse_geocode(gpointer handle,
1026 const LocationPosition *pos,
1027 const LocationMapPref *svc_pref,
1028 LocationAddress **addr,
1029 LocationAccuracy **accuracy)
1031 DECARTA_LOGD("get_reverse_geocode");
1032 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1033 g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
1034 g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
1035 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
1038 char *password = NULL;
1039 ID = location_map_pref_get_property(svc_pref, "ID");
1040 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1041 set_config(ID, password, NULL, NULL);
1043 DecartaGeocode *geocode = NULL;
1044 DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude);
1045 int ret = decarta_search_reverse_geocode(deca_pos, &geocode);
1046 decarta_position_free (deca_pos);
1048 if (ret == DECARTA_ERROR_NONE) {
1050 *addr = get_location_addr_from_decarta_addr (geocode->addr);
1051 *accuracy = get_location_acc_from_decarta_addr (geocode->addr);
1052 decarta_geocode_free (geocode);
1056 return convert_decarta_error_to_location_error (ret);
1060 decarta_idle_reverse_geocode_cb (gpointer data)
1062 DECARTA_LOGD("decarta_idle_reverse_geocode_cb");
1063 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1064 if (idle_data == NULL || idle_data->decarta_data == NULL) {
1065 DECARTA_LOGD("idle_data or decarta_data is NULL");
1069 DecartaData *deca_data = (DecartaData *)idle_data->decarta_data;
1070 int err = decarta_search_reverse_geocode_async (idle_data->pos, idle_data->reverse_geocode_cb, deca_data, &deca_data->handle);
1071 async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle);
1072 if (DECARTA_ERROR_NONE != err) {
1073 DECARTA_LOGD("Decarta Reverse Geocode Failed: %d", err);
1075 // call address_cb() to return the error code, and free DecartaData
1076 if (idle_data->reverse_geocode_cb) {
1077 idle_data->reverse_geocode_cb (err, NULL, idle_data->decarta_data);
1080 decarta_position_free (idle_data->pos);
1086 get_reverse_geocode_async (gpointer handle,
1087 const LocationPosition *pos,
1088 const LocationMapPref *svc_pref,
1089 LocationAddressCB callback,
1092 DECARTA_LOGD("get_reverse_geocode_async");
1093 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1094 g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
1095 g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER);
1098 char *password = NULL;
1099 ID = location_map_pref_get_property(svc_pref, "ID");
1100 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1101 set_config(ID, password, NULL, NULL);
1103 DecartaData* data = g_new0(DecartaData, 1);
1104 data->addr_cb = callback;
1105 data->userdata = (gpointer)userdata;
1106 DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude);
1108 // should call decarta_search_reverse_geocode_async in idle, OR request may be missed
1109 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1110 idle_data->pos= deca_pos;
1111 idle_data->reverse_geocode_cb= address_cb;
1112 idle_data->decarta_data = data;
1113 g_idle_add((GSourceFunc)decarta_idle_reverse_geocode_cb, (gpointer)idle_data);
1115 return LOCATION_ERROR_NONE;
1119 static DecartaPOIPrefSortOrder
1120 decarta_get_sort_order(LocationPOIPrefSortOrder order)
1122 if (order == LOCATION_POI_PREF_SO_ASC) {
1123 return DECARTA_POI_PREF_SO_ASC;
1124 } else if (order == LOCATION_POI_PREF_SO_DESC) {
1125 return DECARTA_POI_PREF_SO_DESC;
1127 return DECARTA_POI_PREF_SO_NONE;
1131 //to make the request_id unique int, not start with 0
1132 static guint request_id = 1;
1135 decarta_idle_directory_cb (gpointer data)
1137 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1138 if (idle_data == NULL) {
1139 g_printf( "decarta_IdleData is NULL\n");
1143 int err = decarta_search_directory_async (idle_data->dir_request, idle_data->dir_cb, idle_data->decarta_data);
1144 if (DECARTA_ERROR_NONE != err) {
1145 g_printf( "Decarta Directory Failed: %d\n", err);
1147 // call landmark_cb() to return the error code, and free DecartaData
1148 if (idle_data->dir_cb) {
1149 char req_id_str[256];
1150 g_snprintf(req_id_str, 256, "%d", idle_data->request_id);
1151 idle_data->dir_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data);
1154 decarta_directory_request_free (idle_data->dir_request);
1159 int search_poi(gpointer handle,
1160 const LocationPOIFilter *filter,
1161 const LocationPosition *position,
1162 const LocationMapPref *svc_pref,
1163 const LocationPOIPreference *pref,
1168 DECARTA_LOGD("location decarta plugin: search_poi");
1169 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1170 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1171 g_return_val_if_fail (position, LOCATION_ERROR_PARAMETER);
1172 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1173 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1174 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1177 char *password = NULL;
1178 ID = location_map_pref_get_property(svc_pref, "ID");
1179 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1180 set_config(ID, password, NULL, NULL);
1182 DecartaData* data = g_new0(DecartaData, 1);
1183 DecartaPosition *pos = decarta_position_new (position->latitude, position->longitude);
1184 *req_id = request_id++;
1185 // POI property: keyword, brand, type, description, URL => CATEGORY, KEYWORD, POIName
1186 const char *type = location_poi_filter_get(filter, "CATEGORY");
1187 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1188 const char *poi_name = location_poi_filter_get(filter, "POIName");
1189 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1190 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1191 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1192 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST,
1193 DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 0, *req_id);
1194 decarta_position_free (pos);
1195 decarta_poi_property_free (property);
1196 decarta_poi_preference_free(poi_pref);
1200 data->userdata = (gpointer)user_data;
1202 // should call decarta_search_directory_async in idle, OR request may be missed
1203 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1204 idle_data->dir_request = dir_request;
1205 idle_data->dir_cb = landmark_cb;
1206 idle_data->decarta_data = data;
1207 idle_data->request_id = request_id;
1208 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1210 return LOCATION_ERROR_NONE;
1213 int search_poi_by_area(gpointer handle,
1214 const LocationPOIFilter *filter,
1215 const LocationBoundary *boundary,
1216 const LocationMapPref *svc_pref,
1217 const LocationPOIPreference *pref,
1222 DECARTA_LOGD("location decarta plugin: search_poi_by_area");
1223 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1224 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1225 g_return_val_if_fail (boundary, LOCATION_ERROR_PARAMETER);
1226 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1227 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1228 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1231 char *password = NULL;
1232 ID = location_map_pref_get_property(svc_pref, "ID");
1233 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1234 set_config(ID, password, NULL, NULL);
1236 if (boundary->type == LOCATION_BOUNDARY_CIRCLE) {
1237 DecartaData* data = g_new0(DecartaData, 1);
1238 DecartaPosition *pos = decarta_position_new (boundary->circle.center->latitude, boundary->circle.center->longitude);
1239 double distance = boundary->circle.radius;
1240 DECARTA_LOGD("search_poi_by_area: Circle lat [%lf], lon [%lf], radius [%f]",
1241 boundary->circle.center->latitude,
1242 boundary->circle.center->longitude,
1244 *req_id = request_id++;
1245 const char *type = location_poi_filter_get(filter, "CATEGORY");
1246 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1247 const char *poi_name = location_poi_filter_get(filter, "POIName");
1248 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1249 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1250 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1251 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE,
1252 DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, distance, *req_id);
1253 decarta_position_free (pos);
1254 decarta_poi_property_free (property);
1255 decarta_poi_preference_free(poi_pref);
1258 data->userdata = (gpointer)user_data;
1260 // should call decarta_search_directory_async in idle, OR request may be missed
1261 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1262 idle_data->dir_request = dir_request;
1263 idle_data->dir_cb = landmark_cb;
1264 idle_data->decarta_data = data;
1265 idle_data->request_id = request_id;
1266 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1268 return LOCATION_ERROR_NONE;
1269 } else if (boundary->type == LOCATION_BOUNDARY_RECT) {
1270 return LOCATION_ERROR_NOT_AVAILABLE;
1271 } else if (boundary->type == LOCATION_BOUNDARY_POLYGON) {
1272 return LOCATION_ERROR_NOT_AVAILABLE;
1274 return LOCATION_ERROR_NOT_AVAILABLE;
1278 int search_poi_by_address(gpointer handle,
1279 const LocationPOIFilter *filter,
1280 const LocationAddress *addr,
1281 const LocationMapPref *svc_pref,
1282 const LocationPOIPreference *pref,
1287 DECARTA_LOGD("location decarta plugin: search_poi_by_addr");
1288 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1289 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1290 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
1291 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1292 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1293 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1296 char *password = NULL;
1297 ID = location_map_pref_get_property(svc_pref, "ID");
1298 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1299 set_config(ID, password, NULL, NULL);
1301 char *language_code = NULL;
1302 char *country_code = NULL;
1303 language_code = location_map_pref_get_language(svc_pref);
1304 country_code = location_map_pref_get_country(svc_pref);
1305 if (language_code == NULL || country_code == NULL) {
1306 gchar tmp_country[3] = "";
1307 gchar tmp_language[3] = "";
1308 get_lang(tmp_country, tmp_language);
1309 if (country_code == NULL) {
1310 country_code = g_strdup(tmp_country);
1312 if (language_code == NULL) {
1313 language_code = g_strdup(tmp_language);
1317 DecartaData* data = g_new0(DecartaData, 1);
1319 // Fixme: landmark_type, landmark_name for decarta_formed_address_new ??
1320 DecartaFormedAddress *formed_addr = decarta_formed_address_new (addr->building_number, addr->street, addr->country_code,
1321 addr->state, addr->city, addr->district, addr->postal_code, NULL, NULL);
1323 *req_id = request_id++;
1325 DecartaAddress *decarta_addr = decarta_address_new (country_code, language_code, FALSE, NULL, formed_addr);
1326 decarta_formed_address_free (formed_addr);
1328 const char *type = location_poi_filter_get(filter, "CATEGORY");
1329 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1330 const char *poi_name = location_poi_filter_get(filter, "POIName");
1331 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1332 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1333 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1335 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS,
1336 DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, decarta_addr, NULL, property, 0, *req_id);
1337 decarta_address_free (decarta_addr);
1338 decarta_poi_property_free (property);
1339 decarta_poi_preference_free(poi_pref);
1342 data->userdata = (gpointer)user_data;
1344 // should call decarta_search_directory_async in idle, OR request may be missed
1345 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1346 idle_data->dir_request = dir_request;
1347 idle_data->dir_cb = landmark_cb;
1348 idle_data->decarta_data = data;
1349 idle_data->request_id = request_id;
1350 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1352 return LOCATION_ERROR_NONE;
1355 int search_poi_by_freeform(gpointer handle,
1356 const LocationPOIFilter *filter,
1357 const gchar *address,
1358 const LocationMapPref *svc_pref,
1359 const LocationPOIPreference *pref,
1364 DECARTA_LOGD("location decarta plugin: search_poi_by_freeformed_address");
1365 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1366 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1367 g_return_val_if_fail (address, LOCATION_ERROR_PARAMETER);
1368 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1369 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1370 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1373 char *password = NULL;
1374 ID = location_map_pref_get_property(svc_pref, "ID");
1375 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1376 set_config(ID, password, NULL, NULL);
1378 char *language_code = NULL;
1379 char *country_code = NULL;
1380 language_code = location_map_pref_get_language(svc_pref);
1381 country_code = location_map_pref_get_country(svc_pref);
1382 if (language_code == NULL || country_code == NULL) {
1383 gchar tmp_country[3] = "";
1384 gchar tmp_language[3] = "";
1385 get_lang(tmp_country, tmp_language);
1386 if (country_code == NULL) {
1387 country_code = g_strdup(tmp_country);
1389 if (language_code == NULL) {
1390 language_code = g_strdup(tmp_language);
1394 DecartaData* data = g_new0(DecartaData, 1);
1396 *req_id = request_id++;
1398 DecartaAddress *free_addr = decarta_address_new (country_code, language_code, TRUE, address, NULL);
1400 const char *type = location_poi_filter_get(filter, "CATEGORY");
1401 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1402 const char *poi_name = location_poi_filter_get(filter, "POIName");
1403 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1405 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1406 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1407 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS,
1408 DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, free_addr, NULL, property, 0, *req_id);
1410 decarta_address_free (free_addr);
1411 decarta_poi_property_free (property);
1412 decarta_poi_preference_free(poi_pref);
1415 data->userdata = (gpointer)user_data;
1417 // should call decarta_search_directory_async in idle, OR request may be missed
1418 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1419 idle_data->dir_request = dir_request;
1420 idle_data->dir_cb = landmark_cb;
1421 idle_data->decarta_data = data;
1422 idle_data->request_id = request_id;
1423 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1425 return LOCATION_ERROR_NONE;
1428 int cancel_poi_request(gpointer handle,
1431 DECARTA_LOGD("location decarta plugin: cancel_poi_request");
1432 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1434 decarta_search_directory_async_cancel (req_id);
1435 return LOCATION_ERROR_NONE;
1439 __route_create_via_list (gpointer data,
1442 LocationPosition *via_loc_pos = (LocationPosition *)data;
1443 GList **via_geocode_list = (GList **)user_data;
1445 DecartaPosition *via_pos = decarta_position_new (via_loc_pos->latitude, via_loc_pos->longitude);
1446 *via_geocode_list = decarta_geocode_list_append (*via_geocode_list, decarta_geocode_new (via_pos, NULL));
1447 decarta_position_free (via_pos);
1450 static DecartaRoutePreference
1451 __get_route_type(const gchar *type)
1453 if (0 == g_strcmp0("FASTEST", type)) {
1454 return DECARTA_ROUTE_PREF_FASTEST;
1455 } else if (0 == g_strcmp0("SHORTEST", type)) {
1456 return DECARTA_ROUTE_PREF_SHORTEST;
1457 } else if (0 == g_strcmp0("PEDESTRIAN", type)) {
1458 return DECARTA_ROUTE_PREF_PEDESTRIAN;
1459 } else if (0 == g_strcmp0("AVOID_FREEWAYS", type)) {
1460 return DECARTA_ROUTE_PREF_AVOID_FREEWAYS;
1461 } else if (0 == g_strcmp0("NO_FREEWAYS", type)) {
1462 return DECARTA_ROUTE_PREF_NO_FREEWAYS;
1463 } else if (0 == g_strcmp0("MORE_FREEWAYS", type)) {
1464 return DECARTA_ROUTE_PREF_MORE_FREEWAYS;
1465 } else if (0 == g_strcmp0("IGNORE_PIPES", type)) {
1466 return DECARTA_ROUTE_PREF_IGNORE_PIPES;
1467 } else if (0 == g_strcmp0("EASY", type)) {
1468 return DECARTA_ROUTE_PREF_EASY;
1470 return DECARTA_ROUTE_PREF_NONE;
1475 decarta_idle_route_cb (gpointer data)
1477 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1478 if (idle_data == NULL) {
1479 g_printf( "idle_data is NULL\n");
1483 int err = decarta_search_route_async (idle_data->route_request, idle_data->route_cb, idle_data->decarta_data);
1484 if (DECARTA_ERROR_NONE != err) {
1485 g_printf("Decarta Route Failed: %d\n", err);
1487 // call route_callback() to return the error code, and free DecartaData
1488 if (idle_data->route_cb) {
1489 char req_id_str[256];
1490 g_snprintf(req_id_str, 256, "%d", idle_data->request_id);
1491 idle_data->route_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data);
1494 decarta_route_request_free (idle_data->route_request);
1499 int request_route (gpointer handle,
1500 const LocationPosition *origin,
1501 const LocationPosition *destination,
1503 const LocationMapPref *svc_pref,
1504 const LocationRoutePreference *pref,
1506 const gpointer user_data,
1509 DECARTA_LOGD("location decarta plugin: request_route");
1510 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1511 g_return_val_if_fail (origin, LOCATION_ERROR_PARAMETER);
1512 g_return_val_if_fail (destination, LOCATION_ERROR_PARAMETER);
1513 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1514 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1515 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1518 char *password = NULL;
1519 ID = location_map_pref_get_property(svc_pref, "ID");
1520 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1521 set_config(ID, password, NULL, NULL);
1523 char *language_code = NULL;
1524 char *maneuver_rules = NULL;
1525 language_code = location_map_pref_get_language(svc_pref);
1526 if (language_code == NULL) {
1527 gchar tmp_country[3] = "";
1528 gchar tmp_language[3] = "";
1529 get_lang(tmp_country, tmp_language);
1530 language_code = g_strdup(tmp_language);
1532 if (!g_strcmp0(language_code, "FR")) {
1533 maneuver_rules = g_strdup_printf("maneuver-rules-%s", language_code);
1535 maneuver_rules = g_strdup("maneuver-rules");
1538 char *dist_uit = NULL;
1539 dist_uit = location_map_pref_get_distance_unit(svc_pref);
1540 if (g_strcmp0(dist_uit, "KM") != 0 && g_strcmp0(dist_uit, "M") != 0 && g_strcmp0(dist_uit, "DM") != 0 &&
1541 g_strcmp0(dist_uit, "MI") != 0 && g_strcmp0(dist_uit, "YD") != 0 && g_strcmp0(dist_uit, "FT") != 0) {
1542 dist_uit = g_strdup("M");
1545 DecartaData* data = g_new0(DecartaData, 1);
1546 DecartaPosition *start_pos = decarta_position_new (origin->latitude, origin->longitude);
1547 DecartaPosition *end_pos = decarta_position_new (destination->latitude, destination->longitude);
1549 DecartaGeocode *start = decarta_geocode_new (start_pos, NULL);
1550 DecartaGeocode *end = decarta_geocode_new (end_pos, NULL);
1551 GList *via_geocode_list = NULL;
1552 GList *tmp_waypoint = (GList *)waypoint;
1554 g_list_foreach(tmp_waypoint, (GFunc)__route_create_via_list, &via_geocode_list);
1556 decarta_position_free (start_pos);
1557 decarta_position_free (end_pos);
1559 gboolean bbox_needed = FALSE;
1560 DecartaPosition *bbox_pos1 = NULL;
1561 DecartaPosition *bbox_pos2 = NULL;
1562 LocationBoundary *bbox = location_route_pref_get_bounding_box(pref);
1563 if (bbox && bbox->type == LOCATION_BOUNDARY_RECT) {
1564 bbox_pos1 = decarta_position_new(bbox->rect.left_top->latitude, bbox->rect.left_top->longitude);
1565 bbox_pos2 = decarta_position_new(bbox->rect.right_bottom->latitude, bbox->rect.right_bottom->longitude);
1569 float resolution = DEFAULT_ROUTE_RESOLUTION;
1570 char *reslolution_str = (char *)location_route_pref_get_property(pref, (gconstpointer)"resolution");
1571 if (reslolution_str) {
1572 resolution = (float)g_ascii_strtod(reslolution_str, NULL);
1575 *req_id = request_id++;
1576 DecartaRouteRequest *route_request = decarta_route_request_new (__get_route_type(location_route_pref_get_route_type(pref)),
1577 start, end, via_geocode_list, TRUE, TRUE,
1578 bbox_needed, bbox_pos1, bbox_pos2, TRUE, resolution, TRUE, *req_id, dist_uit, maneuver_rules);
1579 g_free (maneuver_rules);
1580 decarta_geocode_free (start);
1581 decarta_geocode_free (end);
1582 if (via_geocode_list) {
1583 decarta_geocode_list_free (via_geocode_list);
1584 via_geocode_list = NULL;
1587 decarta_position_free(bbox_pos1);
1590 decarta_position_free(bbox_pos2);
1593 data->route_cb = cb;
1594 data->userdata = (gpointer)user_data;
1595 data->userdata2 = (gpointer)location_position_copy(origin);
1596 data->userdata3 = (gpointer)location_position_copy(destination);
1598 // should call decarta_search_route_async in idle callback, OR request may be missed
1599 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1600 idle_data->route_request = route_request;
1601 idle_data->route_cb= route_callback;
1602 idle_data->decarta_data = data;
1603 idle_data->request_id = request_id;
1604 g_idle_add((GSourceFunc)decarta_idle_route_cb, (gpointer)idle_data);
1606 return LOCATION_ERROR_NONE;
1608 int cancel_route_request (gpointer handle,
1611 int ret = DECARTA_ERROR_NONE;
1613 DECARTA_LOGD("location decarta plugin: request_route");
1614 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1616 ret = decarta_search_route_async_cancel (req_id);
1617 if (ret != DECARTA_ERROR_NONE) {
1618 return convert_decarta_error_to_location_error(ret);
1621 return LOCATION_ERROR_NONE;
1625 is_supported_provider_capability (gpointer handle, LocationMapServiceType type)
1627 DECARTA_LOGD("location decarta plugin: is_supported_provider_capability");
1628 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1630 return g_capa_list[type];
1634 get_provider_capability_key (gpointer handle, LocationMapServiceType type, GList **key)
1636 DECARTA_LOGD("location decarta plugin: get_provider_capability_key");
1637 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1638 g_return_val_if_fail (key, LOCATION_ERROR_PARAMETER);
1640 gchar **str_key = NULL;
1641 int idx = 0, count = 0;
1642 gchar *available_key = NULL;
1645 case MAP_SERVICE_PREF_LANGUAGE:
1647 count = sizeof(key_lang) / sizeof(char *);
1648 g_printf("key_lang[%d], char *[%d]. Count [%d]", sizeof(key_lang), sizeof(char*), count);
1651 case MAP_SERVICE_PREF_PROPERTY:
1652 str_key = key_property;
1653 count = sizeof(key_property) / sizeof(char *);
1654 g_printf("key_property[%d], char *[%d]. Count [%d]", sizeof(key_property), sizeof(char*), count);
1656 case MAP_SERVICE_PREF_DISTANCE_UNIT:
1657 case MAP_SERVICE_ROUTE_DISTANCE_UNIT:
1659 count = sizeof(key_dist) / sizeof(char*);
1661 case MAP_SERVICE_POI_PREF_SORT_BY:
1662 str_key = key_poi_sort;
1663 count = sizeof(key_poi_sort) / sizeof (char*);
1665 case MAP_SERVICE_POI_PREF_PROPERTY:
1666 str_key = key_poi_prop;
1667 count = sizeof(key_poi_prop) / sizeof (char*);
1669 case MAP_SERVICE_POI_FILTER:
1670 str_key = key_poi_filter;
1671 count = sizeof(key_poi_filter) / sizeof (char*);
1673 case MAP_SERVICE_POI_FILTER_CATEGORY:
1674 str_key = key_poi_filter_category;
1675 count = sizeof(key_poi_filter_category) / sizeof (char*);
1677 case MAP_SERVICE_ROUTE_REQUEST_FEATURE_TO_AVOID:
1678 str_key = key_route_feature_to_avoid;
1679 count = sizeof(key_route_feature_to_avoid) / sizeof (char*);
1681 case MAP_SERVICE_ROUTE_PREF_TYPE:
1682 str_key = key_route_type;
1683 count = sizeof(key_route_type) / sizeof (char*);
1685 case MAP_SERVICE_ROUTE_PREF_TRANSPORT_MODE:
1686 str_key = key_route_trans_mode;
1687 count = sizeof(key_route_trans_mode) / sizeof (char*);
1696 return LOCATION_ERROR_NOT_FOUND;
1699 for (idx = 0; idx < count; idx++) {
1700 available_key = g_strdup (str_key[idx]);
1701 *key = g_list_append(*key, available_key);
1704 return LOCATION_ERROR_NONE;
1707 LOCATION_MODULE_API gpointer
1708 init (LocModServiceOps* ops)
1710 DECARTA_LOGD("init");
1711 g_return_val_if_fail(ops, NULL);
1712 gpointer handle = (gpointer)service_name;
1714 ops->get_service_name = get_service_name;
1715 ops->get_geocode = get_geocode;
1716 ops->get_geocode_freetext = get_geocode_freetext;
1717 ops->get_reverse_geocode = get_reverse_geocode;
1718 ops->get_geocode_async = get_geocode_async;
1719 ops->get_geocode_freetext_async = get_geocode_freetext_async;
1720 ops->get_reverse_geocode_async = get_reverse_geocode_async;
1722 ops->search_poi = search_poi;
1723 ops->search_poi_by_area = search_poi_by_area;
1724 ops->search_poi_by_address = search_poi_by_address;
1725 ops->search_poi_by_freeform = search_poi_by_freeform;
1726 ops->cancel_poi_request = cancel_poi_request;
1728 ops->request_route = request_route;
1729 ops->cancel_route_request = cancel_route_request;
1731 ops->is_supported_provider_capability = is_supported_provider_capability;
1732 ops->get_provider_capability_key = get_provider_capability_key;
1734 async_request_queue = g_slist_alloc();
1739 cancel_request (gpointer data, gpointer user_data)
1741 decarta_search_geocode_async_cancel(data);
1742 decarta_search_reverse_geocode_async_cancel(data);
1745 LOCATION_MODULE_API void
1746 shutdown (gpointer handle)
1748 DECARTA_LOGD("shutdown");
1749 g_return_if_fail(handle == (gpointer)service_name);
1751 g_slist_foreach (async_request_queue, cancel_request, NULL);
1753 g_slist_free(async_request_queue);