merge upstream
authorsangho park <sangho.g.park@samsung.com>
Fri, 8 Apr 2011 09:14:56 +0000 (18:14 +0900)
committersangho park <sangho.g.park@samsung.com>
Fri, 8 Apr 2011 09:14:56 +0000 (18:14 +0900)
Change-Id: Ieffeebb19a9b6163a4d4b8731d109be66cb9f218

src/bin/test_map.c
src/lib/Elementary.h.in
src/lib/elm_map.c

index 58f628a..ec4abcc 100644 (file)
@@ -4,6 +4,8 @@
 #endif
 #ifndef ELM_LIB_QUICKLAUNCH
 
+#define MARKER_MAX 1000
+
 typedef struct Marker_Data
 {
     const char *file;
@@ -15,6 +17,9 @@ static Elm_Map_Group_Class *itc_group1, *itc_group2, *itc_group_parking;
 
 static Evas_Object *rect;
 static int nb_elts;
+static Elm_Map_Marker *markers[MARKER_MAX];
+static Elm_Map_Marker *route_from, *route_to;
+static Elm_Map_Route *route;
 
 Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
 Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
@@ -30,6 +35,9 @@ Marker_Data data11= {PACKAGE_DATA_DIR"/images/wood_01.jpg"};
 
 Marker_Data data_parking= {PACKAGE_DATA_DIR"/images/parking.png"};
 
+static Evas_Object * _marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data);
+static Evas_Object * _group_icon_get(Evas_Object *obj, void *data);
+
 static void
 my_map_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
@@ -49,19 +57,63 @@ my_map_longpressed(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *eve
 }
 
 static void
-my_map_clicked_double(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+my_map_clicked_double(void *data, Evas_Object *obj, void *event_info)
 {
-   printf("clicked,double\n");
+   double lon, lat;
+   double flon, flat, tlon, tlat;
+   Evas_Coord ox, oy, x, y, w, h;
+   int zoom;
+   Evas_Event_Mouse_Up *down = (Evas_Event_Mouse_Up *)event_info;
+   if (!down) return;
+
+   evas_object_geometry_get(data, &ox, &oy, &w, &h);
+   zoom = elm_map_zoom_get(data);
+   if (zoom<5) return;
+   elm_map_geo_region_get(obj, &lon, &lat);
+   elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, zoom)*256, &x, &y);
+   x += down->output.x - (w / 2) - ox;
+   y += down->output.y - (h / 2) - oy;
+   elm_map_utils_convert_coord_into_geo(obj, x, y, pow(2.0, zoom)*256, &lon, &lat);
+
+   itc1 = elm_map_marker_class_new(data);
+
+   elm_map_marker_class_del_cb_set(itc1, NULL);
+
+   itc_group1 = elm_map_group_class_new(data);
+   elm_map_group_class_icon_cb_set(itc_group1, _group_icon_get);
+   elm_map_group_class_data_set(itc_group1, (void *)PACKAGE_DATA_DIR"/images/bubble.png");
+   elm_map_group_class_style_set(itc_group1, "empty");
+   elm_map_group_class_zoom_displayed_set(itc_group1, 5);
+
+   if (route_from && route_to)
+     {
+        elm_map_marker_remove(route_from);
+       route_from = NULL;
+        elm_map_marker_remove(route_to);
+       route_to = NULL;
+        elm_map_route_remove(route);
+     }
+
+   if (!route_from) route_from = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
+   else route_to = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
+
+   if (route_from && route_to)
+     {
+        elm_map_marker_region_get(route_from, &flon, &flat);
+        elm_map_marker_region_get(route_to, &tlon, &tlat);
+        route = elm_map_route_add(data, ELM_MAP_ROUTE_TYPE_MOTOCAR, ELM_MAP_ROUTE_METHOD_FASTEST, flon, flat, tlon, tlat);
+        elm_map_route_color_set(route, 255, 0, 0, 255);
+     }
 }
 
 static void
-my_map_load_detail(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+my_map_load_detail(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    printf("load,detail\n");
 }
 
 static void
-my_map_loaded_detail(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+my_map_loaded_detail(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    printf("loaded,detail\n");
 }
@@ -125,12 +177,33 @@ my_map_downloaded(void *data, Evas_Object *obj __UNUSED__, void *event_info __UN
 }
 
 static void
+my_map_route_load(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   printf("route_load\n");
+ }
+
+static void
+my_map_route_loaded(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   double d;
+   const char *w, *n;
+   d = elm_map_route_distance_get(route);
+   printf("route distance = %lf km\n", d);
+
+   w = elm_map_route_waypoint_get(route);
+   if (w) printf("[waypoints]\n%s\n", w);
+
+   n = elm_map_route_node_get(route);
+   if (n) printf("[nodes]\n%s\n", n);
+}
+
+static void
 my_bt_show_reg(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Eina_Bool b = elm_map_paused_get(data);
    elm_map_paused_set(data, EINA_TRUE);
    elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
-   elm_map_geo_region_show(data, 2.352, 48.857);
+   elm_map_geo_region_show(data, 126.977969, 37.566535);
    elm_map_zoom_set(data, 18);
    elm_map_paused_set(data, b);
 }
@@ -138,7 +211,7 @@ my_bt_show_reg(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSE
 static void
 my_bt_bring_reg(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   elm_map_geo_region_bring_in(data, 2.352, 48.857);
+   elm_map_geo_region_bring_in(data, 126.977969, 37.566535);
 }
 
 static void
@@ -220,13 +293,14 @@ my_bt_source_module(void *data, Evas_Object *obj __UNUSED__, void *event_info __
 static void
 my_bt_add(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-    int i;
-    Elm_Map_Group_Class *g_clas;
-    Elm_Map_Marker_Class *m_clas;
-    Marker_Data *d = &data7;
+   int i;
+   Elm_Map_Group_Class *g_clas;
+   Elm_Map_Marker_Class *m_clas;
+   Marker_Data *d = &data7;
 
-    for(i =0; i<1000; i++)
-    {
+   if (*markers) return;
+   for(i =0; i<MARKER_MAX; i++)
+     {
         d = &data7;
 
         int r1 = rand() % (180*2*100);
@@ -238,28 +312,39 @@ my_bt_add(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
         else r2 = r2 - 85*100;
 
         int style = rand() % 3;
-        if(!style)
-            m_clas = itc1;
-        else if(style == 1)
-            m_clas = itc2;
+        if (!style) m_clas = itc1;
+        else if (style == 1) m_clas = itc2;
         else
-        {
-            m_clas = itc_parking;
-            d = &data_parking;
-        }
-
-       style = rand() % 2;
-       if (!style)
-         g_clas = itc_group1;
-       else
-         g_clas = itc_group2;
-
-       elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d); 
+          {
+             m_clas = itc_parking;
+             d = &data_parking;
+          }
+
+        style = rand() % 2;
+        if (!style) g_clas = itc_group1;
+       else g_clas = itc_group2;
+
+       markers[i] = elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d);
     }
-    nb_elts+=1000;
+    nb_elts += 1000;
     printf("nb elements: %d\n", nb_elts);
 }
 
+static void
+my_bt_remove(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   int i;
+
+   for (i = 0; i<MARKER_MAX; i++)
+     { 
+        if (markers[i])
+          {
+             elm_map_marker_remove(markers[i]);
+             markers[i] = NULL;
+          }
+     }
+}
+
 static Evas_Object *
 _marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
 {
@@ -440,7 +525,7 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_smart_callback_add(map, "clicked", my_map_clicked, win);
         evas_object_smart_callback_add(map, "press", my_map_press, win);
         evas_object_smart_callback_add(map, "longpressed", my_map_longpressed, win);
-        evas_object_smart_callback_add(map, "clicked,double", my_map_clicked_double, win);
+        evas_object_smart_callback_add(map, "clicked,double", my_map_clicked_double, map);
         evas_object_smart_callback_add(map, "load,detail", my_map_load_detail, win);
         evas_object_smart_callback_add(map, "loaded,detail", my_map_loaded_detail, win);
         evas_object_smart_callback_add(map, "zoom,start", my_map_zoom_start, win);
@@ -452,6 +537,8 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_smart_callback_add(map, "scroll,drag,stop", my_map_drag_stop, win);
         evas_object_smart_callback_add(map, "scroll", my_map_scroll, win);
         evas_object_smart_callback_add(map, "downloaded", my_map_downloaded, map);
+        evas_object_smart_callback_add(map, "route,load", my_map_route_load, map);
+        evas_object_smart_callback_add(map, "route,loaded", my_map_route_loaded, map);
 
         evas_object_show(map);
 
@@ -468,23 +555,39 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_show(bt);
 
         bt = elm_button_add(win);
+        elm_button_label_set(bt, "Z +");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_in, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.9, 0.1);
+        elm_table_pack(tb2, bt, 2, 0, 1, 1);
+        evas_object_show(bt);
+
+        bx = elm_box_add(win);
+        evas_object_show(bx);
+        evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bx, 0.5, 0.1);
+        elm_table_pack(tb2, bx, 1, 0, 1, 1);
+
+        //
+        bt = elm_button_add(win);
         elm_button_label_set(bt, "Add 1000 markers");
         evas_object_smart_callback_add(bt, "clicked", my_bt_add, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(bt, 0.5, 0.1);
-        elm_table_pack(tb2, bt, 1, 0, 1, 1);
         evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
 
         bt = elm_button_add(win);
-        elm_button_label_set(bt, "Z +");
-        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_in, map);
+        elm_button_label_set(bt, "remove 1000 markers");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_remove, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-        evas_object_size_hint_align_set(bt, 0.9, 0.1);
-        elm_table_pack(tb2, bt, 2, 0, 1, 1);
+        evas_object_size_hint_align_set(bt, 0.5, 0.1);
         evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+        //
 
         bt = elm_button_add(win);
-        elm_button_label_set(bt, "Show Paris");
+        elm_button_label_set(bt, "Show Seoul");
         evas_object_smart_callback_add(bt, "clicked", my_bt_show_reg, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(bt, 0.1, 0.5);
@@ -492,7 +595,7 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_show(bt);
 
         bt = elm_button_add(win);
-        elm_button_label_set(bt, "Bring Paris");
+        elm_button_label_set(bt, "Bring Seoul");
         evas_object_smart_callback_add(bt, "clicked", my_bt_bring_reg, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(bt, 0.9, 0.5);
index f3342b3..45b1741 100644 (file)
@@ -2178,14 +2178,46 @@ extern "C" {
         ELM_MAP_SOURCE_LAST
      } Elm_Map_Sources;
 
-   typedef struct _Elm_Map_Marker       Elm_Map_Marker;
-   typedef struct _Elm_Map_Marker_Class Elm_Map_Marker_Class;
-   typedef struct _Elm_Map_Group_Class  Elm_Map_Group_Class;
+   typedef enum _Elm_Map_Route_Sources
+     {
+        ELM_MAP_ROUTE_SOURCE_YOURS,
+        ELM_MAP_ROUTE_SOURCE_MONAV,
+        ELM_MAP_ROUTE_SOURCE_ORS,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_1,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_2,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_3,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_4,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_5,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_6,
+        ELM_MAP_ROUTE_SOURCE_MODULE,
+        ELM_MAP_ROUTE_SOURCE_LAST
+     } Elm_Map_Route_Sources;
+
+   typedef enum _Elm_Map_Route_Type
+     {
+        ELM_MAP_ROUTE_TYPE_MOTOCAR,
+        ELM_MAP_ROUTE_TYPE_BICYCLE,
+        ELM_MAP_ROUTE_TYPE_FOOT,
+        ELM_MAP_ROUTE_TYPE_LAST
+     } Elm_Map_Route_Type;
+
+   typedef enum _Elm_Map_Route_Method
+     {
+        ELM_MAP_ROUTE_METHOD_FASTEST,
+        ELM_MAP_ROUTE_METHOD_SHORTEST,
+        ELM_MAP_ROUTE_METHOD_LAST
+     } Elm_Map_Route_Method;
+
+   typedef struct _Elm_Map_Marker          Elm_Map_Marker;
+   typedef struct _Elm_Map_Marker_Class    Elm_Map_Marker_Class;
+   typedef struct _Elm_Map_Group_Class     Elm_Map_Group_Class;
+   typedef struct _Elm_Map_Route           Elm_Map_Route;
    typedef Evas_Object *(*ElmMapMarkerGetFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
    typedef void         (*ElmMapMarkerDelFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o);
    typedef Evas_Object *(*ElmMapMarkerIconGetFunc)  (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
    typedef Evas_Object *(*ElmMapGroupIconGetFunc)   (Evas_Object *obj, void *data);
    typedef char        *(*ElmMapSourceURLFunc)      (Evas_Object *obj, int x, int y, int zoom);
+   typedef char        *(*ElmMapRouteSourceURLFunc) (Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat);
 
    EAPI Evas_Object          *elm_map_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_zoom_set(Evas_Object *obj, int zoom) EINA_ARG_NONNULL(1);
@@ -2200,7 +2232,7 @@ extern "C" {
    EAPI void                  elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused) EINA_ARG_NONNULL(1);
    EAPI Eina_Bool             elm_map_paused_markers_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num) EINA_ARG_NONNULL(1, 2, 3);
-   EAPI void                 elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat);
+   EAPI void                  elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat);
    EAPI void                  elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y);
    EAPI Elm_Map_Marker       *elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *clas_group, void *data) EINA_ARG_NONNULL(1, 4, 5);
    EAPI void                  elm_map_max_marker_per_group_set(Evas_Object *obj, int max) EINA_ARG_NONNULL(1);
@@ -2225,13 +2257,23 @@ extern "C" {
    EAPI void                  elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_source_set(Evas_Object *obj, Elm_Map_Sources source) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source) EINA_ARG_NONNULL(1);
    EAPI Elm_Map_Sources       elm_map_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
-   EAPI void                  elm_map_source_custom_api_set(Elm_Map_Sources source, const char *label, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb) EINA_ARG_NONNULL(2, 5);
+   EAPI Elm_Map_Route_Sources elm_map_route_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_source_custom_api_set(Elm_Map_Sources source, const char *label, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb, ElmMapRouteSourceURLFunc route_url_cb) EINA_ARG_NONNULL(2, 5, 6);
    EAPI int                   elm_map_source_zoom_min_get(Elm_Map_Sources source);
    EAPI int                   elm_map_source_zoom_max_get(Elm_Map_Sources source);
    EAPI const char           *elm_map_source_name_get(Elm_Map_Sources source);
    EAPI void                  elm_map_user_agent_set(Evas_Object *obj, const char *user_agent) EINA_ARG_NONNULL(1, 2);
    EAPI const char           *elm_map_user_agent_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Elm_Map_Route        *elm_map_route_add(Evas_Object *obj, Elm_Map_Route_Type type, Elm_Map_Route_Method method, double flon, double flat, double tlon, double tlat) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_remove(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_color_set(Elm_Map_Route *route, int r, int g , int b, int a) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_color_get(Elm_Map_Route *route, int *r, int *g , int *b, int *a) EINA_ARG_NONNULL(1);
+   EAPI double                elm_map_route_distance_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+   EAPI const char           *elm_map_route_node_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+   EAPI const char           *elm_map_route_waypoint_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+
    /* smart callbacks called:
     * "clicked" - when image clicked
     * "press" - when mouse/finger held down initially on image
index e40b3ae..f750c68 100644 (file)
@@ -1,5 +1,6 @@
 #include <Elementary.h>
-#include <Ecore_File.h>
+#include "Ecore_Con.h"
+#include "Eina.h"
 #include "elm_priv.h"
 
 /**
  *
  * Signals that you can add callbacks for are:
  *
- * clicked - This is called when a user has clicked the map without dragging
- * around.
- *
- * press - This is called when a user has pressed down on the map.
- *
- * longpressed - This is called when a user has pressed down on the map for
- * a long time without dragging around.
- *
- * clicked,double - This is called when a user has double-clicked the photo.
- *
- * load,detail - Map detailed data load begins.
- *
- * loaded,detail - This is called when all parts of the map are loaded.
- *
- * zoom,start - Zoom animation started.
- *
- * zoom,stop - Zoom animation stopped.
- *
- * zoom,change - Zoom changed when using an auto zoom mode.
- *
- * scroll - the content has been scrolled (moved)
- *
- * scroll,anim,start - scrolling animation has started
- *
- * scroll,anim,stop - scrolling animation has stopped
- *
- * scroll,drag,start - dragging the contents around has started
- *
- * scroll,drag,stop - dragging the contents around has stopped
- *
- * downloaded - This is called when map images are downloaded
+ * "clicked" - This is called when a user has clicked the map without dragging
+ *             around.
+ * "press" - This is called when a user has pressed down on the map.
+ * "longpressed" - This is called when a user has pressed down on the map for
+ *                 a long time without dragging around.
+ * "clicked,double" - This is called when a user has double-clicked the photo.
+ * "load,detail" - Map detailed data load begins.
+ * "loaded,detail" - This is called when all parts of the map are loaded.
+ * "zoom,start" - Zoom animation started.
+ * "zoom,stop" - Zoom animation stopped.
+ * "zoom,change" - Zoom changed when using an auto zoom mode.
+ * "scroll" - the content has been scrolled (moved)
+ * "scroll,anim,start" - scrolling animation has started
+ * "scroll,anim,stop" - scrolling animation has stopped
+ * "scroll,drag,start" - dragging the contents around has started
+ * "scroll,drag,stop" - dragging the contents around has stopped
+ * "downloaded" - This is called when map images are downloaded
+ * "route,load" - This is called when route request begins
+ * "route,loaded" - This is called when route request ends
  *
  * TODO : doxygen
  */
@@ -54,11 +43,28 @@ typedef struct _Grid_Item Grid_Item;
 typedef struct _Marker_Group Marker_Group;
 typedef struct _Mod_Api Mod_Api;
 typedef struct _Event Event;
+typedef struct _Route_Node Route_Node;
+typedef struct _Route_Waypoint Route_Waypoint;
+typedef struct _Url_Data Url_Data;
+typedef struct _Route_Dump Route_Dump;
 
 #define DEST_DIR_ZOOM_PATH "/tmp/elm_map/%d/%d/"
 #define DEST_DIR_PATH DEST_DIR_ZOOM_PATH"%d/"
 #define DEST_FILE_PATH "%s%d.png"
 #define MOD_AS "map/api"
+#define DEST_XML_FILE "/tmp/elm_map-XXXXXX.xml"
+
+#define ROUTE_YOURS_URL "http://www.yournavigation.org/api/dev/route.php"
+#define ROUTE_TYPE_MOTORCAR "motocar"
+#define ROUTE_TYPE_BICYCLE "bicycle"
+#define ROUTE_TYPE_FOOT "foot"
+#define YOURS_DISTANCE "distance"
+#define YOURS_DESCRIPTION "description"
+#define YOURS_COORDINATES "coordinates"
+
+// TODO: fix monav & ors url 
+#define ROUTE_MONAV_URL "http://"
+#define ROUTE_ORS_URL "http:///"
 
 // Map sources
 // Currently the size of a tile must be 256*256
@@ -70,6 +76,8 @@ typedef struct _Map_Sources_Tab
    int zoom_min;
    int zoom_max;
    ElmMapSourceURLFunc url_cb;
+   Elm_Map_Route_Sources route_source;
+   ElmMapRouteSourceURLFunc route_url_cb;
 } Map_Sources_Tab;
 
 #define ZOOM_MAX 18
@@ -87,19 +95,42 @@ static char * _custom4_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoo
 static char * _custom5_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
 static char * _custom6_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
 
+static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+/*
+static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+ */
+static char *_route_custom1_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom2_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom3_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom4_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom5_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom6_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+/*
+static char *_route_module_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+ */
+
 static Map_Sources_Tab map_sources_tab[] =
 {
-     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb},
-     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb},
-     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb},
-     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, _custom2_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, _custom3_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, _custom4_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, _custom5_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, _custom6_url_cb},
-     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb}
+     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_1, _route_custom1_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, _custom2_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_2, _route_custom2_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, _custom3_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_3, _route_custom3_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, _custom4_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_4, _route_custom4_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, _custom5_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_5, _route_custom5_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, _custom6_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_6, _route_custom6_url_cb},
+     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb}
+};
+
+struct _Url_Data
+{
+   Ecore_Con_Url *con_url;
+
+   FILE *fd;
+   char *fname;
 };
 
 struct _Elm_Map_Marker_Class
