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));
318 DECARTA_LOGD("location decarta plugin: position_cb %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
320 position_list = g_list_append (position_list, (gpointer)pos);
321 accuracy_list = g_list_append (accuracy_list, (gpointer)acc);
323 if (!tmp_geocode_list) break;
324 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
327 error = LOCATION_ERROR_NOT_FOUND;
330 DECARTA_LOGD("position_cb: failed");
331 error = convert_decarta_error_to_location_error (deca_err);
334 data->pos_cb(error, position_list, accuracy_list, data->userdata);
337 if(position_list) decarta_position_free_list(position_list);
338 if(accuracy_list) decarta_accuracy_free_list(accuracy_list);
340 location_accuracy_free ((LocationAccuracy *)data->userdata2);
345 __decarta_append_landmark_list (gpointer data,
348 DecartaPOI *poi = (DecartaPOI *)data;
349 GList **landmark_list = (GList **)user_data;
350 LocationPosition *loc_position = NULL;
351 LocationAddress *loc_address = NULL;
353 LocationLandmark *landmark = location_landmark_new();
355 DECARTA_LOGD("name:%s id:%s phone_number:%s\n", poi->name, poi->id, poi->phone_number);
356 guint id_uint = g_ascii_strtoull(poi->id, NULL, 10);
357 location_landmark_set_id(landmark, id_uint);
358 location_landmark_set_name(landmark, poi->name);
359 location_landmark_set_phone_number(landmark, poi->phone_number);
363 decarta_poi_info_table_iter_init (poi->info_list);
364 while (decarta_poi_info_list_table_next (poi->info_list, &key, &value))
366 DECARTA_LOGD("%s=%s\n", key, value);
367 location_landmark_set_property(landmark, key, value);
370 DECARTA_LOGD("Position: %lf %lf\n", poi->pos->latitude, poi->pos->longitude);
371 loc_position = get_location_pos_from_decarta_pos (poi->pos);
372 location_landmark_set_position(landmark, loc_position);
375 loc_address = get_location_addr_from_decarta_addr (poi->addr);
376 location_landmark_set_address(landmark, loc_address);
379 *landmark_list = g_list_append(*landmark_list, landmark);
384 __decarta_free_landmark_list (gpointer data,
387 LocationLandmark* landmark = (LocationLandmark*)data;
388 location_landmark_free(landmark);
392 decarta_landmark_free_list(GList *landmark_list)
394 g_return_if_fail(landmark_list);
395 g_list_foreach(landmark_list, (GFunc)__decarta_free_landmark_list, NULL);
396 g_list_free(landmark_list);
397 landmark_list = NULL;
402 void landmark_cb (DecartaError error,
403 const gchar *req_id_str,
404 const GList* poi_list,
405 const gchar *error_code,
406 const gchar *error_msg,
409 LocationError loc_error = LOCATION_ERROR_NONE;
410 DecartaData* data = (DecartaData*)userdata;
411 g_return_if_fail(data);
413 GList *landmark_list = NULL;
415 if (error == DECARTA_ERROR_NONE) {
416 DECARTA_LOGD("landmark_cb: success, req_id %s", req_id_str);
418 GList *tmp_poi_list = (GList *)poi_list;
419 g_list_foreach(tmp_poi_list, (GFunc)__decarta_append_landmark_list, &landmark_list);
421 DECARTA_LOGD("landmark_cb: failed, req_id %s, error code %s, msg %s", req_id_str, error_code, error_msg);
423 loc_error = convert_decarta_error_to_location_error (error);
426 req_id = g_ascii_strtoull(req_id_str, NULL, 10);
427 gchar *code = g_strdup(error_code);
428 gchar *msg = g_strdup(error_msg);
429 data->poi_cb(loc_error, req_id, landmark_list, code, msg, data->userdata);
433 if (landmark_list) decarta_landmark_free_list(landmark_list);
438 // used to split the step into segments
439 static DecartaBoundary *
440 __decarta_route_boundary_new_for_rect (DecartaPosition* left_top,
441 DecartaPosition* right_bottom)
443 g_return_val_if_fail(left_top, NULL);
444 g_return_val_if_fail(right_bottom, NULL);
446 DecartaBoundary* boundary = g_slice_new0 (DecartaBoundary);
447 boundary->type = DECARTA_BOUNDARY_RECT;
448 boundary->rect.left_top = decarta_position_copy(left_top);
449 boundary->rect.right_bottom = decarta_position_copy(right_bottom);
453 // postion's latitude & longitude between the boundary
455 __decarta_route_boundary_if_inside (DecartaBoundary* boundary,
456 const DecartaPosition* position)
458 g_return_val_if_fail(boundary, FALSE);
459 g_return_val_if_fail(position, FALSE);
461 gboolean is_inside = FALSE;
463 switch(boundary->type) {
465 case DECARTA_BOUNDARY_RECT: {
466 gdouble y = position->latitude;
467 gdouble x = position->longitude;
468 gdouble y_min, y_max;
469 gdouble x_min, x_max;
471 if (boundary->rect.left_top->latitude < boundary->rect.right_bottom->latitude) {
472 y_min = boundary->rect.left_top->latitude;
473 y_max = boundary->rect.right_bottom->latitude;
475 y_max = boundary->rect.left_top->latitude;
476 y_min = boundary->rect.right_bottom->latitude;
479 if (boundary->rect.left_top->longitude < boundary->rect.right_bottom->longitude) {
480 x_min = boundary->rect.left_top->longitude;
481 x_max = boundary->rect.right_bottom->longitude;
483 x_max = boundary->rect.left_top->longitude;
484 x_min = boundary->rect.right_bottom->longitude;
487 if (x > x_min && x < x_max && y > y_min && y < y_max) {
488 DECARTA_LOGD("\tInside of Rectangular boundary");
494 case DECARTA_BOUNDARY_CIRCLE: {
495 DECARTA_LOGW("\tCircle boundary type is TBD.");
499 case DECARTA_BOUNDARY_POLYGON: {
500 DECARTA_LOGW("\tPolygon boundary type is TBD.");
505 DECARTA_LOGW("\tboundary type is undefined.[%d]", boundary->type);
515 __route_step_foreach_free (gpointer data)
517 g_return_if_fail (data);
518 LocationRouteStep *step = (LocationRouteStep *) data;
519 location_route_step_free(step);
523 __route_segment_foreach_free (gpointer data)
525 g_return_if_fail (data);
526 LocationRouteSegment *segment = (LocationRouteSegment *)data;
527 location_route_segment_free(segment);
530 static LocationBoundary *
531 get_location_boundary_from_decarta_bbox(LocationPosition *pos1,
532 LocationPosition *pos2)
534 g_return_val_if_fail(pos1, NULL);
535 g_return_val_if_fail(pos2, NULL);
536 LocationPosition *right_bottom = NULL;
537 LocationPosition *left_top = NULL;
539 // determine the right_bottom & left_top postion
540 gdouble lon_interval = pos2->longitude - pos1->longitude;
541 if(lon_interval < 180 && lon_interval > -180) {
542 if(pos2->longitude <= pos1->longitude || pos2->latitude >= pos1->latitude) {
551 if(pos2->longitude >= pos1->longitude || pos2->latitude >= pos1->latitude) {
560 LocationBoundary *bbox = location_boundary_new_for_rect(left_top, right_bottom);
562 g_printf("ERROR: get_location_boundary_from_decarta_bbox failed\n");
570 get_location_route_list_from_decarta_route (const DecartaRoute *route,
571 const LocationPosition *origin,
572 const LocationPosition *destination)
574 GList *route_list = NULL;
575 LocationRoute *loc_route = location_route_new();
576 GList *seg_list = NULL;
577 GList *step_list = NULL;
579 // set the route origin & destination
580 location_route_set_origin(loc_route, origin);
581 location_route_set_destination(loc_route, destination);
583 // set the duration, distance
584 location_route_set_total_distance(loc_route, route->total_distance);
585 location_route_set_distance_unit(loc_route, "M");
586 location_route_set_total_duration(loc_route, route->total_time);
588 // set the rout rect area
589 LocationPosition *pos1 = get_location_pos_from_decarta_pos(route->box_corner1);
590 LocationPosition *pos2 = get_location_pos_from_decarta_pos(route->box_corner2);
591 // Fixme: can't create the boundary?
592 LocationBoundary *bbox = get_location_boundary_from_decarta_bbox(pos1, pos2);
593 location_position_free(pos1);
594 location_position_free(pos2);
595 location_route_set_bounding_box(loc_route, bbox);
597 //set the segments for route
598 if (route->instructions_list) {
599 GList *inst_list = (GList *)route->instructions_list;
600 const DecartaRouteInstructions *inst = NULL;
601 inst_list = decarta_route_instructions_list_next( inst_list, &inst);
603 GList *pos_list = (GList *)route->line_pos_list;
604 DecartaPosition *pos_prev = NULL;
605 // for each instruction
607 LocationRouteSegment *seg = location_route_segment_new();
608 location_route_segment_set_distance(seg, inst->distance);
609 location_route_segment_set_duration(seg, inst->duration);
612 g_list_free_full (step_list, __route_step_foreach_free);
616 DecartaBoundary *instuct_rect = __decarta_route_boundary_new_for_rect(inst->map->box_corner1, inst->map->box_corner2);
619 const DecartaPosition *pos = NULL;
620 pos_list = decarta_position_list_next(pos_list, &pos);
622 // search the whole pos list for each instruction
623 if (__decarta_route_boundary_if_inside(instuct_rect, pos)) {
624 LocationRouteStep *step = location_route_step_new();
626 location_route_step_set_start_point(step, get_location_pos_from_decarta_pos(pos_prev));
628 // set geometry for location step
629 GList *geometry_list = NULL;
630 geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos_prev));
631 geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos));
632 location_route_step_set_geometry(step, geometry_list);
634 decarta_position_free(pos_prev);
637 // the first segment's first position should be Origin
638 location_route_step_set_start_point(step, origin);
640 location_route_step_set_instruction(step, inst->instruction);
641 location_route_step_set_end_point(step, get_location_pos_from_decarta_pos(pos));
643 step_list = g_list_append(step_list, step);
644 pos_prev = decarta_position_copy(pos);
647 if (!pos_list) break;
648 pos_list = decarta_position_list_next(pos_list, &pos);
652 // search from beginning of the pos list
653 pos_list = (GList *)route->line_pos_list;
657 location_route_segment_set_route_step(seg, step_list);
658 GList *seg_first = g_list_first(step_list);
660 LocationRouteStep *seg_first_step = (LocationRouteStep *)seg_first->data;
661 const LocationPosition *seg_start_pos = location_route_step_get_start_point(seg_first_step);
662 location_route_segment_set_start_point(seg, seg_start_pos);
664 GList *seg_last = g_list_last(step_list);
666 LocationRouteStep *seg_last_step = (LocationRouteStep *)seg_last->data;
667 const LocationPosition *seg_end_pos = location_route_step_get_end_point(seg_last_step);
668 location_route_segment_set_end_point(seg, seg_end_pos);
672 seg_list = g_list_append(seg_list, seg);
674 if (!inst_list) break;
675 inst_list = decarta_route_instructions_list_next (inst_list, &inst);
680 location_route_set_route_segment(loc_route, seg_list);
681 g_list_free_full (seg_list, __route_segment_foreach_free);
685 route_list = g_list_append(route_list, loc_route);
691 __decarta_free_route_list (gpointer data,
694 LocationRoute *route = (LocationRoute *)data;
695 GList *seg_list = (GList *)location_route_get_route_segment(route);
697 g_list_foreach(seg_list, (GFunc)__route_segment_foreach_free, NULL);
702 decarta_route_free_list(GList *route_list)
704 g_return_if_fail(route_list);
705 g_list_foreach(route_list, (GFunc)__decarta_free_route_list, NULL);
706 g_list_free(route_list);
711 void route_callback(DecartaError error,
712 const gchar *req_id_str,
713 const DecartaRoute *route,
714 const gchar * error_code,
715 const gchar * error_msg,
718 LocationError loc_error = LOCATION_ERROR_NONE;
719 DecartaData* data = (DecartaData*)user_data;
720 g_return_if_fail(data);
722 GList *route_list = NULL;
723 LocationPosition *origin = (LocationPosition *)data->userdata2;
724 LocationPosition *destination = (LocationPosition *)data->userdata3;
726 if (error == DECARTA_ERROR_NONE) {
727 DECARTA_LOGD("route_callback: success");
728 route_list = get_location_route_list_from_decarta_route(route, origin, destination);
731 DECARTA_LOGD("route_callback: failed");
732 loc_error = convert_decarta_error_to_location_error (error);
734 if (data->route_cb) {
735 gchar *code = g_strdup(error_code);
736 gchar *msg = g_strdup(error_msg);
737 data->route_cb(loc_error, req_id, route_list, code, msg, data->userdata);
741 if (route_list) decarta_route_free_list(route_list);
742 if (origin) location_position_free(origin);
743 if (destination) location_position_free(destination);
748 get_geocode (gpointer handle,
749 const LocationAddress *addr,
750 const LocationMapPref *svc_pref,
751 GList **position_list,
752 GList **accuracy_list)
754 DECARTA_LOGD("get_geocode");
755 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
756 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
757 g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER);
758 g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER);
761 GList *geocode_list = NULL;
762 LocationPosition *pos = NULL;
763 LocationAccuracy *acc = NULL;
766 char *password = NULL;
767 ID = location_map_pref_get_property(svc_pref, "ID");
768 password = location_map_pref_get_property(svc_pref, "PASSWORD");
769 set_config(ID, password, NULL, NULL);
771 char *language_code = NULL;
772 char *country_code = NULL;
773 language_code = location_map_pref_get_language(svc_pref);
774 country_code = location_map_pref_get_country(svc_pref);
775 if (language_code == NULL || country_code == NULL) {
776 gchar tmp_country[3] = "";
777 gchar tmp_language[3] = "";
778 get_lang(tmp_country, tmp_language);
779 if (country_code == NULL) {
780 country_code = g_strdup(tmp_country);
782 if (language_code == NULL) {
783 language_code = g_strdup(tmp_language);
787 DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr);
788 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr);
789 decarta_formed_address_free (deca_formed_addr);
790 int ret = decarta_search_geocode(deca_addr, &geocode_list);
791 decarta_address_free (deca_addr);
793 if (ret == DECARTA_ERROR_NONE) {
794 // libslp-location getting multi addresses.
795 /* can't change the geocode_list for del */
796 GList *tmp_geocode_list = (GList *)geocode_list;
797 const DecartaGeocode *geocode = NULL;
798 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
801 pos = get_location_pos_from_decarta_pos (geocode->pos);
802 acc = get_location_acc_from_location_addr (addr);
804 DECARTA_LOGD("location decarta plugin: get_geocode %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
806 *position_list = g_list_append (*position_list, (gpointer)pos);
807 *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc);
809 if (!tmp_geocode_list) break;
810 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
812 decarta_geocode_list_free (geocode_list);
814 return convert_decarta_error_to_location_error (ret);
818 decarta_idle_geocode_cb (gpointer data)
820 decarta_IdleData* idle_data = (decarta_IdleData*)data;
821 if (idle_data == NULL || idle_data->decarta_data == NULL) {
822 g_printf("idle_data or decarta_data is NULL\n");
826 DecartaData *deca_data = (DecartaData *)idle_data->decarta_data;
827 int err = decarta_search_geocode_async(idle_data->addr, idle_data->geocode_cb, deca_data, &deca_data->handle);
828 async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle);
829 if (DECARTA_ERROR_NONE != err) {
830 g_printf("Decarta Geocode Failed: %d\n", err);
832 // call position_cb() to return the error code, and free DecartaData
833 if (idle_data->geocode_cb) {
834 idle_data->geocode_cb (err, NULL, idle_data->decarta_data);
837 decarta_address_free (idle_data->addr);
844 get_geocode_async (gpointer handle,
845 const LocationAddress * addr,
846 const LocationMapPref *svc_pref,
847 LocationPositionCB callback,
850 DECARTA_LOGD("get_geocode_async");
851 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
852 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
853 g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER);
856 char *password = NULL;
857 ID = location_map_pref_get_property(svc_pref, "ID");
858 password = location_map_pref_get_property(svc_pref, "PASSWORD");
859 set_config(ID, password, NULL, NULL);
861 DecartaData* data = g_new0(DecartaData, 1);
863 char *language_code = NULL;
864 char *country_code = NULL;
865 language_code = location_map_pref_get_language(svc_pref);
866 country_code = location_map_pref_get_country(svc_pref);
867 if (language_code == NULL || country_code == NULL) {
868 gchar tmp_country[3] = "";
869 gchar tmp_language[3] = "";
870 get_lang(tmp_country, tmp_language);
871 if (country_code == NULL) {
872 country_code = g_strdup(tmp_country);
874 if (language_code == NULL) {
875 language_code = g_strdup(tmp_language);
879 DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr);
880 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr);
881 decarta_formed_address_free (deca_formed_addr);
882 data->pos_cb = callback;
883 data->userdata = (gpointer)userdata;
884 data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr);
886 // should call decarta_search_geocode_async in idle, OR request may be missed
887 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
888 idle_data->addr = deca_addr;
889 idle_data->geocode_cb = position_cb;
890 idle_data->decarta_data = data;
891 g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data);
893 return LOCATION_ERROR_NONE;
897 get_geocode_freetext(gpointer handle,
899 const LocationMapPref *svc_pref,
900 GList **position_list,
901 GList **accuracy_list)
903 DECARTA_LOGD ("get_geocode_freetext");
904 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
905 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
906 g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER);
907 g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER);
910 GList *geocode_list = NULL;
911 LocationPosition *pos = NULL;
912 LocationAccuracy *acc = NULL;
915 char *password = NULL;
916 ID = location_map_pref_get_property(svc_pref, "ID");
917 password = location_map_pref_get_property(svc_pref, "PASSWORD");
918 set_config(ID, password, NULL, NULL);
920 char *language_code = NULL;
921 char *country_code = NULL;
922 language_code = location_map_pref_get_language(svc_pref);
923 country_code = location_map_pref_get_country(svc_pref);
924 if (language_code == NULL || country_code == NULL) {
925 gchar tmp_country[3] = "";
926 gchar tmp_language[3] = "";
927 get_lang(tmp_country, tmp_language);
928 if (country_code == NULL) {
929 country_code = g_strdup(tmp_country);
931 if (language_code == NULL) {
932 language_code = g_strdup(tmp_language);
936 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL);
937 int ret = decarta_search_geocode(deca_addr, &geocode_list);
938 decarta_address_free (deca_addr);
940 if (ret == DECARTA_ERROR_NONE) {
941 // libslp-location getting multi addresses.
942 /* can't change the geocode_list for del */
943 GList *tmp_geocode_list = (GList *)geocode_list;
944 const DecartaGeocode *geocode = NULL;
945 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
948 pos = get_location_pos_from_decarta_pos (geocode->pos);
949 if (geocode->addr) acc = get_location_acc_from_decarta_addr (geocode->addr);
950 else acc = get_location_acc_from_free_addr (addr);
952 DECARTA_LOGD("location decarta plugin: get_geocode_freetext %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude);
954 *position_list = g_list_append (*position_list, (gpointer)pos);
955 *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc);
957 if (!tmp_geocode_list) break;
958 tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode);
960 decarta_geocode_list_free (geocode_list);
962 return convert_decarta_error_to_location_error (ret);
967 get_geocode_freetext_async (gpointer handle,
969 const LocationMapPref *svc_pref,
970 LocationPositionCB callback,
973 DECARTA_LOGD("get_geocode_freetext_async");
974 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
975 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
976 g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER);
979 char *password = NULL;
980 ID = location_map_pref_get_property(svc_pref, "ID");
981 password = location_map_pref_get_property(svc_pref, "PASSWORD");
982 set_config(ID, password, NULL, NULL);
984 char *language_code = NULL;
985 char *country_code = NULL;
986 language_code = location_map_pref_get_language(svc_pref);
987 country_code = location_map_pref_get_country(svc_pref);
988 if (language_code == NULL || country_code == NULL) {
989 gchar tmp_country[3] = "";
990 gchar tmp_language[3] = "";
991 get_lang(tmp_country, tmp_language);
992 if (country_code == NULL) {
993 country_code = g_strdup(tmp_country);
995 if (language_code == NULL) {
996 language_code = g_strdup(tmp_language);
1000 DecartaData* data = g_new0(DecartaData, 1);
1001 DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL);
1002 data->pos_cb = callback;
1003 data->userdata = (gpointer)userdata;
1004 data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr);
1006 // should call decarta_search_geocode_async in idle, OR request may be missed
1007 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1008 idle_data->addr = deca_addr;
1009 idle_data->geocode_cb = position_cb;
1010 idle_data->decarta_data = data;
1011 g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data);
1013 return LOCATION_ERROR_NONE;
1017 get_reverse_geocode(gpointer handle,
1018 const LocationPosition *pos,
1019 const LocationMapPref *svc_pref,
1020 LocationAddress **addr,
1021 LocationAccuracy **accuracy)
1023 DECARTA_LOGD("get_reverse_geocode");
1024 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1025 g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
1026 g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER);
1027 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
1030 char *password = NULL;
1031 ID = location_map_pref_get_property(svc_pref, "ID");
1032 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1033 set_config(ID, password, NULL, NULL);
1035 DecartaGeocode *geocode = NULL;
1036 DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude);
1037 int ret = decarta_search_reverse_geocode(deca_pos, &geocode);
1038 decarta_position_free (deca_pos);
1040 if (ret == DECARTA_ERROR_NONE) {
1042 *addr = get_location_addr_from_decarta_addr (geocode->addr);
1043 *accuracy = get_location_acc_from_decarta_addr (geocode->addr);
1044 decarta_geocode_free (geocode);
1047 return convert_decarta_error_to_location_error (ret);
1051 decarta_idle_reverse_geocode_cb (gpointer data)
1053 DECARTA_LOGD("decarta_idle_reverse_geocode_cb");
1054 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1055 if (idle_data == NULL || idle_data->decarta_data == NULL) {
1056 DECARTA_LOGD("idle_data or decarta_data is NULL");
1060 DecartaData *deca_data = (DecartaData *)idle_data->decarta_data;
1061 int err = decarta_search_reverse_geocode_async (idle_data->pos, idle_data->reverse_geocode_cb, deca_data, &deca_data->handle);
1062 async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle);
1063 if (DECARTA_ERROR_NONE != err) {
1064 DECARTA_LOGD("Decarta Reverse Geocode Failed: %d", err);
1066 // call address_cb() to return the error code, and free DecartaData
1067 if (idle_data->reverse_geocode_cb) {
1068 idle_data->reverse_geocode_cb (err, NULL, idle_data->decarta_data);
1071 decarta_position_free (idle_data->pos);
1077 get_reverse_geocode_async (gpointer handle,
1078 const LocationPosition *pos,
1079 const LocationMapPref *svc_pref,
1080 LocationAddressCB callback,
1083 DECARTA_LOGD("get_reverse_geocode_async");
1084 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1085 g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER);
1086 g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER);
1089 char *password = NULL;
1090 ID = location_map_pref_get_property(svc_pref, "ID");
1091 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1092 set_config(ID, password, NULL, NULL);
1094 DecartaData* data = g_new0(DecartaData, 1);
1095 data->addr_cb = callback;
1096 data->userdata = (gpointer)userdata;
1097 DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude);
1099 // should call decarta_search_reverse_geocode_async in idle, OR request may be missed
1100 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1101 idle_data->pos= deca_pos;
1102 idle_data->reverse_geocode_cb= address_cb;
1103 idle_data->decarta_data = data;
1104 g_idle_add((GSourceFunc)decarta_idle_reverse_geocode_cb, (gpointer)idle_data);
1106 return LOCATION_ERROR_NONE;
1110 static DecartaPOIPrefSortOrder
1111 decarta_get_sort_order(LocationPOIPrefSortOrder order)
1113 if (order == LOCATION_POI_PREF_SO_ASC) {
1114 return DECARTA_POI_PREF_SO_ASC;
1115 } else if (order == LOCATION_POI_PREF_SO_DESC) {
1116 return DECARTA_POI_PREF_SO_DESC;
1118 return DECARTA_POI_PREF_SO_NONE;
1122 //to make the request_id unique int, not start with 0
1123 static guint request_id = 1;
1126 decarta_idle_directory_cb (gpointer data)
1128 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1129 if (idle_data == NULL) {
1130 g_printf( "decarta_IdleData is NULL\n");
1134 int err = decarta_search_directory_async (idle_data->dir_request, idle_data->dir_cb, idle_data->decarta_data);
1135 if (DECARTA_ERROR_NONE != err) {
1136 g_printf( "Decarta Directory Failed: %d\n", err);
1138 // call landmark_cb() to return the error code, and free DecartaData
1139 if (idle_data->dir_cb) {
1140 char req_id_str[256];
1141 g_snprintf(req_id_str, 256, "%d", idle_data->request_id);
1142 idle_data->dir_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data);
1145 decarta_directory_request_free (idle_data->dir_request);
1150 int search_poi(gpointer handle,
1151 const LocationPOIFilter *filter,
1152 const LocationPosition *position,
1153 const LocationMapPref *svc_pref,
1154 const LocationPOIPreference *pref,
1159 DECARTA_LOGD("location decarta plugin: search_poi");
1160 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1161 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1162 g_return_val_if_fail (position, LOCATION_ERROR_PARAMETER);
1163 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1164 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1165 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1168 char *password = NULL;
1169 ID = location_map_pref_get_property(svc_pref, "ID");
1170 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1171 set_config(ID, password, NULL, NULL);
1173 DecartaData* data = g_new0(DecartaData, 1);
1174 DecartaPosition *pos = decarta_position_new (position->latitude, position->longitude);
1175 *req_id = request_id++;
1176 // POI property: keyword, brand, type, description, URL => CATEGORY, KEYWORD, POIName
1177 const char *type = location_poi_filter_get(filter, "CATEGORY");
1178 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1179 const char *poi_name = location_poi_filter_get(filter, "POIName");
1180 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1181 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1182 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1183 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST,
1184 DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 0, *req_id);
1185 decarta_position_free (pos);
1186 decarta_poi_property_free (property);
1187 decarta_poi_preference_free(poi_pref);
1191 data->userdata = (gpointer)user_data;
1193 // should call decarta_search_directory_async in idle, OR request may be missed
1194 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1195 idle_data->dir_request = dir_request;
1196 idle_data->dir_cb = landmark_cb;
1197 idle_data->decarta_data = data;
1198 idle_data->request_id = request_id;
1199 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1201 return LOCATION_ERROR_NONE;
1204 int search_poi_by_area(gpointer handle,
1205 const LocationPOIFilter *filter,
1206 const LocationBoundary *boundary,
1207 const LocationMapPref *svc_pref,
1208 const LocationPOIPreference *pref,
1213 DECARTA_LOGD("location decarta plugin: search_poi_by_area");
1214 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1215 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1216 g_return_val_if_fail (boundary, LOCATION_ERROR_PARAMETER);
1217 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1218 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1219 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1222 char *password = NULL;
1223 ID = location_map_pref_get_property(svc_pref, "ID");
1224 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1225 set_config(ID, password, NULL, NULL);
1227 if (boundary->type == LOCATION_BOUNDARY_CIRCLE) {
1228 DecartaData* data = g_new0(DecartaData, 1);
1229 DecartaPosition *pos = decarta_position_new (boundary->circle.center->latitude, boundary->circle.center->longitude);
1230 double distance = boundary->circle.radius;
1231 DECARTA_LOGD("search_poi_by_area: Circle lat [%lf], lon [%lf], radius [%f]",
1232 boundary->circle.center->latitude,
1233 boundary->circle.center->longitude,
1235 *req_id = request_id++;
1236 const char *type = location_poi_filter_get(filter, "CATEGORY");
1237 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1238 const char *poi_name = location_poi_filter_get(filter, "POIName");
1239 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1240 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1241 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1242 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE,
1243 DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, distance, *req_id);
1244 decarta_position_free (pos);
1245 decarta_poi_property_free (property);
1246 decarta_poi_preference_free(poi_pref);
1249 data->userdata = (gpointer)user_data;
1251 // should call decarta_search_directory_async in idle, OR request may be missed
1252 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1253 idle_data->dir_request = dir_request;
1254 idle_data->dir_cb = landmark_cb;
1255 idle_data->decarta_data = data;
1256 idle_data->request_id = request_id;
1257 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1259 return LOCATION_ERROR_NONE;
1260 } else if (boundary->type == LOCATION_BOUNDARY_RECT) {
1261 return LOCATION_ERROR_NOT_AVAILABLE;
1262 } else if (boundary->type == LOCATION_BOUNDARY_POLYGON) {
1263 return LOCATION_ERROR_NOT_AVAILABLE;
1265 return LOCATION_ERROR_NOT_AVAILABLE;
1269 int search_poi_by_address(gpointer handle,
1270 const LocationPOIFilter *filter,
1271 const LocationAddress *addr,
1272 const LocationMapPref *svc_pref,
1273 const LocationPOIPreference *pref,
1278 DECARTA_LOGD("location decarta plugin: search_poi_by_addr");
1279 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1280 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1281 g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER);
1282 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1283 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1284 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1287 char *password = NULL;
1288 ID = location_map_pref_get_property(svc_pref, "ID");
1289 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1290 set_config(ID, password, NULL, NULL);
1292 char *language_code = NULL;
1293 char *country_code = NULL;
1294 language_code = location_map_pref_get_language(svc_pref);
1295 country_code = location_map_pref_get_country(svc_pref);
1296 if (language_code == NULL || country_code == NULL) {
1297 gchar tmp_country[3] = "";
1298 gchar tmp_language[3] = "";
1299 get_lang(tmp_country, tmp_language);
1300 if (country_code == NULL) {
1301 country_code = g_strdup(tmp_country);
1303 if (language_code == NULL) {
1304 language_code = g_strdup(tmp_language);
1308 DecartaData* data = g_new0(DecartaData, 1);
1310 // Fixme: landmark_type, landmark_name for decarta_formed_address_new ??
1311 DecartaFormedAddress *formed_addr = decarta_formed_address_new (addr->building_number, addr->street, addr->country_code,
1312 addr->state, addr->city, addr->district, addr->postal_code, NULL, NULL);
1314 *req_id = request_id++;
1316 DecartaAddress *decarta_addr = decarta_address_new (country_code, language_code, FALSE, NULL, formed_addr);
1317 decarta_formed_address_free (formed_addr);
1319 const char *type = location_poi_filter_get(filter, "CATEGORY");
1320 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1321 const char *poi_name = location_poi_filter_get(filter, "POIName");
1322 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1323 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1324 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1326 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS,
1327 DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, decarta_addr, NULL, property, 0, *req_id);
1328 decarta_address_free (decarta_addr);
1329 decarta_poi_property_free (property);
1330 decarta_poi_preference_free(poi_pref);
1333 data->userdata = (gpointer)user_data;
1335 // should call decarta_search_directory_async in idle, OR request may be missed
1336 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1337 idle_data->dir_request = dir_request;
1338 idle_data->dir_cb = landmark_cb;
1339 idle_data->decarta_data = data;
1340 idle_data->request_id = request_id;
1341 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1343 return LOCATION_ERROR_NONE;
1346 int search_poi_by_freeform(gpointer handle,
1347 const LocationPOIFilter *filter,
1348 const gchar *address,
1349 const LocationMapPref *svc_pref,
1350 const LocationPOIPreference *pref,
1355 DECARTA_LOGD("location decarta plugin: search_poi_by_freeformed_address");
1356 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1357 g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER);
1358 g_return_val_if_fail (address, LOCATION_ERROR_PARAMETER);
1359 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1360 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1361 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1364 char *password = NULL;
1365 ID = location_map_pref_get_property(svc_pref, "ID");
1366 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1367 set_config(ID, password, NULL, NULL);
1369 char *language_code = NULL;
1370 char *country_code = NULL;
1371 language_code = location_map_pref_get_language(svc_pref);
1372 country_code = location_map_pref_get_country(svc_pref);
1373 if (language_code == NULL || country_code == NULL) {
1374 gchar tmp_country[3] = "";
1375 gchar tmp_language[3] = "";
1376 get_lang(tmp_country, tmp_language);
1377 if (country_code == NULL) {
1378 country_code = g_strdup(tmp_country);
1380 if (language_code == NULL) {
1381 language_code = g_strdup(tmp_language);
1385 DecartaData* data = g_new0(DecartaData, 1);
1387 *req_id = request_id++;
1389 DecartaAddress *free_addr = decarta_address_new (country_code, language_code, TRUE, address, NULL);
1391 const char *type = location_poi_filter_get(filter, "CATEGORY");
1392 const char *keyword = location_poi_filter_get(filter, "KEYWORD");
1393 const char *poi_name = location_poi_filter_get(filter, "POIName");
1394 DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL);
1396 DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref),
1397 decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref));
1398 DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS,
1399 DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, free_addr, NULL, property, 0, *req_id);
1401 decarta_address_free (free_addr);
1402 decarta_poi_property_free (property);
1403 decarta_poi_preference_free(poi_pref);
1406 data->userdata = (gpointer)user_data;
1408 // should call decarta_search_directory_async in idle, OR request may be missed
1409 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1410 idle_data->dir_request = dir_request;
1411 idle_data->dir_cb = landmark_cb;
1412 idle_data->decarta_data = data;
1413 idle_data->request_id = request_id;
1414 g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data);
1416 return LOCATION_ERROR_NONE;
1419 int cancel_poi_request(gpointer handle,
1422 DECARTA_LOGD("location decarta plugin: cancel_poi_request");
1423 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1425 decarta_search_directory_async_cancel (req_id);
1426 return LOCATION_ERROR_NONE;
1430 __route_create_via_list (gpointer data,
1433 LocationPosition *via_loc_pos = (LocationPosition *)data;
1434 GList **via_geocode_list = (GList **)user_data;
1436 DecartaPosition *via_pos = decarta_position_new (via_loc_pos->latitude, via_loc_pos->longitude);
1437 *via_geocode_list = decarta_geocode_list_append (*via_geocode_list, decarta_geocode_new (via_pos, NULL));
1438 decarta_position_free (via_pos);
1441 static DecartaRoutePreference
1442 __get_route_type(const gchar *type)
1444 if (0 == g_strcmp0("FASTEST", type)) {
1445 return DECARTA_ROUTE_PREF_FASTEST;
1446 } else if (0 == g_strcmp0("SHORTEST", type)) {
1447 return DECARTA_ROUTE_PREF_SHORTEST;
1448 } else if (0 == g_strcmp0("PEDESTRIAN", type)) {
1449 return DECARTA_ROUTE_PREF_PEDESTRIAN;
1450 } else if (0 == g_strcmp0("AVOID_FREEWAYS", type)) {
1451 return DECARTA_ROUTE_PREF_AVOID_FREEWAYS;
1452 } else if (0 == g_strcmp0("NO_FREEWAYS", type)) {
1453 return DECARTA_ROUTE_PREF_NO_FREEWAYS;
1454 } else if (0 == g_strcmp0("MORE_FREEWAYS", type)) {
1455 return DECARTA_ROUTE_PREF_MORE_FREEWAYS;
1456 } else if (0 == g_strcmp0("IGNORE_PIPES", type)) {
1457 return DECARTA_ROUTE_PREF_IGNORE_PIPES;
1458 } else if (0 == g_strcmp0("EASY", type)) {
1459 return DECARTA_ROUTE_PREF_EASY;
1461 return DECARTA_ROUTE_PREF_NONE;
1466 decarta_idle_route_cb (gpointer data)
1468 decarta_IdleData* idle_data = (decarta_IdleData*)data;
1469 if (idle_data == NULL) {
1470 g_printf( "idle_data is NULL\n");
1474 int err = decarta_search_route_async (idle_data->route_request, idle_data->route_cb, idle_data->decarta_data);
1475 if (DECARTA_ERROR_NONE != err) {
1476 g_printf("Decarta Route Failed: %d\n", err);
1478 // call route_callback() to return the error code, and free DecartaData
1479 if (idle_data->route_cb) {
1480 char req_id_str[256];
1481 g_snprintf(req_id_str, 256, "%d", idle_data->request_id);
1482 idle_data->route_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data);
1485 decarta_route_request_free (idle_data->route_request);
1490 int request_route (gpointer handle,
1491 const LocationPosition *origin,
1492 const LocationPosition *destination,
1494 const LocationMapPref *svc_pref,
1495 const LocationRoutePreference *pref,
1497 const gpointer user_data,
1500 DECARTA_LOGD("location decarta plugin: request_route");
1501 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1502 g_return_val_if_fail (origin, LOCATION_ERROR_PARAMETER);
1503 g_return_val_if_fail (destination, LOCATION_ERROR_PARAMETER);
1504 g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER);
1505 g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER);
1506 g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER);
1509 char *password = NULL;
1510 ID = location_map_pref_get_property(svc_pref, "ID");
1511 password = location_map_pref_get_property(svc_pref, "PASSWORD");
1512 set_config(ID, password, NULL, NULL);
1514 char *language_code = NULL;
1515 char *maneuver_rules = NULL;
1516 language_code = location_map_pref_get_language(svc_pref);
1517 if (language_code == NULL) {
1518 gchar tmp_country[3] = "";
1519 gchar tmp_language[3] = "";
1520 get_lang(tmp_country, tmp_language);
1521 language_code = g_strdup(tmp_language);
1523 if (!g_strcmp0(language_code, "FR")) {
1524 maneuver_rules = g_strdup_printf("maneuver-rules-%s", language_code);
1526 maneuver_rules = g_strdup("maneuver-rules");
1529 char *dist_uit = NULL;
1530 dist_uit = location_map_pref_get_distance_unit(svc_pref);
1531 if (g_strcmp0(dist_uit, "KM") != 0 && g_strcmp0(dist_uit, "M") != 0 && g_strcmp0(dist_uit, "DM") != 0 &&
1532 g_strcmp0(dist_uit, "MI") != 0 && g_strcmp0(dist_uit, "YD") != 0 && g_strcmp0(dist_uit, "FT") != 0) {
1533 dist_uit = g_strdup("M");
1536 DecartaData* data = g_new0(DecartaData, 1);
1537 DecartaPosition *start_pos = decarta_position_new (origin->latitude, origin->longitude);
1538 DecartaPosition *end_pos = decarta_position_new (destination->latitude, destination->longitude);
1540 DecartaGeocode *start = decarta_geocode_new (start_pos, NULL);
1541 DecartaGeocode *end = decarta_geocode_new (end_pos, NULL);
1542 GList *via_geocode_list = NULL;
1543 GList *tmp_waypoint = (GList *)waypoint;
1545 g_list_foreach(tmp_waypoint, (GFunc)__route_create_via_list, &via_geocode_list);
1547 decarta_position_free (start_pos);
1548 decarta_position_free (end_pos);
1550 gboolean bbox_needed = FALSE;
1551 DecartaPosition *bbox_pos1 = NULL;
1552 DecartaPosition *bbox_pos2 = NULL;
1553 LocationBoundary *bbox = location_route_pref_get_bounding_box(pref);
1554 if (bbox && bbox->type == LOCATION_BOUNDARY_RECT) {
1555 bbox_pos1 = decarta_position_new(bbox->rect.left_top->latitude, bbox->rect.left_top->longitude);
1556 bbox_pos2 = decarta_position_new(bbox->rect.right_bottom->latitude, bbox->rect.right_bottom->longitude);
1560 float resolution = DEFAULT_ROUTE_RESOLUTION;
1561 char *reslolution_str = (char *)location_route_pref_get_property(pref, (gconstpointer)"resolution");
1562 if (reslolution_str) {
1563 resolution = (float)g_ascii_strtod(reslolution_str, NULL);
1566 *req_id = request_id++;
1567 DecartaRouteRequest *route_request = decarta_route_request_new (__get_route_type(location_route_pref_get_route_type(pref)),
1568 start, end, via_geocode_list, TRUE, TRUE,
1569 bbox_needed, bbox_pos1, bbox_pos2, TRUE, resolution, TRUE, *req_id, dist_uit, maneuver_rules);
1570 g_free (maneuver_rules);
1571 decarta_geocode_free (start);
1572 decarta_geocode_free (end);
1573 if (via_geocode_list) {
1574 decarta_geocode_list_free (via_geocode_list);
1575 via_geocode_list = NULL;
1578 decarta_position_free(bbox_pos1);
1581 decarta_position_free(bbox_pos2);
1584 data->route_cb = cb;
1585 data->userdata = (gpointer)user_data;
1586 data->userdata2 = (gpointer)location_position_copy(origin);
1587 data->userdata3 = (gpointer)location_position_copy(destination);
1589 // should call decarta_search_route_async in idle callback, OR request may be missed
1590 decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1);
1591 idle_data->route_request = route_request;
1592 idle_data->route_cb= route_callback;
1593 idle_data->decarta_data = data;
1594 idle_data->request_id = request_id;
1595 g_idle_add((GSourceFunc)decarta_idle_route_cb, (gpointer)idle_data);
1597 return LOCATION_ERROR_NONE;
1599 int cancel_route_request (gpointer handle,
1602 int ret = DECARTA_ERROR_NONE;
1604 DECARTA_LOGD("location decarta plugin: request_route");
1605 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1607 ret = decarta_search_route_async_cancel (req_id);
1608 if (ret != DECARTA_ERROR_NONE) {
1609 return convert_decarta_error_to_location_error(ret);
1612 return LOCATION_ERROR_NONE;
1616 is_supported_provider_capability (gpointer handle, LocationMapServiceType type)
1618 DECARTA_LOGD("location decarta plugin: is_supported_provider_capability");
1619 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1621 return g_capa_list[type];
1625 get_provider_capability_key (gpointer handle, LocationMapServiceType type, GList **key)
1627 DECARTA_LOGD("location decarta plugin: get_provider_capability_key");
1628 g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE);
1629 g_return_val_if_fail (key, LOCATION_ERROR_PARAMETER);
1631 gchar **str_key = NULL;
1632 int idx = 0, count = 0;
1633 gchar *available_key = NULL;
1636 case MAP_SERVICE_PREF_LANGUAGE:
1638 count = sizeof(key_lang) / sizeof(char *);
1639 g_printf("key_lang[%d], char *[%d]. Count [%d]", sizeof(key_lang), sizeof(char*), count);
1642 case MAP_SERVICE_PREF_PROPERTY:
1643 str_key = key_property;
1644 count = sizeof(key_property) / sizeof(char *);
1645 g_printf("key_property[%d], char *[%d]. Count [%d]", sizeof(key_property), sizeof(char*), count);
1647 case MAP_SERVICE_PREF_DISTANCE_UNIT:
1648 case MAP_SERVICE_ROUTE_DISTANCE_UNIT:
1650 count = sizeof(key_dist) / sizeof(char*);
1652 case MAP_SERVICE_POI_PREF_SORT_BY:
1653 str_key = key_poi_sort;
1654 count = sizeof(key_poi_sort) / sizeof (char*);
1656 case MAP_SERVICE_POI_PREF_PROPERTY:
1657 str_key = key_poi_prop;
1658 count = sizeof(key_poi_prop) / sizeof (char*);
1660 case MAP_SERVICE_POI_FILTER:
1661 str_key = key_poi_filter;
1662 count = sizeof(key_poi_filter) / sizeof (char*);
1664 case MAP_SERVICE_POI_FILTER_CATEGORY:
1665 str_key = key_poi_filter_category;
1666 count = sizeof(key_poi_filter_category) / sizeof (char*);
1668 case MAP_SERVICE_ROUTE_REQUEST_FEATURE_TO_AVOID:
1669 str_key = key_route_feature_to_avoid;
1670 count = sizeof(key_route_feature_to_avoid) / sizeof (char*);
1672 case MAP_SERVICE_ROUTE_PREF_TYPE:
1673 str_key = key_route_type;
1674 count = sizeof(key_route_type) / sizeof (char*);
1676 case MAP_SERVICE_ROUTE_PREF_TRANSPORT_MODE:
1677 str_key = key_route_trans_mode;
1678 count = sizeof(key_route_trans_mode) / sizeof (char*);
1687 return LOCATION_ERROR_NOT_FOUND;
1690 for (idx = 0; idx < count; idx++) {
1691 available_key = g_strdup (str_key[idx]);
1692 *key = g_list_append(*key, available_key);
1695 return LOCATION_ERROR_NONE;
1698 LOCATION_MODULE_API gpointer
1699 init (LocModServiceOps* ops)
1701 DECARTA_LOGD("init");
1702 g_return_val_if_fail(ops, NULL);
1703 gpointer handle = (gpointer)service_name;
1705 ops->get_service_name = get_service_name;
1706 ops->get_geocode = get_geocode;
1707 ops->get_geocode_freetext = get_geocode_freetext;
1708 ops->get_reverse_geocode = get_reverse_geocode;
1709 ops->get_geocode_async = get_geocode_async;
1710 ops->get_geocode_freetext_async = get_geocode_freetext_async;
1711 ops->get_reverse_geocode_async = get_reverse_geocode_async;
1713 ops->search_poi = search_poi;
1714 ops->search_poi_by_area = search_poi_by_area;
1715 ops->search_poi_by_address = search_poi_by_address;
1716 ops->search_poi_by_freeform = search_poi_by_freeform;
1717 ops->cancel_poi_request = cancel_poi_request;
1719 ops->request_route = request_route;
1720 ops->cancel_route_request = cancel_route_request;
1722 ops->is_supported_provider_capability = is_supported_provider_capability;
1723 ops->get_provider_capability_key = get_provider_capability_key;
1725 async_request_queue = g_slist_alloc();
1730 cancel_request (gpointer data, gpointer user_data)
1732 decarta_search_geocode_async_cancel(data);
1733 decarta_search_reverse_geocode_async_cancel(data);
1736 LOCATION_MODULE_API void
1737 shutdown (gpointer handle)
1739 DECARTA_LOGD("shutdown");
1740 g_return_if_fail(handle == (gpointer)service_name);
1742 g_slist_foreach (async_request_queue, cancel_request, NULL);
1744 g_slist_free(async_request_queue);