@@ -108,14 +139,14 @@ struct _Elm_Map_Marker_Class
    int zoom_displayed;
 
    struct _Elm_Map_Marker_Class_Func {
-      ElmMapMarkerGetFunc get;
-      ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del()
-      ElmMapMarkerIconGetFunc icon_get;
+        ElmMapMarkerGetFunc get;
+        ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del()
+        ElmMapMarkerIconGetFunc icon_get;
    } func;
 
    struct { //this part is private, do not modify these values
-      Eina_Bool set : 1;
-      Evas_Coord edje_w, edje_h;
+        Eina_Bool set : 1;
+        Evas_Coord edje_w, edje_h;
    } priv;
 };
 
@@ -144,16 +175,16 @@ struct _Elm_Map_Group_Class
    Eina_Bool hide : 1;
 
    struct {
-      ElmMapGroupIconGetFunc icon_get;
+        ElmMapGroupIconGetFunc icon_get;
    } func;
-   
+
    struct { //this part is private, do not modify these values
-      Eina_Bool set : 1;
-      Evas_Coord edje_w, edje_h;
-      Evas_Coord edje_max_w, edje_max_h;
-      
-      Eina_List *objs_used;
-      Eina_List *objs_notused;
+        Eina_Bool set : 1;
+        Evas_Coord edje_w, edje_h;
+        Evas_Coord edje_max_w, edje_max_h;
+
+        Eina_List *objs_used;
+        Eina_List *objs_notused;
    } priv;
 };
 
@@ -177,6 +208,61 @@ struct _Marker_Group
    Eina_Bool delete_object : 1;
 };
 
+struct _Elm_Map_Route
+{
+   Widget_Data *wd;
+
+   Route_Node *n;
+   Route_Waypoint *w;
+   Ecore_Con_Url *con_url;
+
+   int type;
+   int method;
+   int x, y;
+   double flon, flat, tlon, tlat;
+
+   Eina_List *nodes, *path;
+   Eina_List *waypoint;
+
+   struct {
+      int node_count;
+      int waypoint_count;
+      const char *nodes;
+      const char *waypoints;
+      double distance; /* unit : km */
+   } info;
+
+   Eina_List *handlers;
+   Url_Data ud;
+
+   struct {
+      int r;
+      int g;
+      int b;
+      int a;
+   } color;
+
+   Eina_Bool inbound : 1;
+};
+
+struct _Route_Node
+{
+   Widget_Data *wd;
+
+   int idx;
+   struct {
+      double lon, lat;
+      char *address;
+   } pos;
+};
+
+struct _Route_Waypoint
+{
+   Widget_Data *wd;
+
+   const char *point;
+};
+
 struct _Grid_Item
 {
    Widget_Data *wd;
@@ -184,7 +270,7 @@ struct _Grid_Item
    //Evas_Object *txt;
    const char *file;
    struct {
-      int x, y, w, h;
+        int x, y, w, h;
    } src, out;
    Eina_Bool want : 1;
    Eina_Bool download : 1;
@@ -215,6 +301,7 @@ struct _Widget_Data
    Evas_Coord pan_x, pan_y, minw, minh;
 
    int id;
+   int fid;
    int zoom;
    Elm_Map_Zoom_Mode mode;
 
@@ -224,15 +311,15 @@ struct _Widget_Data
    Ecore_Animator *zoom_animator;
    double t_start, t_end;
    struct {
-      int w, h;
-      int ow, oh, nw, nh;
-      struct {
-         double x, y;
-      } spos;
+        int w, h;
+        int ow, oh, nw, nh;
+        struct {
+             double x, y;
+        } spos;
    } size;
    struct {
-      Eina_Bool show : 1;
-      Evas_Coord x, y ,w ,h;
+        Eina_Bool show : 1;
+        Evas_Coord x, y ,w ,h;
    } show;
    int tsize;
    int nosmooth;
@@ -244,10 +331,10 @@ struct _Widget_Data
    Eina_Bool paused : 1;
    Eina_Bool paused_markers : 1;
    Eina_Bool pinch_zoom : 1;
-   
+
    struct {
-      Eina_Bool enabled;
-      double lon, lat;
+        Eina_Bool enabled;
+        double lon, lat;
    } center_on;
 
    Ecore_Job *markers_place_job;
@@ -262,6 +349,7 @@ struct _Widget_Data
    Eina_List *markers_clas; // list of Elm_Map_Markers_Class*
 
    Elm_Map_Sources source;
+   Elm_Map_Route_Sources route_source;
    Elm_Module *m;
    Eina_List *s_event_list;
    int try_num;
@@ -269,6 +357,7 @@ struct _Widget_Data
 
    Eina_Hash *ua;
    const char *user_agent;
+   Eina_List *route;
 };
 
 struct _Mod_Api
@@ -288,19 +377,37 @@ struct _Pan
 struct _Event
 {
    int device;
-   
+
    struct {
-      Evas_Coord x, y;
+        Evas_Coord x, y;
    } prev;
-   
+
    Evas_Coord x, y, w, h;
-   
+
    Evas_Object *object;
    Ecore_Timer *hold_timer;
-   
+
    int pinch_dis;
 };
 
+struct _Route_Dump
+{
+   int id;
+   char *fname;
+   double distance;
+   char *description;
+   char *coordinates;
+};
+
+enum _Route_Xml_Attribute
+{
+   ROUTE_XML_NONE,
+   ROUTE_XML_DISTANCE,
+   ROUTE_XML_DESCRIPTION,
+   ROUTE_XML_COORDINATES,
+   ROUTE_XML_LAST
+} Route_Xml_Attibute;
+
 static int dis_old = 0;
 static const char *widtype = NULL;
 
@@ -318,22 +425,26 @@ static const char SIG_ZOOM_CHANGE[] = "zoom,change";
 static const char SIG_ZOOM_START[] = "zoom,start";
 static const char SIG_ZOOM_STOP[] = "zoom,stop";
 static const char SIG_DOWNLOADED[] = "downloaded";
+static const char SIG_ROUTE_LOAD[] = "route,load";
+static const char SIG_ROUTE_LOADED[] = "route,loaded";
 static const Evas_Smart_Cb_Description _signals[] = {
-  {SIG_CHANGED, ""},
-  {SIG_CLICKED, ""},
-  {SIG_CLICKED_DOUBLE, ""},
-  {SIG_LOADED_DETAIL, ""},
-  {SIG_LOAD_DETAIL, ""},
-  {SIG_LONGPRESSED, ""},
-  {SIG_PRESS, ""},
-  {SIG_SCROLL, ""},
-  {SIG_SCROLL_DRAG_START, ""},
-  {SIG_SCROLL_DRAG_STOP, ""},
-  {SIG_ZOOM_CHANGE, ""},
-  {SIG_ZOOM_START, ""},
-  {SIG_ZOOM_STOP, ""},
-  {SIG_DOWNLOADED, ""},
-  {NULL, NULL}
+       {SIG_CHANGED, ""},
+       {SIG_CLICKED, ""},
+       {SIG_CLICKED_DOUBLE, ""},
+       {SIG_LOADED_DETAIL, ""},
+       {SIG_LOAD_DETAIL, ""},
+       {SIG_LONGPRESSED, ""},
+       {SIG_PRESS, ""},
+       {SIG_SCROLL, ""},
+       {SIG_SCROLL_DRAG_START, ""},
+       {SIG_SCROLL_DRAG_STOP, ""},
+       {SIG_ZOOM_CHANGE, ""},
+       {SIG_ZOOM_START, ""},
+       {SIG_ZOOM_STOP, ""},
+       {SIG_DOWNLOADED, ""},
+       {SIG_ROUTE_LOAD, ""},
+       {SIG_ROUTE_LOADED, ""},
+       {NULL, NULL}
 };
 
 static void _pan_calculate(Evas_Object *obj);
@@ -374,16 +485,18 @@ static void _mouse_multi_down(void *data, Evas *evas, Evas_Object *obj, void *ev
 static void _mouse_multi_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
 static void _mouse_multi_move(void *data, Evas *evas, Evas_Object *obj, void *event_info);
 
+static void route_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
+
 static int
 get_multi_device(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *l;
    Event *ev;
-   
+
    EINA_LIST_FOREACH(wd->s_event_list, l, ev)
      {
-        if (ev->device) return ev->device;                             
+        if (ev->device) return ev->device;
      }
    return 0;
 }
@@ -401,9 +514,9 @@ create_event_object(void *data, Evas_Object *obj, int device)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    Event *ev = calloc(1, sizeof(Event));
-   
+
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL);
-   
+
    ev->object = obj;
    ev->device = device;
    evas_object_geometry_get(obj, &ev->x, &ev->y, &ev->w, &ev->h);
@@ -417,7 +530,7 @@ get_event_object(void *data, int device)
    Widget_Data *wd = elm_widget_data_get(data);
    Eina_List *l;
    Event *ev;
-   
+
    EINA_LIST_FOREACH(wd->s_event_list, l, ev)
      {
         if (ev->device == device) break;
@@ -507,6 +620,71 @@ module(Evas_Object *obj)
 }
 
 static void
+route_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   Eina_List *lr, *lp, *ln;
+   Route_Node *n;
+   Evas_Object *p;
+   Elm_Map_Route *r;
+   int nodes;
+   int x, y, rx, ry;
+   Evas_Coord size = pow(2.0, wd->zoom)*wd->tsize;
+
+   EINA_LIST_FOREACH(wd->route, lr, r)
+     {
+        EINA_LIST_FOREACH(r->path, lp, p)
+          {
+             evas_object_hide(p);
+          }
+
+        evas_object_geometry_get(wd->rect, &rx, &ry, NULL, NULL);
+        nodes = eina_list_count(r->nodes);
+
+        EINA_LIST_FOREACH(r->nodes, ln, n)
+          {
+             if ((!wd->zoom) || ((n->idx) &&
+                 ((n->idx % (int)ceil((double)nodes/(double)size*100.0))))) continue;
+             if (r->inbound)
+               {
+                  elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
+                  if ((x >= px - ow) && (x <= (px + ow*2)) &&
+                      (y >= py - oh) && (y <= (py + oh*2)))
+                    {
+                       x = x - px + rx;
+                       y = y - py + ry;
+
+                       p = eina_list_nth(r->path, n->idx);
+                       evas_object_line_xy_set(p, r->x, r->y, x, y);
+                       evas_object_color_set(p, r->color.r, r->color.g, r->color.b, r->color.a);
+                       evas_object_raise(p);
+                       evas_object_show(p);
+                       r->x = x;
+                       r->y = y;
+                    }
+                  else r->inbound = EINA_FALSE;
+               }
+             else
+               {
+                  elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
+                  if ((x >= px - ow) && (x <= (px + ow*2)) &&
+                      (y >= py - oh) && (y <= (py + oh*2)))
+                    {
+                       r->x = x - px + rx;
+                       r->y = y - py + ry;
+                       r->inbound = EINA_TRUE;
+                    }
+                  else r->inbound = EINA_FALSE;
+               }
+          }
+          r->inbound = EINA_FALSE;
+     }
+}
+
+static void
 rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -527,11 +705,11 @@ rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_C
                     ox + 0 - px + ax,
                     oy + 0 - py + ay);
    evas_object_resize(wd->rect, gw, gh);
-   
+
    if (wd->show.show)
      {
-       wd->show.show = EINA_FALSE;
-       elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
+        wd->show.show = EINA_FALSE;
+        elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
      }
 }
 
@@ -560,13 +738,13 @@ marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord
 
    if (wd->zoom != wd->marker_zoom)
      {
-       EINA_LIST_FREE(wd->cells_displayed, cell)
-         {
-            EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
-              {
-                 if (group->obj) _group_object_free(group);
-              }
-         }
+        EINA_LIST_FREE(wd->cells_displayed, cell)
+          {
+             EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
+               {
+                  if (group->obj) _group_object_free(group);
+               }
+          }
      }
    wd->marker_zoom = wd->zoom;
 
@@ -586,97 +764,97 @@ marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord
    //hide groups no more displayed
    EINA_LIST_FREE(wd->cells_displayed, cell)
      {
-       eina_matrixsparse_cell_position_get(cell, (unsigned long *)&y, (unsigned long *)&x);
-       if ((y < g_yy) || (y > g_yy + g_hh) || (x < g_xx) || (x > g_xx + g_ww))
-         {
-            EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
-              {
-                 if (group->obj) _group_object_free(group);
-              }
-         }
+        eina_matrixsparse_cell_position_get(cell, (unsigned long *)&y, (unsigned long *)&x);
+        if ((y < g_yy) || (y > g_yy + g_hh) || (x < g_xx) || (x > g_xx + g_ww))
+          {
+             EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
+               {
+                  if (group->obj) _group_object_free(group);
+               }
+          }
      }
 
    for (y = g_yy; y <= g_yy + g_hh; y++)
      {
-       for (x = g_xx; x <= g_xx + g_ww; x++)
-         {
-            if (!wd->markers[wd->zoom]) continue;
-            eina_matrixsparse_cell_idx_get(wd->markers[wd->zoom], y, x, &cell);
-            if (!cell) continue;
-            wd->cells_displayed = eina_list_append(wd->cells_displayed, cell);
-            markers = eina_matrixsparse_cell_data_get(cell);
-            EINA_LIST_FOREACH(markers, l, group)
-              {
-                 if (!group->markers) continue;
-                 if (group->clas->zoom_displayed > wd->zoom) continue;
-
-                 xx = group->x;
-                 yy = group->y;
-                 ww = group->w;
-                 hh = group->h;
-
-                 if (eina_list_count(group->markers) == 1)
-                   {
-                      Elm_Map_Marker *m = eina_list_data_get(group->markers);
-                      ww = m->clas->priv.edje_w;
-                      hh = m->clas->priv.edje_h;
-                   }
-
-                 if (ww <= 0) ww = 1;
-                 if (hh <= 0) hh = 1;
-
-                 if ((gw != g->w) && (g->w > 0))
-                   {
-                      tx = xx;
-                      xx = ((long long )gw * xx) / g->w;
-                      ww = (((long long)gw * (tx + ww)) / g->w) - xx;
-                   }
-                 if ((gh != g->h) && (g->h > 0))
-                   {
-                      ty = yy;
-                      yy = ((long long)gh * yy) / g->h;
-                      hh = (((long long)gh * (ty + hh)) / g->h) - yy;
-                   }
-
-                 if ((!group->clas->hide)
+        for (x = g_xx; x <= g_xx + g_ww; x++)
+          {
+             if (!wd->markers[wd->zoom]) continue;
+             eina_matrixsparse_cell_idx_get(wd->markers[wd->zoom], y, x, &cell);
+             if (!cell) continue;
+             wd->cells_displayed = eina_list_append(wd->cells_displayed, cell);
+             markers = eina_matrixsparse_cell_data_get(cell);
+             EINA_LIST_FOREACH(markers, l, group)
+               {
+                  if (!group->markers) continue;
+                  if (group->clas->zoom_displayed > wd->zoom) continue;
+
+                  xx = group->x;
+                  yy = group->y;
+                  ww = group->w;
+                  hh = group->h;
+
+                  if (eina_list_count(group->markers) == 1)
+                    {
+                       Elm_Map_Marker *m = eina_list_data_get(group->markers);
+                       ww = m->clas->priv.edje_w;
+                       hh = m->clas->priv.edje_h;
+                    }
+
+                  if (ww <= 0) ww = 1;
+                  if (hh <= 0) hh = 1;
+
+                  if ((gw != g->w) && (g->w > 0))
+                    {
+                       tx = xx;
+                       xx = ((long long )gw * xx) / g->w;
+                       ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+                    }
+                  if ((gh != g->h) && (g->h > 0))
+                    {
+                       ty = yy;
+                       yy = ((long long)gh * yy) / g->h;
+                       hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+                    }
+
+                  if ((!group->clas->hide)
                       && (xx-px+ax+ox >= ox) && (xx-px+ax+ox<= ox+ow)
                       && (yy-py+ay+oy >= oy) && (yy-py+ay+oy<= oy+oh))
-                   {
-                      if (!group->obj) _group_object_create(group);
-
-                      if (group->update_nbelems)
-                        {
-                           group->update_nbelems = EINA_FALSE;
-                           if (eina_list_count(group->markers) > 1)
-                             {
-                                snprintf(buf, sizeof(buf), "%d", eina_list_count(group->markers));
-                                edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", buf);
-                             }
-                           else
-                             edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", "");
-                        }
-                      evas_object_move(group->obj,
+                    {
+                       if (!group->obj) _group_object_create(group);
+
+                       if (group->update_nbelems)
+                         {
+                            group->update_nbelems = EINA_FALSE;
+                            if (eina_list_count(group->markers) > 1)
+                              {
+                                 snprintf(buf, sizeof(buf), "%d", eina_list_count(group->markers));
+                                 edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", buf);
+                              }
+                            else
+                              edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", "");
+                         }
+                       evas_object_move(group->obj,
                                         xx - px + ax + ox - ww/2,
                                         yy - py + ay + oy - hh/2);
-                      if ((!wd->paused_markers) || (group->update_resize))
-                        {
-                           group->update_resize = EINA_FALSE;
-                           evas_object_resize(group->obj, ww, hh);
-                        }
-                      if (group->update_raise)
-                        {
-                           group->update_raise = EINA_FALSE;
-                           evas_object_raise(group->obj);
-                           evas_object_show(group->obj);
-                        }
-                      if (group->bubble) _group_bubble_place(group);
-                   }
-                 else if (group->obj)
-                   {
-                      _group_object_free(group);
-                   }
-              }
-         }
+                       if ((!wd->paused_markers) || (group->update_resize))
+                         {
+                            group->update_resize = EINA_FALSE;
+                            evas_object_resize(group->obj, ww, hh);
+                         }
+                       if (group->update_raise)
+                         {
+                            group->update_raise = EINA_FALSE;
+                            evas_object_raise(group->obj);
+                            evas_object_show(group->obj);
+                         }
+                       if (group->bubble) _group_bubble_place(group);
+                    }
+                  else if (group->obj)
+                    {
+                       _group_object_free(group);
+                    }
+               }
+          }
      }
 }
 
@@ -688,7 +866,7 @@ grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord o
    int xx, yy, ww, hh;
 
    if (!wd) return;
-   
+
    ax = 0;
    ay = 0;
    gw = wd->size.w;
@@ -701,36 +879,36 @@ grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord o
 
    EINA_ITERATOR_FOREACH(it, cell)
      {
-       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
-
-       xx = gi->out.x;
-       yy = gi->out.y;
-       ww = gi->out.w;
-       hh = gi->out.h;
-       if ((gw != g->w) && (g->w > 0))
-         {
-            tx = xx;
-            xx = ((long long )gw * xx) / g->w;
-            ww = (((long long)gw * (tx + ww)) / g->w) - xx;
-         }
-       if ((gh != g->h) && (g->h > 0))
-         {
-            ty = yy;
-            yy = ((long long)gh * yy) / g->h;
-            hh = (((long long)gh * (ty + hh)) / g->h) - yy;
-         }
-       evas_object_move(gi->img,
+        Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+
+        xx = gi->out.x;
+        yy = gi->out.y;
+        ww = gi->out.w;
+        hh = gi->out.h;
+        if ((gw != g->w) && (g->w > 0))
+          {
+             tx = xx;
+             xx = ((long long )gw * xx) / g->w;
+             ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+          }
+        if ((gh != g->h) && (g->h > 0))
+          {
+             ty = yy;
+             yy = ((long long)gh * yy) / g->h;
+             hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+          }
+        evas_object_move(gi->img,
                          xx - px + ax + ox,
                          yy - py + ay + oy);
-        
-       evas_object_resize(gi->img, ww, hh);
 
-       /*evas_object_move(gi->txt,
-         xx - px + ax + ox,
-         yy - py + ay + oy);
+        evas_object_resize(gi->img, ww, hh);
+
+        /*evas_object_move(gi->txt,
+                           xx - px + ax + ox,
+                           yy - py + ay + oy);
 
-         evas_object_resize(gi->txt, ww, hh);
-         */
+          evas_object_resize(gi->txt, ww, hh);
+         */
      }
    eina_iterator_free(it);
 }
@@ -752,34 +930,34 @@ grid_clear(Evas_Object *obj, Grid *g)
 
    EINA_ITERATOR_FOREACH(it, cell)
      {
-       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
-       evas_object_del(gi->img);
-       //evas_object_del(gi->txt);
-
-       if (gi->want)
-         {
-            gi->want = EINA_FALSE;
-            wd->preload_num--;
-            if (!wd->preload_num)
-              {
-                 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
-                       "elm,state,busy,stop", "elm");
-                 evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL, NULL);
-              }
-         }
-
-       if (gi->job)
-         {
-            DBG("DOWNLOAD abort %s", gi->file);
-            ecore_file_download_abort(gi->job);
-            ecore_file_remove(gi->file);
-            gi->job = NULL;
-            wd->try_num--;
-         }
-       if (gi->file)
-         eina_stringshare_del(gi->file);
-        
-       free(gi);
+        Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+        evas_object_del(gi->img);
+        //evas_object_del(gi->txt);
+
+        if (gi->want)
+          {
+             gi->want = EINA_FALSE;
+             wd->preload_num--;
+             if (!wd->preload_num)
+               {
+                  edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                          "elm,state,busy,stop", "elm");
+                  evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL, NULL);
+               }
+          }
+
+        if (gi->job)
+          {
+             DBG("DOWNLOAD abort %s", gi->file);
+             ecore_file_download_abort(gi->job);
+             ecore_file_remove(gi->file);
+             gi->job = NULL;
+             wd->try_num--;
+          }
+        if (gi->file)
+          eina_stringshare_del(gi->file);
+
+        free(gi);
      }
    eina_matrixsparse_free(g->grid);
    eina_iterator_free(it);
@@ -796,7 +974,7 @@ _tile_update(Grid_Item *gi)
    evas_object_image_file_set(gi->img, gi->file, NULL);
    if (evas_object_image_load_error_get(gi->img) != EVAS_LOAD_ERROR_NONE)
      ecore_file_remove(gi->file);
-   
+
    evas_object_show(gi->img);
 
    //evas_object_text_text_set(gi->txt, gi->file);
@@ -806,9 +984,9 @@ _tile_update(Grid_Item *gi)
    gi->wd->preload_num--;
    if (!gi->wd->preload_num)
      {
-       edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr),
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr),
                                 "elm,state,busy,stop", "elm");
-       evas_object_smart_callback_call(gi->wd->obj, SIG_LOADED_DETAIL, NULL);
+        evas_object_smart_callback_call(gi->wd->obj, SIG_LOADED_DETAIL, NULL);
      }
 }
 
@@ -826,8 +1004,8 @@ _tile_downloaded(void *data, const char *file __UNUSED__, int status)
 
    if (status)
      {
-       DBG("Download failed %s (%d) ", gi->file, status);
-       ecore_file_remove(gi->file);
+        DBG("Download failed %s (%d) ", gi->file, status);
+        ecore_file_remove(gi->file);
      }
    else
      gi->wd->finish_num++;
@@ -876,7 +1054,7 @@ grid_load(Evas_Object *obj, Grid *g)
    if (!wd) return;
    evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
    evas_output_viewport_get(evas_object_evas_get(wd->obj), &cvx, &cvy, &cvw, &cvh);
-                               
+
    gw = wd->size.w;
    gh = wd->size.h;
 
@@ -888,71 +1066,71 @@ grid_load(Evas_Object *obj, Grid *g)
    if (size < (g->tsize / 2)) return; // else we will load to much tiles
 
    it = eina_matrixsparse_iterator_new(g->grid);
-   
+
    EINA_ITERATOR_FOREACH(it, cell)
      {
-       gi = eina_matrixsparse_cell_data_get(cell);
-
-       xx = gi->out.x;
-       yy = gi->out.y;
-       ww = gi->out.w;
-       hh = gi->out.h;
-
-       if ((gw != g->w) && (g->w > 0))
-         {
-            tx = xx;
-            xx = ((long long )gw * xx) / g->w;
-            ww = (((long long)gw * (tx + ww)) / g->w) - xx;
-         }
-       if ((gh != g->h) && (g->h > 0))
-         {
-            ty = yy;
-            yy = ((long long)gh * yy) / g->h;
-            hh = (((long long)gh * (ty + hh)) / g->h) - yy;
-         }
-
-        if (!ELM_RECTS_INTERSECT(xx - wd->pan_x + ox, 
+        gi = eina_matrixsparse_cell_data_get(cell);
+
+        xx = gi->out.x;
+        yy = gi->out.y;
+        ww = gi->out.w;
+        hh = gi->out.h;
+
+        if ((gw != g->w) && (g->w > 0))
+          {
+             tx = xx;
+             xx = ((long long )gw * xx) / g->w;
+             ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+          }
+        if ((gh != g->h) && (g->h > 0))
+          {
+             ty = yy;
+             yy = ((long long)gh * yy) / g->h;
+             hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+          }
+
+        if (!ELM_RECTS_INTERSECT(xx - wd->pan_x + ox,
                                  yy  - wd->pan_y + oy,
                                  ww, hh,
                                  cvx, cvy, cvw, cvh))
-         {
-            if (gi->want)
-              {
-                 evas_object_hide(gi->img);
-                 //evas_object_hide(gi->txt);
-                 evas_object_image_file_set(gi->img, NULL, NULL);
-                 gi->want = EINA_FALSE;
-                 gi->have = EINA_FALSE;
-                  
-                 if (gi->job)
-                   {
-                      DBG("DOWNLOAD abort %s", gi->file);
-                      ecore_file_download_abort(gi->job);
-                      ecore_file_remove(gi->file);
-                      gi->job = NULL;
+          {
+             if (gi->want)
+               {
+                  evas_object_hide(gi->img);
+                  //evas_object_hide(gi->txt);
+                  evas_object_image_file_set(gi->img, NULL, NULL);
+                  gi->want = EINA_FALSE;
+                  gi->have = EINA_FALSE;
+
+                  if (gi->job)
+                    {
+                       DBG("DOWNLOAD abort %s", gi->file);
+                       ecore_file_download_abort(gi->job);
+                       ecore_file_remove(gi->file);
+                       gi->job = NULL;
                        wd->try_num--;
-                   }
-                 gi->download = EINA_FALSE;
-                 wd->preload_num--;
-                 if (!wd->preload_num)
-                   {
-                      edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                    }
+                  gi->download = EINA_FALSE;
+                  wd->preload_num--;
+                  if (!wd->preload_num)
+                    {
+                       edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
                                                "elm,state,busy,stop", "elm");
-                      evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL,
-                                                      NULL);
-                   }
-
-              }
-            else if (gi->have)
-              {
-                 evas_object_hide(gi->img);
-                 //evas_object_hide(gi->txt);
-                 evas_object_image_preload(gi->img, 1);
-                 evas_object_image_file_set(gi->img, NULL, NULL);
-                 gi->have = EINA_FALSE;
-                 gi->want = EINA_FALSE;
-              }
-         }
+                       evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL,
+                                                       NULL);
+                    }
+
+               }
+             else if (gi->have)
+               {
+                  evas_object_hide(gi->img);
+                  //evas_object_hide(gi->txt);
+                  evas_object_image_preload(gi->img, 1);
+                  evas_object_image_file_set(gi->img, NULL, NULL);
+                  gi->have = EINA_FALSE;
+                  gi->want = EINA_FALSE;
+               }
+          }
      }
    eina_iterator_free(it);
 
@@ -970,97 +1148,97 @@ grid_load(Evas_Object *obj, Grid *g)
 
    for (y = yy; y <= yy + hh; y++)
      {
-       for (x = xx; x <= xx + ww; x++)
-         {
-            gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
-
-            if ((!gi) && (g != eina_list_data_get(wd->grids)))
-              continue;
-
-            if (!gi)
-              {
-                 gi = calloc(1, sizeof(Grid_Item));
-                 gi->src.x = x * g->tsize;
-                 gi->src.y = y * g->tsize;
-                 gi->src.w = g->tsize;
-                 gi->src.h = g->tsize;
-
-                 gi->out.x = gi->src.x;
-                 gi->out.y = gi->src.y;
-                 gi->out.w = gi->src.w;
-                 gi->out.h = gi->src.h;
-
-                 gi->wd = wd;
-                  
-                 gi->img = evas_object_image_add(evas_object_evas_get(obj));
-                 evas_object_image_scale_hint_set
-                    (gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
-                 evas_object_image_filled_set(gi->img, 1);
-                  
-                 evas_object_smart_member_add(gi->img, wd->pan_smart);
-                 elm_widget_sub_object_add(obj, gi->img);
-                 evas_object_pass_events_set(gi->img, EINA_TRUE);
-                 evas_object_stack_below(gi->img, wd->sep_maps_markers);
-                  
-                 /*gi->txt = evas_object_text_add(evas_object_evas_get(obj));
-                   evas_object_text_font_set(gi->txt, "Vera", 12);
-                   evas_object_color_set(gi->txt, 100, 100, 100, 255);
-                   evas_object_smart_member_add(gi->txt,
-                   wd->pan_smart);
-                   elm_widget_sub_object_add(obj, gi->txt);
-                   evas_object_pass_events_set(gi->txt, EINA_TRUE);
-                   */
-                 eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
-              }
-             
-            if ((!gi->have) && (!gi->download))
-              {
-                 char buf[PATH_MAX], buf2[PATH_MAX];
-                 char *source;
-                  
-                 gi->want = EINA_TRUE;
-                  
-                 snprintf(buf, sizeof(buf), DEST_DIR_PATH, wd->id, g->zoom, x);
-                 if (!ecore_file_exists(buf))
-                   ecore_file_mkpath(buf);
-                  
-                 snprintf(buf2, sizeof(buf2), DEST_FILE_PATH, buf, y);
-                  
-                 source = map_sources_tab[wd->source].url_cb(obj, x, y, g->zoom);
-                 if ((!source) || (strlen(source)==0)) continue;
-                  
-                 eina_stringshare_replace(&gi->file, buf2);
-
-                 if ((ecore_file_exists(buf2)) || (g == eina_list_data_get(wd->grids)))
-                   {
-                      gi->download = EINA_TRUE;
-                      wd->preload_num++;
-                      if (wd->preload_num == 1)
-                        {
-                           edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+        for (x = xx; x <= xx + ww; x++)
+          {
+             gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
+
+             if ((!gi) && (g != eina_list_data_get(wd->grids)))
+               continue;
+
+             if (!gi)
+               {
+                  gi = calloc(1, sizeof(Grid_Item));
+                  gi->src.x = x * g->tsize;
+                  gi->src.y = y * g->tsize;
+                  gi->src.w = g->tsize;
+                  gi->src.h = g->tsize;
+
+                  gi->out.x = gi->src.x;
+                  gi->out.y = gi->src.y;
+                  gi->out.w = gi->src.w;
+                  gi->out.h = gi->src.h;
+
+                  gi->wd = wd;
+
+                  gi->img = evas_object_image_add(evas_object_evas_get(obj));
+                  evas_object_image_scale_hint_set
+                     (gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+                  evas_object_image_filled_set(gi->img, 1);
+
+                  evas_object_smart_member_add(gi->img, wd->pan_smart);
+                  elm_widget_sub_object_add(obj, gi->img);
+                  evas_object_pass_events_set(gi->img, EINA_TRUE);
+                  evas_object_stack_below(gi->img, wd->sep_maps_markers);
+
+/*                gi->txt = evas_object_text_add(evas_object_evas_get(obj));
+                  evas_object_text_font_set(gi->txt, "Vera", 12);
+                  evas_object_color_set(gi->txt, 100, 100, 100, 255);
+                  evas_object_smart_member_add(gi->txt,
+                                               wd->pan_smart);
+                  elm_widget_sub_object_add(obj, gi->txt);
+                  evas_object_pass_events_set(gi->txt, EINA_TRUE);
+*/
+                  eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
+               }
+
+             if ((!gi->have) && (!gi->download))
+               {
+                  char buf[PATH_MAX], buf2[PATH_MAX];
+                  char *source;
+
+                  gi->want = EINA_TRUE;
+
+                  snprintf(buf, sizeof(buf), DEST_DIR_PATH, wd->id, g->zoom, x);
+                  if (!ecore_file_exists(buf))
+                    ecore_file_mkpath(buf);
+
+                  snprintf(buf2, sizeof(buf2), DEST_FILE_PATH, buf, y);
+
+                  source = map_sources_tab[wd->source].url_cb(obj, x, y, g->zoom);
+                  if ((!source) || (strlen(source)==0)) continue;
+
+                  eina_stringshare_replace(&gi->file, buf2);
+
+                  if ((ecore_file_exists(buf2)) || (g == eina_list_data_get(wd->grids)))
+                    {
+                       gi->download = EINA_TRUE;
+                       wd->preload_num++;
+                       if (wd->preload_num == 1)
+                         {
+                            edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
                                                     "elm,state,busy,start", "elm");
-                           evas_object_smart_callback_call(obj,
-                                                           SIG_LOAD_DETAIL,
-                                                           NULL);
-                        }
-                       
-                      if (ecore_file_exists(buf2))
-                        _tile_update(gi);
-                      else
-                        {
-                           DBG("DOWNLOAD %s \t in %s", source, buf2);
-                           ecore_file_download_full(source, buf2, _tile_downloaded, NULL, gi, &(gi->job), wd->ua);
+                            evas_object_smart_callback_call(obj,
+                                                            SIG_LOAD_DETAIL,
+                                                            NULL);
+                         }
+
+                       if (ecore_file_exists(buf2))
+                         _tile_update(gi);
+                       else
+                         {
+                            DBG("DOWNLOAD %s \t in %s", source, buf2);
+                            ecore_file_download_full(source, buf2, _tile_downloaded, NULL, gi, &(gi->job), wd->ua);
                             if (!gi->job)
                               DBG("Can't start to download %s", buf);
                             else
                               wd->try_num++;
-                        }
-                   }
-                 if (source) free(source);
-              }
-            else if (gi->have)
-              evas_object_show(gi->img);
-         }
+                         }
+                    }
+                  if (source) free(source);
+               }
+             else if (gi->have)
+               evas_object_show(gi->img);
+          }
      }
 }
 
@@ -1073,8 +1251,8 @@ grid_clearall(Evas_Object *obj)
    if (!wd) return;
    EINA_LIST_FREE(wd->grids, g)
      {
-       grid_clear(obj, g);
-       free(g);
+        grid_clear(obj, g);
+        free(g);
      }
 }
 
@@ -1088,15 +1266,15 @@ _smooth_update(Evas_Object *obj)
    if (!wd) return;
    EINA_LIST_FOREACH(wd->grids, l, g)
      {
-       Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
-       Eina_Matrixsparse_Cell *cell;
-        
-       EINA_ITERATOR_FOREACH(it, cell)
-         {
-            Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
-            evas_object_image_smooth_scale_set(gi->img, (!wd->nosmooth));
-         }
-       eina_iterator_free(it);
+        Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
+        Eina_Matrixsparse_Cell *cell;
+
+        EINA_ITERATOR_FOREACH(it, cell)
+          {
+             Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+             evas_object_image_smooth_scale_set(gi->img, (!wd->nosmooth));
+          }
+        eina_iterator_free(it);
      }
 }
 
@@ -1111,9 +1289,9 @@ _grid_raise(Grid *g)
 
    EINA_ITERATOR_FOREACH(it, cell)
      {
-       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
-       evas_object_raise(gi->img);
-       //evas_object_raise(gi->txt);
+        Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+        evas_object_raise(gi->img);
+        //evas_object_raise(gi->txt);
      }
    eina_iterator_free(it);
 }
@@ -1136,8 +1314,8 @@ _scr(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
    if (!wd) return;
    if (!wd->scr_timer)
      {
-       wd->nosmooth++;
-       if (wd->nosmooth == 1) _smooth_update(data);
+        wd->nosmooth++;
+        if (wd->nosmooth == 1) _smooth_update(data);
      }
    if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
    wd->scr_timer = ecore_timer_add(0.5, _scr_timeout, data);
@@ -1159,14 +1337,14 @@ zoom_do(Evas_Object *obj, double t)
 
    if (wd->center_on.enabled)
      {
-       elm_map_utils_convert_geo_into_coord(obj, wd->center_on.lon, wd->center_on.lat, wd->size.w, &xx, &yy);
-       xx -= ow / 2;
-       yy -= oh / 2;
+        elm_map_utils_convert_geo_into_coord(obj, wd->center_on.lon, wd->center_on.lat, wd->size.w, &xx, &yy);
+        xx -= ow / 2;
+        yy -= oh / 2;
      }
    else
      {
-       xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
-       yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
+        xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
+        yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
      }
 
    if (xx < 0) xx = 0;
@@ -1184,7 +1362,7 @@ zoom_do(Evas_Object *obj, double t)
    wd->calc_job = ecore_job_add(_calc_job, wd);
    if (t >= 1.0)
      {
-       return ECORE_CALLBACK_CANCEL;
+        return ECORE_CALLBACK_CANCEL;
      }
    return ECORE_CALLBACK_RENEW;
 }
@@ -1210,10 +1388,10 @@ _zoom_anim(void *data)
    go = zoom_do(obj, t);
    if (!go)
      {
-       wd->nosmooth--;
-       if (!wd->nosmooth) _smooth_update(data);
-       wd->zoom_animator = NULL;
-       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+        wd->nosmooth--;
+        if (!wd->nosmooth) _smooth_update(data);
+        wd->zoom_animator = NULL;
+        evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
      }
    return go;
 }
@@ -1235,7 +1413,7 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_inf
    Widget_Data *wd = elm_widget_data_get(data);
    Evas_Event_Mouse_Down *ev = event_info;
    Event *ev0;
-   
+
    ev0 = get_event_object(data, 0);
    if (ev0) return;
    ev0 = create_event_object(data, obj, 0);
@@ -1250,9 +1428,9 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_inf
    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
    else wd->on_hold = EINA_FALSE;
    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
-      evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, ev);
+     evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, ev);
    else
-      evas_object_smart_callback_call(data, SIG_PRESS, ev);
+     evas_object_smart_callback_call(data, SIG_PRESS, ev);
    wd->longpressed = EINA_FALSE;
    if (wd->long_timer) ecore_timer_del(wd->long_timer);
    wd->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
@@ -1278,7 +1456,7 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *
    int mdevice;
    Event *ev0;
    Event *ev1;
-   
+
    ev0 = get_event_object(data, 0);
    if (ev0)
      {
@@ -1297,8 +1475,8 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *
         else
           {
              ev1 = get_event_object(data, mdevice);
-             if (ev1) 
-                ev1->hold_timer = ecore_timer_add(0.35, _hold_timer_cb, ev1);
+             if (ev1)
+               ev1->hold_timer = ecore_timer_add(0.35, _hold_timer_cb, ev1);
           }
         destroy_event_object(data, ev0);
      }
@@ -1309,8 +1487,8 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *
    else wd->on_hold = EINA_FALSE;
    if (wd->long_timer)
      {
-       ecore_timer_del(wd->long_timer);
-       wd->long_timer = NULL;
+        ecore_timer_del(wd->long_timer);
+        wd->long_timer = NULL;
      }
    if (!wd->on_hold) evas_object_smart_callback_call(data, SIG_CLICKED, ev);
    wd->on_hold = EINA_FALSE;
@@ -1366,7 +1544,7 @@ _mouse_multi_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__
 
    dis_new = get_distance(ev0->prev.x, ev0->prev.y, ev->prev.x, ev->prev.y);
    zoom = wd->zoom;
-   
+
    if (dis_old)
      {
         if (((dis_old - dis_new) > 0) && 
@@ -1404,17 +1582,17 @@ _mouse_multi_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__,
         return;
      }
    dis_old = 0;
-   
+
    ev0 = get_event_object(data, 0);
    if (ev0)
-      ev0->hold_timer = ecore_timer_add(0.35, _hold_timer_cb, ev0);
+     ev0->hold_timer = ecore_timer_add(0.35, _hold_timer_cb, ev0);
    else
      {
         if (ev->hold_timer)
           {
              ecore_timer_del(ev->hold_timer);
              ev->hold_timer = NULL;
-          }   
+          }
      }
    destroy_event_object(data, ev);
 }
@@ -1425,12 +1603,12 @@ static Eina_Bool
 _hold_timer_cb(void *data)
 {
    Event *ev0 = data;
-   
+
    ev0->hold_timer = NULL;
    return ECORE_CALLBACK_CANCEL;
 }
 
-static void 
+static void
 _rect_resize_cb(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -1450,21 +1628,26 @@ _del_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *l;
    Event *ev;
+   Evas_Object *p;
+   Route_Node *n;
+   Route_Waypoint *w;
+   Ecore_Event_Handler *h;
+   Elm_Map_Route *r;
 
    if (!wd) return;
 
    EINA_LIST_FREE(wd->groups_clas, group_clas)
      {
-       if (group_clas->style)
-         eina_stringshare_del(group_clas->style);
-       free(group_clas);
+        if (group_clas->style)
+          eina_stringshare_del(group_clas->style);
+        free(group_clas);
      }
 
    EINA_LIST_FREE(wd->markers_clas, marker_clas)
      {
-       if (marker_clas->style)
-         eina_stringshare_del(marker_clas->style);
-       free(marker_clas);
+        if (marker_clas->style)
+          eina_stringshare_del(marker_clas->style);
+        free(marker_clas);
      }
 
    EINA_LIST_FOREACH(wd->s_event_list, l, ev)
@@ -1472,6 +1655,34 @@ _del_hook(Evas_Object *obj)
         destroy_event_object(obj, ev);
      }
 
+   EINA_LIST_FOREACH(wd->route, l, r)
+     {
+        EINA_LIST_FREE(r->path, p)
+          {
+             evas_object_del(p);
+          }
+
+        EINA_LIST_FREE(r->waypoint, w)
+          {
+             if (w->point) eina_stringshare_del(w->point);
+             free(w);
+          }
+
+        EINA_LIST_FREE(r->nodes, n)
+          {
+             if (n->pos.address) eina_stringshare_del(n->pos.address);
+             free(n);
+          }
+
+        EINA_LIST_FREE(r->handlers, h)
+          {
+             ecore_event_handler_del(h);
+          }
+
+        if (r->con_url) ecore_con_url_free(r->con_url);
+        if (r->info.nodes) eina_stringshare_del(r->info.nodes);
+        if (r->info.waypoints) eina_stringshare_del(r->info.waypoints);
+     }
    if (wd->calc_job) ecore_job_del(wd->calc_job);
    if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
    if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
@@ -1481,7 +1692,6 @@ _del_hook(Evas_Object *obj)
         Mod_Api *api = wd->m->api;
         if (api->obj_unhook) api->obj_unhook(obj);
      }
-   
    if (wd->user_agent) eina_stringshare_del(wd->user_agent);
    if (wd->ua) eina_hash_free(wd->ua);
 
@@ -1502,27 +1712,27 @@ _del_pre_hook(Evas_Object *obj)
    if (!wd) return;
    for (i = 0; i < ZOOM_MAX + 1; i++)
      {
-       if (!wd->markers[i]) continue;
-       Eina_Iterator *it = eina_matrixsparse_iterator_new(wd->markers[i]);
-       Eina_Matrixsparse_Cell *cell;
-        
-       EINA_ITERATOR_FOREACH(it, cell)
-         {
-            l =  eina_matrixsparse_cell_data_get(cell);
-            EINA_LIST_FREE(l, group)
-              {
-                 EINA_LIST_FREE(group->markers, marker)
-                   {
-                      evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+        if (!wd->markers[i]) continue;
+        Eina_Iterator *it = eina_matrixsparse_iterator_new(wd->markers[i]);
+        Eina_Matrixsparse_Cell *cell;
+
+        EINA_ITERATOR_FOREACH(it, cell)
+          {
+             l =  eina_matrixsparse_cell_data_get(cell);
+             EINA_LIST_FREE(l, group)
+               {
+                  EINA_LIST_FREE(group->markers, marker)
+                    {
+                       evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
                                                            _bubble_sc_hits_changed_cb, group);
-                      if (free_marker) free(marker);
-                   }
-                 free(group);
-              }
-            free_marker = EINA_FALSE;
-         }
-       eina_iterator_free(it);
-       eina_matrixsparse_free(wd->markers[i]);
+                       if (free_marker) free(marker);
+                    }
+                  free(group);
+               }
+             free_marker = EINA_FALSE;
+          }
+        eina_iterator_free(it);
+        eina_matrixsparse_free(wd->markers[i]);
      }
 
    evas_object_del(wd->sep_maps_markers);
@@ -1537,13 +1747,13 @@ _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
    if (!wd) return;
    if (elm_widget_focus_get(obj))
      {
-       edje_object_signal_emit(wd->obj, "elm,action,focus", "elm");
-       evas_object_focus_set(wd->obj, EINA_TRUE);
+        edje_object_signal_emit(wd->obj, "elm,action,focus", "elm");
+        evas_object_focus_set(wd->obj, EINA_TRUE);
      }
    else
      {
-       edje_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
-       evas_object_focus_set(wd->obj, EINA_FALSE);
+        edje_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
+        evas_object_focus_set(wd->obj, EINA_FALSE);
      }
 }
 
@@ -1553,7 +1763,7 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
-//   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+   //   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
    _sizing_eval(obj);
 }
 
@@ -1578,20 +1788,20 @@ _calc_job(void *data)
    minh = wd->size.h;
    if (wd->resized)
      {
-       wd->resized = 0;
-       if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
-         {
-            double tz = wd->zoom;
-            wd->zoom = 0.0;
-            elm_map_zoom_set(wd->obj, tz);
-         }
+        wd->resized = 0;
+        if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
+          {
+             double tz = wd->zoom;
+             wd->zoom = 0.0;
+             elm_map_zoom_set(wd->obj, tz);
+          }
      }
    if ((minw != wd->minw) || (minh != wd->minh))
      {
-       wd->minw = minw;
-       wd->minh = minh;
-       evas_object_smart_callback_call(wd->pan_smart, SIG_CHANGED, NULL);
-       _sizing_eval(wd->obj);
+        wd->minw = minw;
+        wd->minh = minh;
+        evas_object_smart_callback_call(wd->pan_smart, SIG_CHANGED, NULL);
+        _sizing_eval(wd->obj);
      }
    wd->calc_job = NULL;
    evas_object_smart_changed(wd->pan_smart);
@@ -1696,9 +1906,10 @@ _pan_calculate(Evas_Object *obj)
    rect_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
    EINA_LIST_FOREACH(sd->wd->grids, l, g)
      {
-       grid_load(sd->wd->obj, g);
-       grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
-       marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+        grid_load(sd->wd->obj, g);
+        grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+        marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+        if (!sd->wd->zoom_animator) route_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
      }
 }
 
@@ -1785,57 +1996,57 @@ _group_object_create(Marker_Group *group)
    if (group->obj) return;
    if ((!group->clas->priv.objs_notused) || (eina_list_count(group->markers) == 1))
      {
-       //set icon and style
-       if (eina_list_count(group->markers) == 1)
-         {
-            Elm_Map_Marker *m = eina_list_data_get(group->markers);
-            if (m->clas->style)
-              style = m->clas->style;
-             
-            if (m->clas->func.icon_get)
-              icon = m->clas->func.icon_get(group->wd->obj, m, m->data);
-             
-            group->delete_object = EINA_TRUE;
-         }
-       else
-         {
-            if (group->clas->style)
-              style = group->clas->style;
-             
-            if (group->clas->func.icon_get)
-              icon = group->clas->func.icon_get(group->wd->obj, group->clas->data);
-             
-            group->delete_object = EINA_FALSE;
-         }
-        
-       group->obj = elm_layout_add(group->wd->obj);
-       elm_layout_theme_set(group->obj, "map/marker", style, elm_widget_style_get(group->wd->obj));
-
-       if (icon) elm_layout_content_set(group->obj, "elm.icon", icon);
-        
-       evas_object_smart_member_add(group->obj, group->wd->pan_smart);
-       elm_widget_sub_object_add(group->wd->obj, group->obj);
-       evas_object_stack_above(group->obj, group->wd->sep_maps_markers);
-
-       if (!group->delete_object)
-         group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
-     }
-   else
-     {
-       group->delete_object = EINA_FALSE;
-        
-       group->obj = eina_list_data_get(group->clas->priv.objs_notused);
-       group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
-       group->clas->priv.objs_notused = eina_list_remove(group->clas->priv.objs_notused, group->obj);
-       evas_object_show(group->obj);
-     }
-
-   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb, group);
-   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb, group);
+        //set icon and style
+        if (eina_list_count(group->markers) == 1)
+          {
+             Elm_Map_Marker *m = eina_list_data_get(group->markers);
+             if (m->clas->style)
+               style = m->clas->style;
 
-   group->update_nbelems = EINA_TRUE;
-   group->update_resize = EINA_TRUE;
-   group->update_raise = EINA_TRUE;
+             if (m->clas->func.icon_get)
+               icon = m->clas->func.icon_get(group->wd->obj, m, m->data);
+
+             group->delete_object = EINA_TRUE;
+          }
+        else
+          {
+             if (group->clas->style)
+               style = group->clas->style;
+
+             if (group->clas->func.icon_get)
+               icon = group->clas->func.icon_get(group->wd->obj, group->clas->data);
+
+             group->delete_object = EINA_FALSE;
+          }
+
+        group->obj = elm_layout_add(group->wd->obj);
+        elm_layout_theme_set(group->obj, "map/marker", style, elm_widget_style_get(group->wd->obj));
+
+        if (icon) elm_layout_content_set(group->obj, "elm.icon", icon);
+
+        evas_object_smart_member_add(group->obj, group->wd->pan_smart);
+        elm_widget_sub_object_add(group->wd->obj, group->obj);
+        evas_object_stack_above(group->obj, group->wd->sep_maps_markers);
+
+        if (!group->delete_object)
+          group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
+     }
+   else
+     {
+        group->delete_object = EINA_FALSE;
+
+        group->obj = eina_list_data_get(group->clas->priv.objs_notused);
+        group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
+        group->clas->priv.objs_notused = eina_list_remove(group->clas->priv.objs_notused, group->obj);
+        evas_object_show(group->obj);
+     }
+
+   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb, group);
+   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb, group);
+
+   group->update_nbelems = EINA_TRUE;
+   group->update_resize = EINA_TRUE;
+   group->update_raise = EINA_TRUE;
 
    if (group->open) _group_bubble_create(group);
 }
@@ -1846,12 +2057,12 @@ _group_object_free(Marker_Group *group)
    if (!group->obj) return;
    if (!group->delete_object)
      {
-       group->clas->priv.objs_notused = eina_list_append(group->clas->priv.objs_notused, group->obj);
-       group->clas->priv.objs_used = eina_list_remove(group->clas->priv.objs_used, group->obj);
-       evas_object_hide(group->obj);
+        group->clas->priv.objs_notused = eina_list_append(group->clas->priv.objs_notused, group->obj);
+        group->clas->priv.objs_used = eina_list_remove(group->clas->priv.objs_used, group->obj);
+        evas_object_hide(group->obj);
 
-       edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb);
-       edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb);
+        edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb);
+        edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb);
      }
    else
      evas_object_del(group->obj);
@@ -1883,23 +2094,23 @@ _group_bubble_create(Marker_Group *group)
    evas_object_smart_member_add(group->bubble,
                                 group->wd->obj);
    elm_widget_sub_object_add(group->wd->obj, group->bubble);
-   
+
    _group_bubble_content_free(group);
    if (!_group_bubble_content_update(group))
      {
-       //no content, we can delete the bubble
-       _group_bubble_free(group);
-       return;
+        //no content, we can delete the bubble
+        _group_bubble_free(group);
+        return;
      }
-   
+
    group->rect = evas_object_rectangle_add(evas_object_evas_get(group->obj));
    evas_object_color_set(group->rect, 0, 0, 0, 0);
    evas_object_repeat_events_set(group->rect, EINA_TRUE);
    evas_object_smart_member_add(group->rect, group->wd->obj);
    elm_widget_sub_object_add(group->wd->obj, group->rect);
-   
+
    evas_object_event_callback_add(group->rect, EVAS_CALLBACK_MOUSE_UP, _group_bubble_mouse_up_cb, group);
-   
+
    _group_bubble_place(group);
 }
 
@@ -1919,41 +2130,41 @@ _group_bubble_content_update(Marker_Group *group)
 
    if (!group->sc)
      {
-       group->sc = elm_scroller_add(group->bubble);
-       elm_widget_style_set(group->sc, "map_bubble");
-       elm_scroller_content_min_limit(group->sc, EINA_FALSE, EINA_TRUE);
-       elm_scroller_policy_set(group->sc, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
-       elm_scroller_bounce_set(group->sc, _elm_config->thumbscroll_bounce_enable, EINA_FALSE);
-       edje_object_part_swallow(group->bubble, "elm.swallow.content", group->sc);
-       evas_object_show(group->sc);
-       evas_object_smart_member_add(group->sc,
+        group->sc = elm_scroller_add(group->bubble);
+        elm_widget_style_set(group->sc, "map_bubble");
+        elm_scroller_content_min_limit(group->sc, EINA_FALSE, EINA_TRUE);
+        elm_scroller_policy_set(group->sc, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
+        elm_scroller_bounce_set(group->sc, _elm_config->thumbscroll_bounce_enable, EINA_FALSE);
+        edje_object_part_swallow(group->bubble, "elm.swallow.content", group->sc);
+        evas_object_show(group->sc);
+        evas_object_smart_member_add(group->sc,
                                      group->wd->obj);
-       elm_widget_sub_object_add(group->wd->obj, group->sc);
-        
-       group->bx = elm_box_add(group->bubble);
-       evas_object_size_hint_align_set(group->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       evas_object_size_hint_weight_set(group->bx, 0.5, 0.5);
-       elm_box_horizontal_set(group->bx, EINA_TRUE);
-       evas_object_show(group->bx);
-        
-       elm_scroller_content_set(group->sc, group->bx);
-        
-       evas_object_event_callback_add(group->sc, EVAS_CALLBACK_RESIZE,
+        elm_widget_sub_object_add(group->wd->obj, group->sc);
+
+        group->bx = elm_box_add(group->bubble);
+        evas_object_size_hint_align_set(group->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        evas_object_size_hint_weight_set(group->bx, 0.5, 0.5);
+        elm_box_horizontal_set(group->bx, EINA_TRUE);
+        evas_object_show(group->bx);
+
+        elm_scroller_content_set(group->sc, group->bx);
+
+        evas_object_event_callback_add(group->sc, EVAS_CALLBACK_RESIZE,
                                        _bubble_sc_hits_changed_cb, group);
      }
-   
+
    EINA_LIST_FOREACH(group->markers, l, marker)
      {
-       if (i >= group->wd->markers_max_num) break;
-       if ((!marker->content) && (marker->clas->func.get))
-         marker->content = marker->clas->func.get(group->wd->obj, marker, marker->data);
-       else if (marker->content)
-         elm_box_unpack(group->bx, marker->content);
-       if (marker->content)
-         {
-            elm_box_pack_end(group->bx, marker->content);
-            i++;
-         }
+        if (i >= group->wd->markers_max_num) break;
+        if ((!marker->content) && (marker->clas->func.get))
+          marker->content = marker->clas->func.get(group->wd->obj, marker, marker->data);
+        else if (marker->content)
+          elm_box_unpack(group->bx, marker->content);
+        if (marker->content)
+          {
+             elm_box_pack_end(group->bx, marker->content);
+             i++;
+          }
      }
    return i;
 }
@@ -1967,11 +2178,11 @@ _group_bubble_content_free(Marker_Group *group)
    if (!group->sc) return;
    EINA_LIST_FOREACH(group->markers, l, marker)
      {
-       if ((marker->content) && (marker->clas->func.del))
-         marker->clas->func.del(group->wd->obj, marker, marker->data, marker->content);
-       else if (marker->content)
-         evas_object_del(marker->content);
-       marker->content = NULL;
+        if ((marker->content) && (marker->clas->func.del))
+          marker->clas->func.del(group->wd->obj, marker, marker->data, marker->content);
+        else if (marker->content)
+          evas_object_del(marker->content);
+        marker->content = NULL;
      }
    evas_object_del(group->sc);
    group->sc = NULL;
@@ -2034,15 +2245,15 @@ _group_open_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __U
 
    if (group->bringin)
      {
-       group->bringin = EINA_FALSE;
-       return;
+        group->bringin = EINA_FALSE;
+        return;
      }
 
    if (group->bubble)
      {
-       group->open = EINA_FALSE;
-       _group_bubble_free(group);
-       return;
+        group->open = EINA_FALSE;
+        _group_bubble_free(group);
+        return;
      }
    group->open = EINA_TRUE;
    _group_bubble_create(group);
@@ -2091,16 +2302,16 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty
    else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
      {
         if (page_y < 0)
-           y -= -(page_y * v_h) / 100;
+          y -= -(page_y * v_h) / 100;
         else
-           y -= page_y;
+          y -= page_y;
      }
    else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
      {
         if (page_y < 0)
-           y += -(page_y * v_h) / 100;
+          y += -(page_y * v_h) / 100;
         else
-           y += page_y;
+          y += page_y;
      }
    else if (!strcmp(ev->keyname, "KP_Add"))
      {
@@ -2126,6 +2337,195 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty
    return EINA_TRUE;
 }
 
+static Eina_Bool
+cb_dump_attrs(void *data __UNUSED__, const char *key __UNUSED__, const char *value __UNUSED__)
+{
+   return EINA_TRUE;
+}
+
+
+static Eina_Bool
+cb_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+{
+   Route_Dump *dump = data;
+
+   switch (type)
+     {
+      case EINA_SIMPLE_XML_OPEN:
+      case EINA_SIMPLE_XML_OPEN_EMPTY:
+        {
+           const char *attrs;
+
+           attrs = eina_simple_xml_tag_attributes_find(value, length);
+           if (!attrs)
+             {
+                if (!strncmp(value, YOURS_DISTANCE, length)) dump->id = ROUTE_XML_DISTANCE;
+                else if (!strncmp(value, YOURS_DESCRIPTION, length)) dump->id = ROUTE_XML_DESCRIPTION;
+                else if (!strncmp(value, YOURS_COORDINATES, length)) dump->id = ROUTE_XML_COORDINATES;
+                else dump->id = ROUTE_XML_NONE;
+             }
+           else
+             {
+                eina_simple_xml_attributes_parse
+                  (attrs, length - (attrs - value), cb_dump_attrs, dump);
+             }
+        }
+        break;
+
+      case EINA_SIMPLE_XML_DATA:
+        {
+           char *buf = malloc(length);
+           if (!buf) return EINA_FALSE;
+           snprintf(buf, length, "%s", value);
+           if (dump->id == ROUTE_XML_DISTANCE) dump->distance = atof(buf);
+           else if (!(dump->description) && (dump->id == ROUTE_XML_DESCRIPTION)) dump->description = strdup(buf);
+           else if (dump->id == ROUTE_XML_COORDINATES) dump->coordinates = strdup(buf);
+           free(buf);
+        }
+        break;
+
+      case EINA_SIMPLE_XML_CLOSE:
+        break;
+      case EINA_SIMPLE_XML_CDATA:
+        break;
+      case EINA_SIMPLE_XML_ERROR:
+        break;
+      case EINA_SIMPLE_XML_PROCESSING:
+        break;
+      case EINA_SIMPLE_XML_DOCTYPE:
+        break;
+      case EINA_SIMPLE_XML_COMMENT:
+        break;
+      case EINA_SIMPLE_XML_IGNORED:
+        break;
+     }
+
+   return EINA_TRUE;
+}
+
+static void
+_parse_kml(void *data)
+{
+   Elm_Map_Route *r = (Elm_Map_Route*)data;
+   if (!r && !r->ud.fname) return;
+
+   FILE *f;
+   char **str;
+   unsigned int ele, idx;
+   double lon, lat;
+   Evas_Object *path;
+
+   Route_Dump dump = {0, r->ud.fname, 0.0, NULL, NULL};
+
+   f = fopen(r->ud.fname, "rb");
+   if (f)
+     {
+        long sz;
+
+        fseek(f, 0, SEEK_END);
+        sz = ftell(f);
+        if (sz > 0)
+          {
+             char *buf;
+
+             fseek(f, 0, SEEK_SET);
+             buf = malloc(sz);
+             if (buf)
+               {
+                  if (fread(buf, 1, sz, f))
+                    {
+                       eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_dump, &dump);
+                       free(buf);
+                    }
+               }
+          }
+        fclose(f);
+
+        if (dump.distance) r->info.distance = dump.distance;
+        if (dump.description)
+          {
+             eina_stringshare_replace(&r->info.waypoints, dump.description);
+             str = eina_str_split_full(dump.description, "\n", 0, &ele);
+             r->info.waypoint_count = ele;
+             for (idx = 0 ; idx < ele ; idx++)
+               {
+                  Route_Waypoint *wp = ELM_NEW(Route_Waypoint);
+                  if (wp)
+                    {
+                       wp->wd = r->wd;
+                       wp->point = eina_stringshare_add(str[idx]);
+                       DBG("%s", str[idx]);
+                       r->waypoint = eina_list_append(r->waypoint, wp);
+                    }
+               }
+             if (str && str[0])
+               {
+                  free(str[0]);
+                  free(str);
+               }
+          }
+        else WRN("description is not found !");
+
+        if (dump.coordinates)
+          {
+             eina_stringshare_replace(&r->info.nodes, dump.coordinates);
+             str = eina_str_split_full(dump.coordinates, "\n", 0, &ele);
+             r->info.node_count = ele;
+             for (idx = 0 ; idx < ele ; idx++)
+               {
+                  sscanf(str[idx], "%lf,%lf", &lon, &lat);
+                  Route_Node *n = ELM_NEW(Route_Node);
+                  if (n)
+                    {
+                       n->wd = r->wd;
+                       n->pos.lon = lon;
+                       n->pos.lat = lat;
+                       n->idx = idx;
+                       DBG("%lf:%lf", lon, lat);
+                       n->pos.address = NULL;
+                       r->nodes = eina_list_append(r->nodes, n);
+
+                       path = evas_object_line_add(evas_object_evas_get(r->wd->obj));
+                       evas_object_smart_member_add(path, r->wd->pan_smart);
+                       r->path = eina_list_append(r->path, path);
+                    }
+               }
+             if (str && str[0])
+               {
+                  free(str[0]);
+                  free(str);
+               }
+          }
+     }
+}
+
+static Eina_Bool
+_common_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Url_Complete *ev = event;
+   Elm_Map_Route *r = (Elm_Map_Route*)data;
+   Widget_Data *wd = r->wd;
+
+   if ((!r) || (!ev)) return EINA_TRUE;
+   Elm_Map_Route *rr = ecore_con_url_data_get(r->con_url);
+   ecore_con_url_data_set(r->con_url, NULL);
+   if (r!=rr) return EINA_TRUE;
+
+   if (r->ud.fd) fclose(r->ud.fd);
+   _parse_kml(r);
+
+   if (wd->grids)
+     {
+        Evas_Coord ox, oy, ow, oh;
+        evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
+        route_place(wd->obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+     }
+   edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                           "elm,state,busy,stop", "elm");
+   evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOADED, NULL);
+   return EINA_TRUE;
+}
+
 static int idnum = 1;
 
 /**
@@ -2146,18 +2546,8 @@ elm_map_add(Evas_Object *parent)
    static Evas_Smart *smart = NULL;
    Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+   ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
 
-   if (!ecore_file_download_protocol_available("http://"))
-     {
-       ERR("Ecore must be built with the support of HTTP for the widget map !");
-       return NULL;
-     }
-
-   wd = ELM_NEW(Widget_Data);
-   e = evas_object_evas_get(parent);
-   if (!e) return NULL;
-   obj = elm_widget_add(e);
    ELM_SET_WIDTYPE(widtype, "map");
    elm_widget_type_set(obj, "map");
    elm_widget_sub_object_add(parent, obj);
@@ -2196,24 +2586,24 @@ elm_map_add(Evas_Object *parent)
 
    if (!smart)
      {
-       static Evas_Smart_Class sc;
-
-       evas_object_smart_clipped_smart_set(&_pan_sc);
-       sc = _pan_sc;
-       sc.name = "elm_map_pan";
-       sc.version = EVAS_SMART_CLASS_VERSION;
-       sc.add = _pan_add;
-       sc.del = _pan_del;
-       sc.resize = _pan_resize;
-       sc.move = _pan_move;
-       sc.calculate = _pan_calculate;
-       smart = evas_smart_class_new(&sc);
+        static Evas_Smart_Class sc;
+
+        evas_object_smart_clipped_smart_set(&_pan_sc);
+        sc = _pan_sc;
+        sc.name = "elm_map_pan";
+        sc.version = EVAS_SMART_CLASS_VERSION;
+        sc.add = _pan_add;
+        sc.del = _pan_del;
+        sc.resize = _pan_resize;
+        sc.move = _pan_move;
+        sc.calculate = _pan_calculate;
+        smart = evas_smart_class_new(&sc);
      }
    if (smart)
      {
-       wd->pan_smart = evas_object_smart_add(e, smart);
-       wd->pan = evas_object_smart_data_get(wd->pan_smart);
-       wd->pan->wd = wd;
+        wd->pan_smart = evas_object_smart_add(e, smart);
+        wd->pan = evas_object_smart_data_get(wd->pan_smart);
+        wd->pan->wd = wd;
      }
 
    elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
@@ -2224,12 +2614,12 @@ elm_map_add(Evas_Object *parent)
    evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_RESIZE,
                                   _rect_resize_cb, obj);
    evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_DOWN,
-        _mouse_down, obj);
+                                  _mouse_down, obj);
    evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_MOVE,
                                   _mouse_move, obj);
    evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_UP,
-        _mouse_up, obj);
-   evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MULTI_DOWN, 
+                                  _mouse_up, obj);
+   evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MULTI_DOWN,
                                   _mouse_multi_down, obj);
    evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MULTI_MOVE,
                                   _mouse_multi_move, obj);
@@ -2243,6 +2633,7 @@ elm_map_add(Evas_Object *parent)
 
    wd->zoom = -1;
    wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
+   wd->fid = 0;
    wd->id = ((int)getpid() << 16) | idnum;
    idnum++;
 
@@ -2266,6 +2657,11 @@ elm_map_add(Evas_Object *parent)
    // TODO: convert Elementary to subclassing of Evas_Smart_Class
    // TODO: and save some bytes, making descriptions per-class and not instance!
    evas_object_smart_callbacks_descriptions_set(obj, _signals);
+
+   if (!ecore_file_download_protocol_available("http://"))
+     {
+        ERR("Ecore must be built with curl support for the map widget!");
+     }
    return obj;
 }
 
@@ -2284,12 +2680,14 @@ elm_map_zoom_set(Evas_Object *obj, int zoom)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   Eina_List *l;
+   Eina_List *l, *lr;
    Grid *g, *g_zoom = NULL;
    Evas_Coord rx, ry, rw, rh;
+   Evas_Object *p;
+   Elm_Map_Route *r;
    int z;
    int zoom_changed = 0, started = 0;
-   
+
    if (!wd) return;
    if (zoom < 0 ) zoom = 0;
    if (zoom > map_sources_tab[wd->source].zoom_max)
@@ -2304,105 +2702,116 @@ elm_map_zoom_set(Evas_Object *obj, int zoom)
    elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
    elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
 
+   EINA_LIST_FOREACH(wd->route, lr, r)
+     {
+        if (r)
+          {
+             EINA_LIST_FOREACH(r->path, l, p)
+               {
+                  evas_object_hide(p);
+               }
+          }
+     }
+
    if (wd->mode == ELM_MAP_ZOOM_MODE_MANUAL)
      {
-       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
-       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+        wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+        wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
      }
    else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
      {
-       int p2w, p2h;
-       int cumulw, cumulh;
-
-       cumulw = wd->tsize;
-       p2w = 0;
-       while (cumulw <= rw)
-         {
-            p2w++;
-            cumulw *= 2;
-         }
-       p2w--;
-
-       cumulh = wd->tsize;
-       p2h = 0;
-       while (cumulh <= rh)
-         {
-            p2h++;
-            cumulh *= 2;
-         }
-       p2h--;
-        
-       if (p2w < p2h)
-         z = p2w;
-       else
-         z = p2h;
-        
-       wd->zoom = z;
-       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
-       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+        int p2w, p2h;
+        int cumulw, cumulh;
+
+        cumulw = wd->tsize;
+        p2w = 0;
+        while (cumulw <= rw)
+          {
+             p2w++;
+             cumulw *= 2;
+          }
+        p2w--;
+
+        cumulh = wd->tsize;
+        p2h = 0;
+        while (cumulh <= rh)
+          {
+             p2h++;
+             cumulh *= 2;
+          }
+        p2h--;
+
+        if (p2w < p2h)
+          z = p2w;
+        else
+          z = p2h;
+
+        wd->zoom = z;
+        wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+        wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
      }
    else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
      {
-       int p2w, p2h;
-       int cumulw, cumulh;
-        
-       cumulw = wd->tsize;
-       p2w = 0;
-       while (cumulw <= rw)
-         {
-            p2w++;
-            cumulw *= 2;
-         }
-       p2w--;
-
-       cumulh = wd->tsize;
-       p2h = 0;
-       while (cumulh <= rh)
-         {
-            p2h++;
-            cumulh *= 2;
-         }
-       p2h--;
-
-       if (p2w > p2h)
-         z = p2w;
-       else
-         z = p2h;
-        
-       wd->zoom = z;
-       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
-       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+        int p2w, p2h;
+        int cumulw, cumulh;
+
+        cumulw = wd->tsize;
+        p2w = 0;
+        while (cumulw <= rw)
+          {
+             p2w++;
+             cumulw *= 2;
+          }
+        p2w--;
+
+        cumulh = wd->tsize;
+        p2h = 0;
+        while (cumulh <= rh)
+          {
+             p2h++;
+             cumulh *= 2;
+          }
+        p2h--;
+
+        if (p2w > p2h)
+          z = p2w;
+        else
+          z = p2h;
+
+        wd->zoom = z;
+        wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+        wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
      }
 
    EINA_LIST_FOREACH(wd->grids, l, g)
      {
-       if (g->zoom == wd->zoom)
-         {
-            wd->grids = eina_list_remove(wd->grids, g);
-            wd->grids = eina_list_prepend(wd->grids, g);
-            _grid_raise(g);
-            goto done;
-         }
+        if (g->zoom == wd->zoom)
+          {
+             wd->grids = eina_list_remove(wd->grids, g);
+             wd->grids = eina_list_prepend(wd->grids, g);
+             _grid_raise(g);
+             goto done;
+          }
      }
    g = grid_create(obj);
    if (g)
      {
-       if (eina_list_count(wd->grids) > 1)
-         {
-            g_zoom = eina_list_last(wd->grids)->data;
-            wd->grids = eina_list_remove(wd->grids, g_zoom);
-            grid_clear(obj, g_zoom);
-            free(g_zoom);
-         }
-       wd->grids = eina_list_prepend(wd->grids, g);
+        if (eina_list_count(wd->grids) > 1)
+          {
+             g_zoom = eina_list_last(wd->grids)->data;
+             wd->grids = eina_list_remove(wd->grids, g_zoom);
+             grid_clear(obj, g_zoom);
+             free(g_zoom);
+          }
+        wd->grids = eina_list_prepend(wd->grids, g);
      }
    else
      {
-       EINA_LIST_FREE(wd->grids, g)
-         {
-            grid_clear(obj, g);
-            free(g);
-         }
+        EINA_LIST_FREE(wd->grids, g)
+          {
+             grid_clear(obj, g);
+             free(g);
+          }
      }
 done:
 
@@ -2410,13 +2819,13 @@ done:
    wd->t_end = wd->t_start + _elm_config->zoom_friction;
    if ((wd->size.w > 0) && (wd->size.h > 0))
      {
-       wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.ow;
-       wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.oh;
+        wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.ow;
+        wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.oh;
      }
    else
      {
-       wd->size.spos.x = 0.5;
-       wd->size.spos.y = 0.5;
+        wd->size.spos.x = 0.5;
+        wd->size.spos.y = 0.5;
      }
    if (rw > wd->size.ow) wd->size.spos.x = 0.5;
    if (rh > wd->size.oh) wd->size.spos.y = 0.5;
@@ -2424,34 +2833,34 @@ done:
    if (wd->size.spos.y > 1.0) wd->size.spos.y = 1.0;
    if (wd->paused)
      {
-       zoom_do(obj, 1.0);
+        zoom_do(obj, 1.0);
      }
    else
      {
-       if (!wd->zoom_animator)
-         {
-            wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
-            wd->nosmooth++;
-            if (wd->nosmooth == 1) _smooth_update(obj);
-            started = 1;
-         }
+        if (!wd->zoom_animator)
+          {
+             wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
+             wd->nosmooth++;
+             if (wd->nosmooth == 1) _smooth_update(obj);
+             started = 1;
+          }
      }
    if (wd->zoom_animator)
      {
-       if (!_zoom_anim(obj))
-         {
-            ecore_animator_del(wd->zoom_animator);
-            wd->zoom_animator = NULL;
-         }
+        if (!_zoom_anim(obj))
+          {
+             ecore_animator_del(wd->zoom_animator);
+             wd->zoom_animator = NULL;
+          }
      }
    if (wd->calc_job) ecore_job_del(wd->calc_job);
    wd->calc_job = ecore_job_add(_calc_job, wd);
    if (!wd->paused)
      {
-       if (started)
-         evas_object_smart_callback_call(obj, SIG_ZOOM_START, NULL);
-       if (!wd->zoom_animator)
-         evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+        if (started)
+          evas_object_smart_callback_call(obj, SIG_ZOOM_START, NULL);
+        if (!wd->zoom_animator)
+          evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
      }
 
    if (zoom_changed)
@@ -2507,9 +2916,9 @@ elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
    if (wd->mode == mode) return;
    wd->mode = mode;
      {
-       double tz = wd->zoom;
-       wd->zoom = 0.0;
-       elm_map_zoom_set(wd->obj, tz);
+        double tz = wd->zoom;
+        wd->zoom = 0.0;
+        elm_map_zoom_set(wd->obj, tz);
      }
 }
 
@@ -2557,12 +2966,12 @@ elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
 
    if (wd->zoom_animator)
      {
-       wd->nosmooth--;
-       if (!wd->nosmooth) _smooth_update(obj);
-       ecore_animator_del(wd->zoom_animator);
-       wd->zoom_animator = NULL;
-       zoom_do(obj, 1.0);
-       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+        wd->nosmooth--;
+        if (!wd->nosmooth) _smooth_update(obj);
+        ecore_animator_del(wd->zoom_animator);
+        wd->zoom_animator = NULL;
+        zoom_do(obj, 1.0);
+        evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
      }
    elm_smart_scroller_region_bring_in(wd->scr, rx, ry, rw, rh);
 
@@ -2598,11 +3007,11 @@ elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
 
    if (wd->zoom_animator)
      {
-       wd->nosmooth--;
-       ecore_animator_del(wd->zoom_animator);
-       wd->zoom_animator = NULL;
-       zoom_do(obj, 1.0);
-       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+        wd->nosmooth--;
+        ecore_animator_del(wd->zoom_animator);
+        wd->zoom_animator = NULL;
+        zoom_do(obj, 1.0);
+        evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
      }
    elm_smart_scroller_child_region_show(wd->scr, rx, ry, rw, rh);
 
@@ -2660,13 +3069,13 @@ elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
    wd->paused = paused;
    if (wd->paused)
      {
-       if (wd->zoom_animator)
-         {
-            ecore_animator_del(wd->zoom_animator);
-            wd->zoom_animator = NULL;
-            zoom_do(obj, 1.0);
-            evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
-         }
+        if (wd->zoom_animator)
+          {
+             ecore_animator_del(wd->zoom_animator);
+             wd->zoom_animator = NULL;
+             zoom_do(obj, 1.0);
+             evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+          }
      }
 }
 
@@ -2742,7 +3151,7 @@ elm_map_paused_markers_get(const Evas_Object *obj)
  * @ingroup Map
  */
 
-EAPI void 
+EAPI void
 elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
@@ -2787,12 +3196,12 @@ elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int s
 
    if (lon)
      {
-       *lon = x / (double)size * 360.0 - 180;
+        *lon = x / (double)size * 360.0 - 180;
      }
    if (lat)
      {
-       double n = ELM_PI - 2.0 * ELM_PI * y / size;
-       *lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
+        double n = ELM_PI - 2.0 * ELM_PI * y / size;
+        *lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
      }
 }
 
@@ -2881,144 +3290,144 @@ elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Clas
 
    if (!clas_group->priv.set)
      {
-       style = "radio";
-       if (marker->clas_group && marker->clas_group->style)
-         style = marker->clas_group->style;
-
-       o = edje_object_add(evas_object_evas_get(obj));
-       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
-       s = edje_object_data_get(o, "size_w");
-       if (s) clas_group->priv.edje_w = atoi(s);
-       else clas_group->priv.edje_w = 0;
-       s = edje_object_data_get(o, "size_h");
-       if (s) clas_group->priv.edje_h = atoi(s);
-       else clas_group->priv.edje_h = 0;
-       s = edje_object_data_get(o, "size_max_w");
-       if (s) clas_group->priv.edje_max_w = atoi(s);
-       else clas_group->priv.edje_max_w = 0;
-       s = edje_object_data_get(o, "size_max_h");
-       if (s) clas_group->priv.edje_max_h = atoi(s);
-       else clas_group->priv.edje_max_h = 0;
-       evas_object_del(o);
-
-       clas_group->priv.set = EINA_TRUE;
+        style = "radio";
+        if (marker->clas_group && marker->clas_group->style)
+          style = marker->clas_group->style;
+
+        o = edje_object_add(evas_object_evas_get(obj));
+        _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
+        s = edje_object_data_get(o, "size_w");
+        if (s) clas_group->priv.edje_w = atoi(s);
+        else clas_group->priv.edje_w = 0;
+        s = edje_object_data_get(o, "size_h");
+        if (s) clas_group->priv.edje_h = atoi(s);
+        else clas_group->priv.edje_h = 0;
+        s = edje_object_data_get(o, "size_max_w");
+        if (s) clas_group->priv.edje_max_w = atoi(s);
+        else clas_group->priv.edje_max_w = 0;
+        s = edje_object_data_get(o, "size_max_h");
+        if (s) clas_group->priv.edje_max_h = atoi(s);
+        else clas_group->priv.edje_max_h = 0;
+        evas_object_del(o);
+
+        clas_group->priv.set = EINA_TRUE;
      }
 
    if (!clas->priv.set)
      {
-       style = "radio";
-       if (marker->clas && marker->clas->style)
-         style = marker->clas->style;
-        
-       o = edje_object_add(evas_object_evas_get(obj));
-       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
-       s = edje_object_data_get(o, "size_w");
-       if (s) clas->priv.edje_w = atoi(s);
-       else clas->priv.edje_w = 0;
-       s = edje_object_data_get(o, "size_h");
-       if (s) clas->priv.edje_h = atoi(s);
-       else clas->priv.edje_h = 0;
-       evas_object_del(o);
-
-       clas->priv.set = EINA_TRUE;
+        style = "radio";
+        if (marker->clas && marker->clas->style)
+          style = marker->clas->style;
+
+        o = edje_object_add(evas_object_evas_get(obj));
+        _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
+        s = edje_object_data_get(o, "size_w");
+        if (s) clas->priv.edje_w = atoi(s);
+        else clas->priv.edje_w = 0;
+        s = edje_object_data_get(o, "size_h");
+        if (s) clas->priv.edje_h = atoi(s);
+        else clas->priv.edje_h = 0;
+        evas_object_del(o);
+
+        clas->priv.set = EINA_TRUE;
      }
 
    for (i = clas_group->zoom_displayed; i <= ZOOM_MAX; i++)
      {
-       elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, i)*wd->tsize,
+        elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, i)*wd->tsize,
                                              &(marker->x[i]), &(marker->y[i]));
-        
-       //search in the matrixsparse the region where the marker will be
-       mpi = marker->x[i] / wd->tsize;
-       mpj = marker->y[i] / wd->tsize;
-
-       if (!wd->markers[i])
-         {
-            int size =  pow(2.0, i);
-            wd->markers[i] = eina_matrixsparse_new(size, size, NULL, NULL);
-         }
-
-       group = NULL;
-       if (i <= clas_group->zoom_grouped)
-         {
-            for (j = 0, group = NULL; j < 9 && !group; j++)
-              {
-                 EINA_LIST_FOREACH(eina_matrixsparse_data_idx_get(wd->markers[i], mpj + tabj[j], mpi + tabi[j]),
+
+        //search in the matrixsparse the region where the marker will be
+        mpi = marker->x[i] / wd->tsize;
+        mpj = marker->y[i] / wd->tsize;
+
+        if (!wd->markers[i])
+          {
+             int size =  pow(2.0, i);
+             wd->markers[i] = eina_matrixsparse_new(size, size, NULL, NULL);
+          }
+
+        group = NULL;
+        if (i <= clas_group->zoom_grouped)
+          {
+             for (j = 0, group = NULL; j < 9 && !group; j++)
+               {
+                  EINA_LIST_FOREACH(eina_matrixsparse_data_idx_get(wd->markers[i], mpj + tabj[j], mpi + tabi[j]),
                                     l, group)
-                   {
-                      if (group->clas == marker->clas_group
+                    {
+                       if (group->clas == marker->clas_group
                            && ELM_RECTS_INTERSECT(marker->x[i]-clas->priv.edje_w/4,
                                                   marker->y[i]-clas->priv.edje_h/4, clas->priv.edje_w, clas->priv.edje_h,
                                                   group->x-group->w/4, group->y-group->h/4, group->w, group->h))
-                        {
-                           group->markers = eina_list_append(group->markers, marker);
-                           group->update_nbelems = EINA_TRUE;
-                           group->update_resize = EINA_TRUE;
-
-                           group->sum_x += marker->x[i];
-                           group->sum_y += marker->y[i];
-                           group->x = group->sum_x / eina_list_count(group->markers);
-                           group->y = group->sum_y / eina_list_count(group->markers);
-
-                           group->w = group->clas->priv.edje_w + group->clas->priv.edje_w/8.
-                              * eina_list_count(group->markers);
-                           group->h = group->clas->priv.edje_h + group->clas->priv.edje_h/8.
-                              * eina_list_count(group->markers);
-                           if (group->w > group->clas->priv.edje_max_w) group->w = group->clas->priv.edje_max_w;
-                           if (group->h > group->clas->priv.edje_max_h) group->h = group->clas->priv.edje_max_h;
-
-                           if (group->obj && eina_list_count(group->markers) == 2)
-                             {
-                                _group_object_free(group);
-                                _group_object_create(group);
-                             }
-                           if (group->bubble)
-                             _group_bubble_content_update(group);
-                            
-                           break;
-                        }
-                   }
-              }
-         }
-       if (!group)
-         {
-            group = calloc(1, sizeof(Marker_Group));
-            group->wd = wd;
-            group->sum_x = marker->x[i];
-            group->sum_y = marker->y[i];
-            group->x = marker->x[i];
-            group->y = marker->y[i];
-            group->w = clas_group->priv.edje_w;
-            group->h = clas_group->priv.edje_h;
-            group->clas = clas_group;
-
-            group->markers = eina_list_append(group->markers, marker);
-            group->update_nbelems = EINA_TRUE;
-            group->update_resize = EINA_TRUE;
-
-            eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
-
-            if (!group->cell)
-              {
-                 l = eina_list_append(NULL, group);
-                 eina_matrixsparse_data_idx_set(wd->markers[i], mpj, mpi, l);
-                 eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
-              }
-            else
-              {
-                 l = eina_matrixsparse_cell_data_get(group->cell);
-                 l = eina_list_append(l, group);
-                 eina_matrixsparse_cell_data_set(group->cell, l);
-              }
-         }
-       marker->groups[i] = group;
+                         {
+                            group->markers = eina_list_append(group->markers, marker);
+                            group->update_nbelems = EINA_TRUE;
+                            group->update_resize = EINA_TRUE;
+
+                            group->sum_x += marker->x[i];
+                            group->sum_y += marker->y[i];
+                            group->x = group->sum_x / eina_list_count(group->markers);
+                            group->y = group->sum_y / eina_list_count(group->markers);
+
+                            group->w = group->clas->priv.edje_w + group->clas->priv.edje_w/8.
+                               * eina_list_count(group->markers);
+                            group->h = group->clas->priv.edje_h + group->clas->priv.edje_h/8.
+                               * eina_list_count(group->markers);
+                            if (group->w > group->clas->priv.edje_max_w) group->w = group->clas->priv.edje_max_w;
+                            if (group->h > group->clas->priv.edje_max_h) group->h = group->clas->priv.edje_max_h;
+
+                            if (group->obj && eina_list_count(group->markers) == 2)
+                              {
+                                 _group_object_free(group);
+                                 _group_object_create(group);
+                              }
+                            if (group->bubble)
+                              _group_bubble_content_update(group);
+
+                            break;
+                         }
+                    }
+               }
+          }
+        if (!group)
+          {
+             group = calloc(1, sizeof(Marker_Group));
+             group->wd = wd;
+             group->sum_x = marker->x[i];
+             group->sum_y = marker->y[i];
+             group->x = marker->x[i];
+             group->y = marker->y[i];
+             group->w = clas_group->priv.edje_w;
+             group->h = clas_group->priv.edje_h;
+             group->clas = clas_group;
+
+             group->markers = eina_list_append(group->markers, marker);
+             group->update_nbelems = EINA_TRUE;
+             group->update_resize = EINA_TRUE;
+
+             eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
+
+             if (!group->cell)
+               {
+                  l = eina_list_append(NULL, group);
+                  eina_matrixsparse_data_idx_set(wd->markers[i], mpj, mpi, l);
+                  eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
+               }
+             else
+               {
+                  l = eina_matrixsparse_cell_data_get(group->cell);
+                  l = eina_list_append(l, group);
+                  eina_matrixsparse_cell_data_set(group->cell, l);
+               }
+          }
+        marker->groups[i] = group;
      }
 
    if (wd->grids)
      {
-       Evas_Coord ox, oy, ow, oh;
-       evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
-       marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+        Evas_Coord ox, oy, ow, oh;
+        evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+        marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
      }
 
    return marker;
@@ -3083,14 +3492,14 @@ elm_map_marker_remove(Elm_Map_Marker *marker)
      marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
    else if (marker->content)
      evas_object_del(marker->content);
-   
+
    free(marker);
-   
+
    if (wd->grids)
      {
-       Evas_Coord ox, oy, ow, oh;
-       evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
-       marker_place(wd->obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+        Evas_Coord ox, oy, ow, oh;
+        evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
+        marker_place(wd->obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
      }
 }
 
@@ -3164,35 +3573,35 @@ elm_map_markers_list_show(Eina_List *markers)
 
    EINA_LIST_FOREACH(markers, l, marker)
      {
-       wd = marker->wd;
+        wd = marker->wd;
+
+        if ((!m_min_lon) || (marker->longitude < m_min_lon->longitude))
+          m_min_lon = marker;
 
-       if ((!m_min_lon) || (marker->longitude < m_min_lon->longitude))
-         m_min_lon = marker;
-        
-       if ((!m_max_lon) || (marker->longitude > m_max_lon->longitude))
-         m_max_lon = marker;
-        
-       if ((!m_min_lat) || (marker->latitude > m_min_lat->latitude))
-         m_min_lat = marker;
-        
-       if ((!m_max_lat) || (marker->latitude < m_max_lat->latitude))
-         m_max_lat = marker;
+        if ((!m_max_lon) || (marker->longitude > m_max_lon->longitude))
+          m_max_lon = marker;
+
+        if ((!m_min_lat) || (marker->latitude > m_min_lat->latitude))
+          m_min_lat = marker;
+
+        if ((!m_max_lat) || (marker->latitude < m_max_lat->latitude))
+          m_max_lat = marker;
      }
-   
+
    lon = (m_max_lon->longitude - m_min_lon->longitude) / 2. + m_min_lon->longitude;
    lat = (m_max_lat->latitude - m_min_lat->latitude) / 2. + m_min_lat->latitude;
-   
+
    elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
    for (zoom = map_sources_tab[wd->source].zoom_max; zoom>map_sources_tab[wd->source].zoom_min; zoom--)
      {
-       Evas_Coord size = pow(2.0, zoom)*wd->tsize;
-       elm_map_utils_convert_geo_into_coord(wd->obj, lon, lat, size, &xc, &yc);
-        
-       if ((m_min_lon->x[zoom] - wd->marker_max_w >= xc-rw/2)
+        Evas_Coord size = pow(2.0, zoom)*wd->tsize;
+        elm_map_utils_convert_geo_into_coord(wd->obj, lon, lat, size, &xc, &yc);
+
+        if ((m_min_lon->x[zoom] - wd->marker_max_w >= xc-rw/2)
             && (m_min_lat->y[zoom] - wd->marker_max_h >= yc-rh/2)
             && (m_max_lon->x[zoom] + wd->marker_max_w <= xc+rw/2)
             && (m_max_lat->y[zoom] + wd->marker_max_h <= yc+rh/2))
-         break;
+          break;
      }
 
    elm_map_geo_region_show(wd->obj, lon, lat);
@@ -3248,12 +3657,12 @@ elm_map_marker_update(Elm_Map_Marker *marker)
    EINA_SAFETY_ON_NULL_RETURN(marker);
    if (marker->content)
      {
-       if (marker->clas->func.del)
-         marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
-       else
-         evas_object_del(marker->content);
-       marker->content = NULL;
-       _group_bubble_content_update(marker->groups[marker->wd->zoom]);
+        if (marker->clas->func.del)
+          marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
+        else
+          evas_object_del(marker->content);
+        marker->content = NULL;
+        _group_bubble_content_update(marker->groups[marker->wd->zoom]);
      }
 }
 
@@ -3273,7 +3682,7 @@ elm_map_bubbles_close(Evas_Object *obj)
    Eina_List *l, *l_next;
    if (!wd) return;
    EINA_LIST_FOREACH_SAFE(wd->opened_bubbles, l, l_next, group)
-     _group_bubble_free(group);
+      _group_bubble_free(group);
 }
 
 
@@ -3399,9 +3808,9 @@ elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_B
    clas->hide = hide;
    if (wd->grids)
      {
-       Evas_Coord ox, oy, ow, oh;
-       evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
-       marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+        Evas_Coord ox, oy, ow, oh;
+        evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+        marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
      }
 }
 
@@ -3533,16 +3942,33 @@ elm_map_source_set(Evas_Object *obj, Elm_Map_Sources source)
    wd->source = source;
    zoom = wd->zoom;
    wd->zoom = -1;
-   
+
    if (map_sources_tab[wd->source].zoom_max < zoom)
      zoom = map_sources_tab[wd->source].zoom_max;
    if (map_sources_tab[wd->source].zoom_min > zoom)
      zoom = map_sources_tab[wd->source].zoom_min;
-   
+
    elm_map_zoom_set(obj, zoom);
 }
 
 /**
+ * Set the source of the route.
+ *
+ * @param clas the group class
+ * @param source the new source
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source __UNUSED__)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->source = source;
+}
+
+/**
  * Get the current source
  *
  * @param obj the map object
@@ -3560,6 +3986,23 @@ elm_map_source_get(const Evas_Object *obj)
 }
 
 /**
+ * Get the current route source
+ *
+ * @param obj the map object
+ * @return Returns the source of the route
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Route_Sources
+elm_map_route_source_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ROUTE_SOURCE_YOURS;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_MAP_ROUTE_SOURCE_YOURS;
+   return wd->route_source;
+}
+
+/**
  * Set the API of a custom source.
  *
  * A custom web service can be associated to the source ELM_MAP_SOURCE_CUSTOM_(1..7).
@@ -3573,7 +4016,7 @@ elm_map_source_get(const Evas_Object *obj)
  * @ingroup Map
  */
 EAPI void
-elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb)
+elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb, ElmMapRouteSourceURLFunc route_url_cb)
 {
    EINA_SAFETY_ON_NULL_RETURN(name);
    EINA_SAFETY_ON_NULL_RETURN(url_cb);
@@ -3581,6 +4024,7 @@ elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom
    map_sources_tab[source].zoom_min = zoom_min;
    map_sources_tab[source].zoom_max = zoom_max;
    map_sources_tab[source].url_cb = url_cb;
+   map_sources_tab[source].route_url_cb = route_url_cb;
 }
 
 /**
@@ -3642,7 +4086,7 @@ elm_map_user_agent_set(Evas_Object *obj, const char *user_agent)
    if (!wd) return;
    if (!wd->user_agent) wd->user_agent = eina_stringshare_add(user_agent);
    else eina_stringshare_replace(&wd->user_agent, user_agent);
-   
+
    if (!wd->ua) wd->ua = eina_hash_string_small_new(NULL);
    eina_hash_set(wd->ua, "User-Agent", wd->user_agent);
 }
@@ -3665,6 +4109,244 @@ elm_map_user_agent_get(Evas_Object *obj)
    return wd->user_agent;
 }
 
+/**
+ * Add a route on the map
+ *
+ * @param obj The map object
+ * @param type the type if transport
+ * @param method the routing method
+ * @param flon the start longitude
+ * @param flat the start latitude
+ * @param tlon the destination longitude
+ * @param tlat the destination latitude
+ *
+ * @return The Route object
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Route *
+elm_map_route_add(Evas_Object *obj,
+                  Elm_Map_Route_Type type,
+                  Elm_Map_Route_Method method,
+                  double flon,
+                  double flat,
+                  double tlon,
+                  double tlat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   char buf[PATH_MAX];
+   char *source;
+   char *type_name = NULL;
+   int fd;
+   Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
+   if (!route) return NULL;
+
+   snprintf(buf, sizeof(buf), DEST_XML_FILE);
+   fd = mkstemp(buf);
+   if (fd < 0)
+     {
+        free(route);
+        return NULL;
+     }
+   
+   route->con_url = ecore_con_url_new(NULL);
+   route->ud.fname = strdup(buf);
+   INF("xml file : %s", route->ud.fname);
+
+   wd->fid++;
+   route->ud.fd = fdopen(fd, "w+");
+   if ((!route->con_url) || (!route->ud.fd))
+     {
+        ecore_con_url_free(route->con_url);
+        free(route);
+        return NULL;
+     }
+
+   route->wd = wd;
+   route->color.r = 255;
+   route->color.g = 0;
+   route->color.b = 0;
+   route->color.a = 255;
+   route->handlers = eina_list_append
+     (route->handlers, (void *)ecore_event_handler_add
+         (ECORE_CON_EVENT_URL_COMPLETE, _common_complete_cb, route));
+
+   route->inbound = EINA_FALSE;
+   route->type = type;
+   route->method = method;
+   route->flon = flon;
+   route->flat = flat;
+   route->tlon = tlon;
+   route->tlat = tlat;
+
+   switch (type)
+     {
+      case ELM_MAP_ROUTE_TYPE_MOTOCAR:
+        type_name = strdup(ROUTE_TYPE_MOTORCAR);
+        break;
+      case ELM_MAP_ROUTE_TYPE_BICYCLE:
+        type_name = strdup(ROUTE_TYPE_BICYCLE);
+        break;
+      case ELM_MAP_ROUTE_TYPE_FOOT:
+        type_name = strdup(ROUTE_TYPE_FOOT);
+        break;
+      default:
+        break;
+     }
+
+   source = map_sources_tab[wd->source].route_url_cb(obj, type_name, method, flon, flat, tlon, tlat);
+   INF("route url = %s", source);
+
+   wd->route = eina_list_append(wd->route, route);
+
+   ecore_con_url_url_set(route->con_url, source);
+   ecore_con_url_fd_set(route->con_url, fileno(route->ud.fd));
+   ecore_con_url_data_set(route->con_url, route);
+   ecore_con_url_get(route->con_url);
+   if (type_name) free(type_name);
+   if (source) free(source);
+
+   edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                           "elm,state,busy,start", "elm");
+   evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOAD, NULL);
+   return route;
+}
+
+/**
+ * Remove a route from the map
+ *
+ * @param route The route to remove
+ *
+ * @ingroup Map
+ */
+
+EAPI void
+elm_map_route_remove(Elm_Map_Route *route)
+{
+   EINA_SAFETY_ON_NULL_RETURN(route);
+
+   Route_Waypoint *w;
+   Route_Node *n;
+   Evas_Object *p;
+   Ecore_Event_Handler *h;
+
+   EINA_LIST_FREE(route->path, p)
+     {
+        evas_object_del(p);
+     }
+
+   EINA_LIST_FREE(route->waypoint, w)
+     {
+        if (w->point) eina_stringshare_del(w->point);
+        free(w);
+     }
+
+   EINA_LIST_FREE(route->nodes, n)
+     {
+        if (n->pos.address) eina_stringshare_del(n->pos.address);
+        free(n);
+     }
+
+   EINA_LIST_FREE(route->handlers, h)
+     {
+        ecore_event_handler_del(h);
+     }
+
+   if (route->ud.fname)
+     {
+        ecore_file_remove(route->ud.fname);
+        free(route->ud.fname);
+        route->ud.fname = NULL;
+     }
+}
+
+/**
+ * Set the option used for the background color
+ *
+ * @param route The route object
+ * @param r
+ * @param g
+ * @param b
+ * @param a
+ *
+ * This sets the color used for the route
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_route_color_set(Elm_Map_Route *route, int r, int g , int b, int a)
+{
+   route->color.r = r;
+   route->color.g = g;
+   route->color.b = b;
+   route->color.a = a;
+}
+
+/**
+ * Get the option used for the background color
+ *
+ * @param route The route object
+ * @param r
+ * @param g
+ * @param b
+ * @param a
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_route_color_get(Elm_Map_Route *route, int *r, int *g , int *b, int *a)
+{
+   if (*r) *r = route->color.r;
+   if (*g) *g = route->color.g;
+   if (*b) *b = route->color.b;
+   if (*a) *a = route->color.a;
+}
+
+/**
+ * Get the information of route distance
+ *
+ * @param route the route object
+ * @return Returns the distance of route (unit : km)
+ *
+ * @ingroup Map
+ */
+EAPI double
+elm_map_route_distance_get(Elm_Map_Route *route)
+{
+   return route->info.distance;
+}
+
+/**
+ * Get the information of route nodes
+ *
+ * @param route the route object
+ * @return Returns the nodes of route
+ *
+ * @ingroup Map
+ */
+
+EAPI const char*
+elm_map_route_node_get(Elm_Map_Route *route)
+{
+   return route->info.nodes;
+}
+
+/**
+ * Get the information of route waypoint
+ *
+ * @param route the route object
+ * @return Returns the waypoint of route
+ *
+ * @ingroup Map
+ */
+
+EAPI const char*
+elm_map_route_waypoint_get(Elm_Map_Route *route)
+{
+   return route->info.waypoints;
+}
 
 static char *
 _mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
@@ -3679,7 +4361,7 @@ static char *
 _osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
    char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf), 
+   snprintf(buf, sizeof(buf),
             "http://tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
             zoom, x, y);
    return strdup(buf);
@@ -3689,7 +4371,7 @@ static char *
 _cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
    char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf), 
+   snprintf(buf, sizeof(buf),
             "http://andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png",
             zoom, x, y);
    return strdup(buf);
@@ -3699,7 +4381,7 @@ static char *
 _maplint_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
    char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf), 
+   snprintf(buf, sizeof(buf),
             "http://tah.openstreetmap.org/Tiles/maplint/%d/%d/%d.png",
             zoom, x, y);
    return strdup(buf);
@@ -3758,3 +4440,75 @@ _module_url_cb(Evas_Object *obj, int x, int y, int zoom)
    return buf;
 }
 
+static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+
+// TODO: fix monav api
+/*
+static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_MONAV_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+*/
+
+// TODO: fix ors api
+/*
+static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_ORS_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+*/
+
+static char *_route_custom1_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *_route_custom2_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *_route_custom3_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *_route_custom4_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *_route_custom5_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *_route_custom6_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   return strdup("");
+}
+/*
+static char *_route_module_url_cb(Evas_Object *obj __UNUSED__, char *type_name __UNUSED__, int method __UNUSED__, double flon __UNUSED__, double flat __UNUSED__, double tlon __UNUSED__, double tlat __UNUSED__)
+{
+   // TODO: make example route module
+   return strdup("");
+}
+*/