From: Bluezery <ohpowel@gmail.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Mar 2012 04:18:33 +0000 (04:18 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Mar 2012 04:18:33 +0000 (04:18 +0000)
Subject: [E-devel] [Patch][elm_map] Add overlay in the map

I made a overlay APIs in the map. This will replace the marker APIs.
I hope that markers will be deleted before elementary 1.0 release.
This was discussed before in
http://marc.info/?l=enlightenment-devel&m=132685497711772&w=2

Marker only supports layout style overlay. So only icon and image are
suitable for marker.  For now on, overlay can support any evas object
and also layout style.
Currently overlay support default, bubble, and class types.  And more
types will be added (Polyline, Polygon, scale, POI etc.).
I made a Elm_Map_Overlay opaque structure for handling general overlay
properties (hide, pause, show, etc.) and coordinates or internal
content (icon, content, etc.) for those different types.
Class type overlay is something like mixture of previous marker group
and marker class.
If member overlays in the same class are closed, they will be grouped.
(Same functionality as previous maker group.) The group's properties
and contents are defined by using general overlay functions.  (New
functionality)
This defined properties and contents can be be propagated to member
overlays appended to this class.  (Same functionality as previous
maker class.)

There are some missing functionalities remained. Group callbacks are
not supported yet in the overlays.
So images inside group bubble can not be shown. I will implement this
feature.

After this patch, I will fix signals and function names before
elementary 1.0 releases.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@68672 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/examples.dox
src/bin/test_map.c
src/examples/map_example_01.c
src/examples/map_example_02.c
src/examples/map_example_03.c
src/lib/elm_map.c
src/lib/elm_map.h

index 9b08137..fda24f3 100644 (file)
  */
 
 /**
- * @page map_example_02 Map Example - Markers Usage
+ * @page map_example_02 Map Example - Overlay Usage
  *
  * This code places a Elementary map widget on a window,
- * to exemplify part of the widget's API, related to markers.
+ * to exemplify part of the widget's API, related to overlays.
  *
- * We'll start this example the same way
+ * We'll start this example in the same way
  * @ref map_example_01 "Map Example 1". Adding a map with buttons to control
  * zoom, so if you didn't read it yet, just do it now.
  * @dontinclude map_example_02.c
  * @skipline elm_map_add
  * @until zoom_fill
  *
- * Markers can be placed over the map to represent anything we want. Let's
- * say we want to represent some countries and cities with markers. To add
- * a mark we need a marker class and also a group class.
- *
- * A marker class can be created as the following code does:
- * @skipline marker_class_new
- * @until style_set
- *
- * These lines create a new class, set a function to return the object
- * to be displayed inside the bubble that opens when a user clicks over
- * the mark, set the function to retrieve an icon to be placed inside
- * the marker, and defines the style of this marker. It can be @c empty
- * that will just show the icon, @c radio, that will place a blue circle,
- * and @c radio2 that will place a green circle.
- *
- * The group classes can be created in a very similar way, but you won't
- * set callback functions to get stuff to be placed inside the bubble,
- * since clicking over a group marker will just get the content
- * of all the markers composing the group and place on this bubble.
- * The limit of markers to get can be set with function
- * elm_map_max_marker_per_group_set() but we won't need on this example.
- * But we can set the zoom required to display the marks that belongs
- * to this group class, so if the zoom is less than this value, nothing
- * will be show. The group marker style will be used when markers are
- * near each other, and the count of markers grouped will be placed
- * inside the group marker.
- * @skipline group_class_new
- * @until displayed_set
- *
- * For marker and group classes to represent a country, the same is done:
- * @skipline marker_class_new
- * @until displayed_set
- *
- * Next we'll create some markers representing cities and coutries.
- * We'll append them in a list, to close up them later. To create a marker
- * we need to pass the coordinates, marker class, group class and optionally,
- * data:
- * @skipline marker_add
- * @until data_chile
- * @until append
+ * Overlays can be placed over the map to represent anything we want. Let's
+ * say we want to represent some countries and cities with overlays. 
+ * 
+ * Before we create city or country overlays, let's create class overlays. 
+ *
+ * @skipline elm_map_overlay_class_add
+ * @until elm_map_overlay_icon_set
+ * These lines create a class overlay which represents cities.
+ * This class overlay will be used for grouping city overlays. 
+ * Later city overlays in the same class are appended to this class overlay. 
+ * if city overlays are near each other, they will be grouped.
+ *
+ * We can set the icon for the class so that the icon will be displayed 
+ * when city overlays are grouped.
+ * We can set the zoom required to display the overlays that belongs
+ * to this class, so if the zoom is less than this value, nothing
+ * will be shown. 
+ * 
+ * Country class can be created in the same way.
+ * @skipline elm_map_overlay_class_add
+ * @until elm_map_overlay_icon_set
+ *
+ * Next we'll create some overlays representing cities and coutries.
+ * We set the data for the overlay so that can be used later when 
+ * clicked callback is called.
+ * We'll append them into city class to be grouped.
+ * We'll append them in a list, to close up them later. 
+ * To create a default overlay, we need to pass the coordinates.
+ * @skipline elm_map_overlay_add
+ * @until eina_list_append
+ *
+ * We subscribe a smart callback "overlay,clicked" to create bubble on 
+ * the clicked overlay.
+ * @dontinclude map_example_02.c
+ * @skipline "overlay,clicked"
+ *
+ * Finally, on our @c main function, we ask the map to show all the overlays
+ * with the biggest zoom possible, passing the list of overlays added.
+ * @skipline elm_map_overlays_show
  *
  * We have created a specific structure for this example to store the name
  * of the place and a path to a image file to represent it.
  * @dontinclude map_example_02.c
  * @skipline typedef
- * @until Marker_Data;
+ * @until Overlay_Data;
  *
  * We'll create instances for each place:
  * @skipline argentina
  * @until sky_03
  *
- * Finally, on our @c main function, we ask the map to show all the markers
- * with the biggest zoom possible, passing the list of markers added:
- * @skipline list_show
- *
- * Actually the zoom is not what we want, so after the download of the map
- * is concluded, let's set another zoom level. For this we add a callback
- * for @c "downloaded" signal:
- * @skipline callback_add
- *
- * The callback function will simply set the zoom level we want and remove
- * the callback, otherwise it would be called all the time, after the map
- * is downloaded:
+  * To return an icon, all we need to do is to add a elm_icon and return it:
  * @dontinclude map_example_02.c
- * @skipline _map_downloaded
- * @until }
- *
- * We added two kinds of callback functions when we added the markers.
- * One will return the content of the bubbles, and other the icon to be
- * placed inside the marker.
- *
- * To return an icon, all we need to do is add a elm_icon and return it:
- * @dontinclude map_example_02.c
- * @skip static Evas_Object
- * @skip }
- * @skipline static Evas_Object
+ * @skipline _icon_get(
  * @until }
  *
- * For the content, let's return something more elaboreate. We will return
+ * For the content, let's return something more elaborate. We will return
  * a box with an image representing the place, and the name of this place:
- * @skipline static Evas_Object
+ * @skipline _box_get(
  * @until }
  *
  * See @ref map_example_02.c "map_example_02.c" for full source,
  * start point, and would like that he enters the address of his
  * destination in a entry, and we'll trace a route on the map.
  *
- * We'll start this example the same way
+ * We'll start this example in the same way
  * @ref map_example_01 "Map Example 1". Adding a map with buttons to control
  * zoom, so if you didn't read it yet, just do it now. Actually there is
  * a change, that we're aligning buttons to the top, since we wan't a
index 8600469..4aa7d7d 100644 (file)
@@ -8,10 +8,10 @@
 #define MARKER_MAX 1000
 #define NAME_ENTRY_TEXT "Enter freeform address"
 
-typedef struct Marker_Data
+typedef struct Overlay_Data
 {
    const char *file;
-} Marker_Data;
+} Overlay_Data;
 
 typedef struct Map_Source
 {
@@ -19,12 +19,11 @@ typedef struct Map_Source
    char *source_name;
 } Map_Source;
 
-static Elm_Map_Marker_Class *itc1, *itc2, *itc_parking;
-static Elm_Map_Group_Class *itc_group1, *itc_group2, *itc_group_parking, *route_group;
+static Elm_Map_Overlay *route_start, *route_end, *route_clas;
+static Elm_Map_Overlay *bubble_img;
+static Elm_Map_Overlay *bubble_parking;
 
 static Evas_Object *menu, *fs_win;
-/*static Elm_Map_Marker *markers[MARKER_MAX];*/
-static Elm_Map_Marker *route_from, *route_to;
 static Elm_Map_Route *route;
 static Elm_Map_Name *name;
 static Evas_Object *track;
@@ -33,22 +32,19 @@ static Evas_Coord old_x, old_y;
 static Evas_Coord old_d;
 static Map_Source ms[SOURCE_MAX];
 
-Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
-Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
-Marker_Data data3 = {PACKAGE_DATA_DIR"/images/panel_01.jpg"};
-Marker_Data data4 = {PACKAGE_DATA_DIR"/images/plant_01.jpg"};
-Marker_Data data5 = {PACKAGE_DATA_DIR"/images/rock_01.jpg"};
-Marker_Data data6 = {PACKAGE_DATA_DIR"/images/rock_02.jpg"};
-Marker_Data data7 = {PACKAGE_DATA_DIR"/images/sky_01.jpg"};
-Marker_Data data8 = {PACKAGE_DATA_DIR"/images/sky_02.jpg"};
-Marker_Data data9 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
-Marker_Data data10 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
-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);
+Overlay_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
+Overlay_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
+Overlay_Data data3 = {PACKAGE_DATA_DIR"/images/panel_01.jpg"};
+Overlay_Data data4 = {PACKAGE_DATA_DIR"/images/plant_01.jpg"};
+Overlay_Data data5 = {PACKAGE_DATA_DIR"/images/rock_01.jpg"};
+Overlay_Data data6 = {PACKAGE_DATA_DIR"/images/rock_02.jpg"};
+Overlay_Data data7 = {PACKAGE_DATA_DIR"/images/sky_01.jpg"};
+Overlay_Data data8 = {PACKAGE_DATA_DIR"/images/sky_02.jpg"};
+Overlay_Data data9 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
+Overlay_Data data10 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
+Overlay_Data data11= {PACKAGE_DATA_DIR"/images/wood_01.jpg"};
+Overlay_Data parking= {PACKAGE_DATA_DIR"/images/parking.png"};
+Overlay_Data icon_data = {PACKAGE_DATA_DIR"/images/icon_14.png"};
 
 static void
 #ifdef ELM_EMAP
@@ -98,48 +94,60 @@ my_map_longpressed(void *data __UNUSED__, Evas_Object *obj, void *event_info)
    name = elm_map_utils_convert_coord_into_name(obj, lon, lat);
 }
 
+static Evas_Object *
+_route_icon_get(Evas_Object *obj)
+{
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/bubble.png", NULL);
+   evas_object_show(icon);
+
+   return icon;
+}
+
 static void
 my_map_clicked_double(void *data __UNUSED__, Evas_Object *obj, void *event_info)
 {
    printf("clicked,double\n");
    double lon, lat;
-   double flon, flat, tlon, tlat;
    Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
    if (!down) return;
    if (elm_map_zoom_get(obj) < 5) return;
 
    elm_map_canvas_to_geo_convert(obj, down->canvas.x, down->canvas.y, &lon, &lat);
    printf("x:%d, y:%d, lon:%lf, lat:%lf\n", down->canvas.x, down->canvas.y, lon, lat);
-   if (!itc1) itc1 = elm_map_marker_class_new(obj);
 
-   elm_map_marker_class_del_cb_set(itc1, NULL);
 
-   if (!route_group)
+   if (!route_clas)
      {
-        route_group = elm_map_group_class_new(obj);
-        elm_map_group_class_icon_cb_set(route_group, _group_icon_get);
-        elm_map_group_class_data_set(route_group, (void *)PACKAGE_DATA_DIR"/images/bubble.png");
-        elm_map_group_class_style_set(route_group, "empty");
-        elm_map_group_class_zoom_displayed_set(route_group, 5);
+        route_clas = elm_map_overlay_class_add(obj);
+        elm_map_overlay_icon_set(route_clas, _route_icon_get(obj));
+        elm_map_overlay_displayed_zoom_min_set(route_clas, 5);
      }
 
-   if (route_from && route_to)
+   if (route_start && route_end)
      {
-        elm_map_marker_remove(route_from);
-        route_from = NULL;
-        elm_map_marker_remove(route_to);
-        route_to = NULL;
+        printf("11\n");
+        elm_map_overlay_del(route_start);
+        elm_map_overlay_del(route_end);
         elm_map_route_remove(route);
+        route_start = NULL;
+        route_end = NULL;
+        //route = NULL;
      }
 
-   if (!route_from) route_from = elm_map_marker_add(obj, lon, lat, itc1, route_group, NULL);
-   else route_to = elm_map_marker_add(obj, lon, lat, itc1, route_group, NULL);
+   if (!route_start) route_start = elm_map_overlay_add(obj, lon, lat);
+   else route_end = elm_map_overlay_add(obj, lon, lat);
 
-   if (route_from && route_to)
+   if (route_start && route_end)
      {
-        elm_map_marker_region_get(route_from, &flon, &flat);
-        elm_map_marker_region_get(route_to, &tlon, &tlat);
-        route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR, ELM_MAP_ROUTE_METHOD_FASTEST, flon, flat, tlon, tlat);
+        double start_lon, start_lat, end_lon, end_lat;
+        elm_map_overlay_class_append(route_clas, route_start);
+        elm_map_overlay_class_append(route_clas, route_end);
+        elm_map_overlay_geo_get(route_start, &start_lon, &start_lat);
+        elm_map_overlay_geo_get(route_end, &end_lon, &end_lat);
+        route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR,
+                                  ELM_MAP_ROUTE_METHOD_FASTEST,
+                                  start_lon, start_lat, end_lon, end_lat);
         elm_map_route_color_set(route, 255, 0, 0, 255);
      }
 }
@@ -455,7 +463,7 @@ map_marker_add(void *data)
    int i;
    Elm_Map_Group_Class *g_clas;
    Elm_Map_Marker_Class *m_clas;
-   Marker_Data *d = &data7;
+   Overlay_Data *d = &data7;
 
    if (*markers) return;
    for (i =0; i<MARKER_MAX; i++)
@@ -476,7 +484,7 @@ map_marker_add(void *data)
         else
           {
              m_clas = itc_parking;
-             d = &data_parking;
+             d = &parking;
           }
 
         style = rand() % 2;
@@ -522,61 +530,31 @@ my_map_entry_activated(void *data, Evas_Object *obj, void *event_info __UNUSED__
 */
 
 static Evas_Object *
-_marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
+_box_get(Evas_Object *obj, Overlay_Data *data)
 {
-   Marker_Data *d = data;
-
-   Evas_Object *bx = elm_box_add(obj);
+   Evas_Object *bx, *img, *label;
+   bx = elm_box_add(obj);
    evas_object_show(bx);
 
-   if (d == &data3)
-     {
-        Evas_Object *icon = elm_icon_add(obj);
-        elm_icon_file_set(icon, d->file, NULL);
-        evas_object_show(icon);
-
-        Evas_Object *o = elm_button_add(obj);
-        elm_object_part_content_set(o, "icon", icon);
-        evas_object_show(o);
-        elm_box_pack_end(bx, o);
-     }
-   else
-     {
-        Evas_Object *o = evas_object_image_add(evas_object_evas_get(obj));
-        evas_object_image_file_set(o, d->file, NULL);
-        evas_object_image_filled_set(o, EINA_TRUE);
-        evas_object_size_hint_min_set(o, 64, 64);
-        evas_object_show(o);
-        elm_box_pack_end(bx, o);
-
-        Evas_Object *lbl = elm_label_add(obj);
-        elm_object_text_set(lbl, "Wolves Go !");
-        evas_object_show(lbl);
-        elm_box_pack_end(bx, lbl);
-     }
-
+   img = evas_object_image_add(evas_object_evas_get(obj));
+   evas_object_image_file_set(img, data->file, NULL);
+   evas_object_image_filled_set(img, EINA_TRUE);
+   evas_object_size_hint_min_set(img, 64, 64);
+   evas_object_show(img);
+   elm_box_pack_end(bx, img);
+
+   label = elm_label_add(obj);
+   elm_object_text_set(label, "Wolves go!!");
+   evas_object_show(label);
+   elm_box_pack_end(bx, label);
    return bx;
 }
 
 static Evas_Object *
-_icon_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
+_icon_get(Evas_Object *obj, Overlay_Data *data)
 {
-   Marker_Data *d = data;
-
-   Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, d->file, NULL);
-   evas_object_show(icon);
-
-   return icon;
-}
-
-static Evas_Object *
-_group_icon_get(Evas_Object *obj, void *data)
-{
-   char *file = data;
-
    Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, file, NULL);
+   elm_icon_file_set(icon, data->file, NULL);
    evas_object_show(icon);
 
    return icon;
@@ -689,6 +667,62 @@ _map_mouse_up(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj __U
      }
 }
 
+static void
+_overlay_cb(void *data __UNUSED__, Evas_Object *map, void *ev)
+{
+   printf("Overlay clicked: ");
+   Elm_Map_Overlay *overlay = ev;
+   Evas_Object *bx;
+
+   Overlay_Data *od = elm_map_overlay_data_get(overlay);
+   if (!od)
+     {
+        printf("No overlay data\n");
+     }
+   else if (elm_map_overlay_type_get(overlay) == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+     {
+        // prevent duplication
+        if (!bubble_img)  bubble_img = elm_map_overlay_bubble_add(map);
+
+        elm_map_overlay_bubble_follow(bubble_img, overlay);
+        bx = _box_get(map, od);
+        elm_map_overlay_bubble_content_clear(bubble_img);
+        elm_map_overlay_bubble_content_append(bubble_img, bx);
+        printf("overlay rendered\n");
+     }
+   else printf("not default type\n");
+}
+
+static void
+_parking_cb(void *data __UNUSED__, Evas_Object *map, Elm_Map_Overlay *ovl)
+{
+   printf("Parking clicked\n");
+   if (elm_map_overlay_type_get(ovl) != ELM_MAP_OVERLAY_TYPE_DEFAULT) return;
+
+   double lon, lat;
+   elm_map_overlay_geo_get(ovl, &lon, &lat);
+   if (!bubble_parking)
+     {
+        Evas_Object *bubble, *label;
+        bubble = elm_bubble_add(map);
+        elm_bubble_corner_set(bubble, "bottom_left");
+        elm_object_text_set(bubble, "Overlay object");
+        elm_object_part_text_set(bubble, "info", "Bubble is overlayed");
+
+        label = elm_label_add(bubble);
+        elm_object_text_set(label, "Parking Here !!");
+        evas_object_show(label);
+        elm_object_content_set(bubble, label);
+
+        evas_object_resize(bubble, 125, 50);
+        evas_object_show(bubble);
+
+        bubble_parking = elm_map_overlay_add(map, lon + 0.0006, lat + 0.0006);
+        elm_map_overlay_content_set(bubble_parking, bubble);
+     }
+   elm_map_overlay_geo_set(bubble_parking, lon + 0.0006, lat + 0.0006);
+}
+
 void
 test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
@@ -707,6 +741,11 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
    map = elm_map_add(win);
    if (map)
      {
+        Elm_Map_Overlay *ovl_1, *ovl_2, *ovl_3, *ovl_4, *ovl_5, *ovl6;
+        Elm_Map_Overlay *ovl_7, *ovl_8, *ovl_9, *ovl_10, *ovl_11;
+        Elm_Map_Overlay *parking1, *parking2, *parking3, *parking4, *parking5;
+        Elm_Map_Overlay *grp1, *grp2, *grp_parking;
+
         srand(time(NULL));
 
         source_names = elm_map_source_names_get(map);
@@ -720,34 +759,6 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         elm_win_resize_object_add(win, map);
         evas_object_data_set(map, "window", win);
 
-        itc1 = elm_map_marker_class_new(map);
-        elm_map_marker_class_get_cb_set(itc1, _marker_get);
-        elm_map_marker_class_del_cb_set(itc1, NULL);
-
-        itc2 = elm_map_marker_class_new(map);
-        elm_map_marker_class_get_cb_set(itc2, _marker_get);
-        elm_map_marker_class_del_cb_set(itc2, NULL);
-        elm_map_marker_class_style_set(itc2, "radio2");
-
-        itc_parking = elm_map_marker_class_new(map);
-        elm_map_marker_class_get_cb_set(itc_parking, _marker_get);
-        elm_map_marker_class_del_cb_set(itc_parking, NULL);
-        elm_map_marker_class_icon_cb_set(itc_parking, _icon_get);
-        elm_map_marker_class_style_set(itc_parking, "empty");
-
-        itc_group1 = elm_map_group_class_new(map);
-        elm_map_group_class_data_set(itc_group1, (void *)PACKAGE_DATA_DIR"/images/plant_01.jpg");
-
-        itc_group2 = elm_map_group_class_new(map);
-        elm_map_group_class_style_set(itc_group2, "radio2");
-        elm_map_group_class_zoom_displayed_set(itc_group1, 3);
-
-        itc_group_parking = elm_map_group_class_new(map);
-        elm_map_group_class_icon_cb_set(itc_group_parking, _group_icon_get);
-        elm_map_group_class_data_set(itc_group_parking, (void *)PACKAGE_DATA_DIR"/images/parking.png");
-        elm_map_group_class_style_set(itc_group_parking, "empty");
-        elm_map_group_class_zoom_displayed_set(itc_group_parking, 5);
-
         evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_DOWN,
                                        _map_mouse_down, map);
         evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_MOVE,
@@ -755,21 +766,6 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_UP,
                                        _map_mouse_up, map);
 
-        elm_map_marker_add(map, 2.352, 48.857, itc1, itc_group1, &data1);
-        elm_map_marker_add(map, 2.355, 48.857, itc1, itc_group1, &data3);
-        elm_map_marker_add(map, 3, 48.857, itc2, itc_group1, &data2);
-        elm_map_marker_add(map, 2.352, 49, itc2, itc_group1, &data1);
-
-        elm_map_marker_add(map, 7.31451, 48.857127, itc1, itc_group1, &data10);
-        elm_map_marker_add(map, 7.314704, 48.857119, itc1, itc_group1, &data4);
-        elm_map_marker_add(map, 7.314704, 48.857119, itc2, itc_group1, &data5);
-        elm_map_marker_add(map, 7.31432, 48.856785, itc2, itc_group1, &data6);
-        elm_map_marker_add(map, 7.3148, 48.85725, itc1, itc_group2, &data7);
-        elm_map_marker_add(map, 7.316445, 48.8572210000694, itc1, itc_group1, &data8);
-        elm_map_marker_add(map, 7.316527000125, 48.85609, itc2, itc_group2, &data9);
-        elm_map_marker_add(map, 7.3165409990833, 48.856078, itc2, itc_group1, &data11);
-        elm_map_marker_add(map, 7.319812, 48.856561, itc2, itc_group2, &data10);
-
         evas_object_smart_callback_add(map, "clicked", my_map_clicked, map);
         evas_object_smart_callback_add(map, "press", my_map_press, map);
         evas_object_smart_callback_add(map, "longpressed", my_map_longpressed, map);
@@ -789,6 +785,71 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __
         evas_object_smart_callback_add(map, "route,loaded", my_map_route_loaded, map);
         evas_object_smart_callback_add(map, "name,load", my_map_name_load, map);
         evas_object_smart_callback_add(map, "name,loaded", my_map_name_loaded, map);
+        evas_object_smart_callback_add(map, "overlay,clicked", _overlay_cb, map);
+
+        // Create Overlays
+        ovl_1 = elm_map_overlay_add(map, 2.352, 48.857);
+        ovl_2 = elm_map_overlay_add(map, 3, 48.857);
+        ovl_3 = elm_map_overlay_add(map, 2.352, 49);
+        ovl_4 = elm_map_overlay_add(map, 7.31451, 48.857127);
+        ovl_5 = elm_map_overlay_add(map, 7.314704, 48.857119);
+        ovl6 = elm_map_overlay_add(map, 7.31432, 48.856785);
+        ovl_7 = elm_map_overlay_add(map, 7.3148, 48.85725);
+        ovl_8 = elm_map_overlay_add(map, 7.316445, 48.8572210000694);
+        ovl_9 = elm_map_overlay_add(map, 7.316527000125, 48.85609);
+        ovl_10 = elm_map_overlay_add(map, 7.3165409990833, 48.856078);
+        ovl_11 = elm_map_overlay_add(map, 7.319812, 48.856561);
+        elm_map_overlay_data_set(ovl_1, &data1);
+        elm_map_overlay_data_set(ovl_2, &data2);
+        elm_map_overlay_data_set(ovl_3, &data3);
+        elm_map_overlay_data_set(ovl_4, &data4);
+        elm_map_overlay_data_set(ovl_5, &data5);
+        elm_map_overlay_data_set(ovl6, &data6);
+        elm_map_overlay_data_set(ovl_7, &data7);
+        elm_map_overlay_data_set(ovl_8, &data8);
+        elm_map_overlay_data_set(ovl_9, &data9);
+        elm_map_overlay_data_set(ovl_10, &data10);
+        elm_map_overlay_data_set(ovl_11, &data11);
+
+        // Append overlays to groups
+        grp1 = elm_map_overlay_class_add(map);
+        elm_map_overlay_displayed_zoom_min_set(grp1, 3);
+        elm_map_overlay_class_append(grp1, ovl_1);
+        elm_map_overlay_class_append(grp1, ovl_2);
+        elm_map_overlay_class_append(grp1, ovl_3);
+        elm_map_overlay_class_append(grp1, ovl_4);
+        elm_map_overlay_class_append(grp1, ovl_5);
+        elm_map_overlay_class_append(grp1, ovl6);
+
+        // Append overlays to groups
+        grp2 = elm_map_overlay_class_add(map);
+        elm_map_overlay_class_append(grp2, ovl_7);
+        elm_map_overlay_class_append(grp2, ovl_8);
+        elm_map_overlay_class_append(grp2, ovl_9);
+        elm_map_overlay_class_append(grp2, ovl_10);
+        elm_map_overlay_class_append(grp2, ovl_11);
+
+        // Create overlays
+        parking1 = elm_map_overlay_add(map, 127.04871, 37.25730);
+        parking2 = elm_map_overlay_add(map, 127.05578, 37.25545);
+        parking3 = elm_map_overlay_add(map, 127.05515, 37.25439);
+        parking4 = elm_map_overlay_add(map, 127.05328, 37.25721);
+        parking5 = elm_map_overlay_add(map, 127.05431, 37.25873);
+        elm_map_overlay_icon_set(parking4, _icon_get(map, &icon_data));
+        elm_map_overlay_get_cb_set(parking1, _parking_cb, NULL);
+        elm_map_overlay_get_cb_set(parking2, _parking_cb, NULL);
+        elm_map_overlay_get_cb_set(parking3, _parking_cb, NULL);
+        elm_map_overlay_get_cb_set(parking4, _parking_cb, NULL);
+        elm_map_overlay_get_cb_set(parking5, _parking_cb, NULL);
+
+        // Append overlays to groups
+        grp_parking = elm_map_overlay_class_add(map);
+        elm_map_overlay_icon_set(grp_parking, _icon_get(map, &parking));
+        elm_map_overlay_class_append(grp_parking, parking1);
+        elm_map_overlay_class_append(grp_parking, parking2);
+        elm_map_overlay_class_append(grp_parking, parking3);
+        elm_map_overlay_class_append(grp_parking, parking4);
+        elm_map_overlay_class_append(grp_parking, parking5);
 
         evas_object_show(map);
      }
index 8fd5778..3572498 100644 (file)
 static void
 _bt_zoom_in(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
-   Evas_Object *map = data;
    int zoom;
-
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
-   zoom = elm_map_zoom_get(map);
-   elm_map_zoom_set(map, zoom + 1);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(data);
+   elm_map_zoom_set(data, zoom + 1);
 }
 
 static void
 _bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
-   Evas_Object *map = data;
    int zoom;
-
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
-   zoom = elm_map_zoom_get(map);
-   elm_map_zoom_set(map, zoom - 1);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(data);
+   elm_map_zoom_set(data, zoom - 1);
 }
 
 static void
 _bt_zoom_fit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   Evas_Object *map = data;
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FIT);
 }
 
 static void
 _bt_zoom_fill(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   Evas_Object *map = data;
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL);
 }
 
 static void
@@ -117,8 +111,8 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__)
    evas_object_show(bt);
    evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);
 
-   elm_map_geo_region_show(map, -43.2, -22.9);
    elm_map_zoom_set(map, 12);
+   elm_map_geo_region_show(map, -43.2, -22.9);
 
    evas_object_resize(win, 512, 512);
    evas_object_show(win);
index 0a8a8c0..e0c9215 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Simple Elementary's <b>map widget</b> example, illustrating markers
+ * Simple Elementary's <b>map widget</b> example, illustrating overlays
  * usage.
  *
  * See stdout/stderr for output. Compile with:
 # define __UNUSED__
 #endif
 
-typedef struct _Marker_Data
+typedef struct _Overlay_Data
 {
    const char *name;
    const char *file;
-} Marker_Data;
+} Overlay_Data;
 
-Marker_Data data_argentina = {"Argentina",
+Overlay_Data data_argentina = {"Argentina",
      PACKAGE_DATA_DIR"/images/rock_01.jpg"};
-Marker_Data data_chile = {"Chile",
+Overlay_Data data_chile = {"Chile",
      PACKAGE_DATA_DIR"/images/rock_02.jpg"};
-Marker_Data data_sampa = {"São Paulo",
+Overlay_Data data_sampa = {"São Paulo",
      PACKAGE_DATA_DIR"/images/sky_01.jpg"};
-Marker_Data data_rio = {"Rio de Janeiro",
+Overlay_Data data_rio = {"Rio de Janeiro",
      PACKAGE_DATA_DIR"/images/sky_02.jpg"};
-Marker_Data data_brasilia = {"Brasília",
+Overlay_Data data_brasilia = {"Brasília",
      PACKAGE_DATA_DIR"/images/sky_03.jpg"};
 
+static Elm_Map_Overlay *bubble;
+
 static Evas_Object *
-_marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
+_icon_get(Evas_Object *obj, const char *file)
 {
-   Evas_Object *bx, *im, *lbl;
-   Marker_Data *md = data;
-
-   bx = elm_box_add(obj);
-   evas_object_show(bx);
-
-   im = elm_image_add(obj);
-   elm_image_file_set(im, md->file, NULL);
-   evas_object_size_hint_min_set(im, 64, 64);
-   evas_object_show(im);
-   elm_box_pack_end(bx, im);
-
-   lbl = elm_label_add(obj);
-   elm_object_text_set(lbl, md->name);
-   evas_object_show(lbl);
-   elm_box_pack_end(bx, lbl);
-
-   return bx;
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, file, NULL);
+   evas_object_show(icon);
+   return icon;
 }
 
 static Evas_Object *
-_marker_city_content_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data __UNUSED__)
+_city_icon_get(Evas_Object *obj)
 {
-   Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_07.png", NULL);
-   evas_object_show(icon);
+   return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_07.png");
+}
 
-   return icon;
+static Evas_Object *
+_clas_city_icon_get(Evas_Object *obj)
+{
+   return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_05.png");
 }
 
 static Evas_Object *
-_group_city_content_get(Evas_Object *obj, void *data __UNUSED__)
+_country_icon_get(Evas_Object *obj)
 {
-   Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_05.png", NULL);
-   evas_object_show(icon);
-   return icon;
+   return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_06.png");
 }
 
 static Evas_Object *
-_marker_country_content_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data __UNUSED__)
+_clas_country_icon_get(Evas_Object *obj)
 {
-   Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_06.png", NULL);
-   evas_object_show(icon);
-   return icon;
+   return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_04.png");
 }
 
 static Evas_Object *
-_group_country_content_get(Evas_Object *obj, void *data __UNUSED__)
+_box_get(Evas_Object *obj, Overlay_Data *data)
 {
-   Evas_Object *icon = elm_icon_add(obj);
-   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_04.png", NULL);
-   evas_object_show(icon);
-   return icon;
+   Evas_Object *bx, *img, *label;
+   bx = elm_box_add(obj);
+   evas_object_show(bx);
+
+   img = evas_object_image_add(evas_object_evas_get(obj));
+   evas_object_image_file_set(img, data->file, NULL);
+   evas_object_image_filled_set(img, EINA_TRUE);
+   evas_object_size_hint_min_set(img, 64, 64);
+   evas_object_show(img);
+   elm_box_pack_end(bx, img);
+
+   label = elm_label_add(obj);
+   elm_object_text_set(label, data->name);
+   evas_object_show(label);
+   elm_box_pack_end(bx, label);
+   return bx;
+}
+
+static void
+_overlay_cb(void *data __UNUSED__, Evas_Object *map, void *ev)
+{
+   printf("Overlay clicked\n");
+   Elm_Map_Overlay *overlay = ev;
+   Evas_Object *bx;
+
+   // prevent duplication
+   if (!bubble)  bubble = elm_map_overlay_bubble_add(map);
+
+   elm_map_overlay_bubble_follow(bubble, overlay);
+   elm_map_overlay_bubble_content_clear(bubble);
+   bx = _box_get(map, elm_map_overlay_data_get(overlay));
+   elm_map_overlay_bubble_content_append(bubble, bx);
 }
 
 static void
@@ -152,13 +164,11 @@ EAPI_MAIN int
 elm_main(int argc __UNUSED__, char **argv __UNUSED__)
 {
    Evas_Object *win, *bg, *map, *box, *bt;
-   static Elm_Map_Marker_Class *mc_city, *mc_country;
-   static Elm_Map_Group_Class *gc_city, *gc_country;
-   Eina_List *markers = NULL;
-   Elm_Map_Marker *m;
+   Eina_List *ovls = NULL;
+   Elm_Map_Overlay *ovl, *city_clas, *country_clas;
 
    win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
-   elm_win_title_set(win, "Map Markers Example");
+   elm_win_title_set(win, "Map Overlay Example");
    evas_object_smart_callback_add(win, "delete,request", _on_done, NULL);
 
    bg = elm_bg_add(win);
@@ -198,42 +208,47 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__)
    evas_object_show(bt);
    evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);
 
-   mc_city = elm_map_marker_class_new(map);
-   elm_map_marker_class_get_cb_set(mc_city, _marker_get);
-   elm_map_marker_class_icon_cb_set(mc_city, _marker_city_content_get);
-   elm_map_marker_class_style_set(mc_city, "radio");
-
-   gc_city = elm_map_group_class_new(map);
-   elm_map_group_class_style_set(gc_city, "radio2");
-   elm_map_group_class_icon_cb_set(gc_city, _group_city_content_get);
-   elm_map_group_class_zoom_displayed_set(gc_city, 3);
-
-   mc_country = elm_map_marker_class_new(map);
-   elm_map_marker_class_get_cb_set(mc_country, _marker_get);
-   elm_map_marker_class_icon_cb_set(mc_country, _marker_country_content_get);
-   elm_map_marker_class_style_set(mc_country, "empty");
-
-   gc_country = elm_map_group_class_new(map);
-   elm_map_group_class_style_set(gc_country, "empty");
-   elm_map_group_class_icon_cb_set(gc_country, _group_country_content_get);
-   elm_map_group_class_zoom_displayed_set(gc_country, 1);
-
-   m = elm_map_marker_add(map, -43.2, -22.9, mc_city, gc_city, &data_rio);
-   markers = eina_list_append(markers, m);
-   m = elm_map_marker_add(map, -46.63, -23.55, mc_city, gc_city, &data_sampa);
-   markers = eina_list_append(markers, m);
-   m = elm_map_marker_add(map, -47.88, -15.78, mc_city, gc_city,
-                          &data_brasilia);
-   markers = eina_list_append(markers, m);
-
-   m = elm_map_marker_add(map, -65.23, -35.1, mc_country, gc_country,
-                      &data_argentina);
-   markers = eina_list_append(markers, m);
-   m = elm_map_marker_add(map, -71.3, -31.75, mc_country, gc_country,
-                      &data_chile);
-   markers = eina_list_append(markers, m);
-
-   elm_map_markers_list_show(markers);
+   evas_object_smart_callback_add(map, "overlay,clicked", _overlay_cb, NULL);
+
+   city_clas = elm_map_overlay_class_add(map);
+   elm_map_overlay_displayed_zoom_min_set(city_clas, 3);
+   elm_map_overlay_icon_set(city_clas, _clas_city_icon_get(map));
+
+   country_clas = elm_map_overlay_class_add(map);
+   elm_map_overlay_displayed_zoom_min_set(country_clas, 1);
+   elm_map_overlay_icon_set(country_clas, _clas_country_icon_get(map));
+
+   ovl = elm_map_overlay_add(map, -43.2, -22.9);
+   elm_map_overlay_icon_set(ovl, _city_icon_get(map));
+   elm_map_overlay_data_set(ovl, &data_rio);
+   elm_map_overlay_class_append(city_clas, ovl);
+   ovls = eina_list_append(ovls, ovl);
+
+   ovl = elm_map_overlay_add(map, -46.63, -23.55);
+   elm_map_overlay_icon_set(ovl, _city_icon_get(map));
+   elm_map_overlay_data_set(ovl, &data_sampa);
+   elm_map_overlay_class_append(city_clas, ovl);
+   ovls = eina_list_append(ovls, ovl);
+
+   ovl = elm_map_overlay_add(map, -47.88, -15.78);
+   elm_map_overlay_icon_set(ovl, _city_icon_get(map));
+   elm_map_overlay_data_set(ovl, &data_brasilia);
+   elm_map_overlay_class_append(city_clas, ovl);
+   ovls = eina_list_append(ovls, ovl);
+
+   ovl = elm_map_overlay_add(map, -65.23, -35.1);
+   elm_map_overlay_icon_set(ovl, _country_icon_get(map));
+   elm_map_overlay_data_set(ovl, &data_argentina);
+   elm_map_overlay_class_append(country_clas, ovl);
+   ovls = eina_list_append(ovls, ovl);
+
+   ovl = elm_map_overlay_add(map, -71.3, -31.75);
+   elm_map_overlay_icon_set(ovl, _country_icon_get(map));
+   elm_map_overlay_data_set(ovl, &data_chile);
+   elm_map_overlay_class_append(country_clas, ovl);
+   ovls = eina_list_append(ovls, ovl);
+
+   elm_map_overlays_show(ovls);
 
    evas_object_resize(win, 512, 512);
    evas_object_show(win);
index 25f3b69..6a49b45 100644 (file)
@@ -63,37 +63,31 @@ _bt_route(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 static void
 _bt_zoom_in(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
-   Evas_Object *map = data;
    int zoom;
-
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
-   zoom = elm_map_zoom_get(map);
-   elm_map_zoom_set(map, zoom + 1);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(data);
+   elm_map_zoom_set(data, zoom + 1);
 }
 
 static void
 _bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
-   Evas_Object *map = data;
    int zoom;
-
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
-   zoom = elm_map_zoom_get(map);
-   elm_map_zoom_set(map, zoom - 1);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(data);
+   elm_map_zoom_set(data, zoom - 1);
 }
 
 static void
 _bt_zoom_fit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   Evas_Object *map = data;
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FIT);
 }
 
 static void
 _bt_zoom_fill(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   Evas_Object *map = data;
-   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL);
 }
 
 static void
@@ -192,8 +186,8 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__)
    example_data.start_lon = -43.175;
    example_data.start_lat = -22.97;
 
-   elm_map_geo_region_show(map, example_data.start_lon, example_data.start_lat);
    elm_map_zoom_set(map, 12);
+   elm_map_geo_region_show(map, example_data.start_lon, example_data.start_lat);
 
    evas_object_resize(win, 512, 512);
    evas_object_show(win);
index 8214301..0c90c6d 100644 (file)
@@ -12,6 +12,10 @@ typedef struct _Widget_Data Widget_Data;
 typedef struct _Pan Pan;
 typedef struct _Grid Grid;
 typedef struct _Grid_Item Grid_Item;
+typedef struct _Overlay_Default Overlay_Default;
+typedef struct _Overlay_Group Overlay_Group;
+typedef struct _Overlay_Class Overlay_Class;
+typedef struct _Overlay_Bubble Overlay_Bubble;
 typedef struct _Marker_Group Marker_Group;
 typedef struct _Marker_Bubble Marker_Bubble;
 typedef struct _Path_Node Path_Node;
@@ -19,14 +23,16 @@ typedef struct _Path_Waypoint Path_Waypoint;
 typedef struct _Url_Data Url_Data;
 typedef struct _Route_Dump Route_Dump;
 typedef struct _Name_Dump Name_Dump;
-typedef struct _Track_Dump Track_Dump;
 typedef struct _Delayed_Data Delayed_Data;
 typedef struct _Map_Sources_Tab Map_Sources_Tab;
 
 #define ROUND(z) (((z) < 0) ? (int)ceil((z) - 0.005) : (int)floor((z) + 0.005))
 #define EVAS_MAP_POINT 4
 #define DEFAULT_TILE_SIZE 256
+#define MAX_CONCURRENT_DOWNLOAD 10
+
 #define MARER_MAX_NUMBER 30
+
 #define CACHE_ROOT_PATH   "/tmp/elm_map"
 #define CACHE_PATH        CACHE_ROOT_PATH"/%d/%d/%d"
 #define CACHE_FILE_PATH   "%s/%d.png"
@@ -47,16 +53,8 @@ typedef struct _Map_Sources_Tab Map_Sources_Tab;
 #define NOMINATIM_ATTR_LON "lon"
 #define NOMINATIM_ATTR_LAT "lat"
 
-#define MAX_CONCURRENT_DOWNLOAD 10
-
-/* FIXME: This is unused currently
-#define GPX_NAME "name>"
-#define GPX_COORDINATES "trkpt "
-#define GPX_LON "lon"
-#define GPX_LAT "lat"
-#define GPX_ELE "ele>"
-#define GPX_TIME "time>"
-*/
+#define OVERLAY_CLASS_ZOOM_MAX 255
+#define OVERLAY_GROUPING_SCALE 2
 
 enum _Route_Xml_Attribute
 {
@@ -91,6 +89,7 @@ struct _Delayed_Data
    int zoom;
    double lon, lat;
    Eina_List *markers;
+   Eina_List *overlays;
 };
 
 // Map sources
@@ -101,12 +100,12 @@ struct _Map_Sources_Tab
    const char *name;
    int zoom_min;
    int zoom_max;
-   ElmMapModuleUrlFunc url_cb;
+   Elm_Map_Module_Url_Func url_cb;
    Elm_Map_Route_Sources route_source;
-   ElmMapModuleRouteUrlFunc route_url_cb;
-   ElmMapModuleNameUrlFunc name_url_cb;
-   ElmMapModuleGeoIntoCoordFunc geo_into_coord;
-   ElmMapModuleCoordIntoGeoFunc coord_into_geo;
+   Elm_Map_Module_Route_Url_Func route_url_cb;
+   Elm_Map_Module_Name_Url_Func name_url_cb;
+   Elm_Map_Module_Geo_Into_Coord_Func geo_into_coord;
+   Elm_Map_Module_Coord_Into_Geo_Func coord_into_geo;
 };
 
 struct _Url_Data
@@ -117,14 +116,83 @@ struct _Url_Data
    char *fname;
 };
 
+struct _Overlay_Default
+{
+   Evas_Coord w, h;
+
+   // Display priority is obj > icon > clas_obj > clas_icon > layout
+   Evas_Object *obj;
+   Evas_Object *icon;
+
+   // if obj or icon exists, do not inherit from class
+   Evas_Object *clas_obj;      // Duplicated from class icon
+   Evas_Object *clas_obj_ref;  // Checking fro class icon is changed
+   Evas_Object *clas_icon;     // Duplicated from class icon
+   Evas_Object *clas_icon_ref; // Checking for class icon is changed
+
+   char *style;
+   Evas_Object *layout;
+   double lon, lat;
+   Evas_Coord x, y;
+};
+
+struct _Overlay_Group
+{
+   Overlay_Default *ovl;
+   Evas_Object *clas_icon;
+   Elm_Map_Overlay *clas;
+   Eina_List *members;
+};
+
+struct _Overlay_Class
+{
+   Elm_Map_Overlay *clas;
+   Evas_Object *obj;
+   char *style;
+   Evas_Object *icon;
+   Eina_List *members;
+   int zoom_max;
+};
+
+struct _Overlay_Bubble
+{
+   Widget_Data *wd;
+   Evas_Object *pobj;
+   Evas_Object *obj, *sc, *bx;
+   double lon, lat;
+   Evas_Coord x, y, w, h;
+};
+
+struct _Elm_Map_Overlay
+{
+   Widget_Data *wd;
+
+   Eina_Bool paused : 1;
+   Eina_Bool hide : 1;
+   Evas_Coord zoom_min;
+
+    void *data;               // user set data
+
+   Elm_Map_Overlay_Type type;
+   void *ovl;                 // Overlay Data for each type
+
+   // These are not used if overlay type is class
+   Eina_Bool grp_in : 1;
+   Eina_Bool grp_boss : 1;
+   Overlay_Group *grp;
+
+   Elm_Map_Overlay_Get_Cb cb;
+   void *cb_data;
+};
+
 struct _Elm_Map_Marker_Class
 {
    const char *style;
    struct _Elm_Map_Marker_Class_Func
      {
-        ElmMapMarkerGetFunc get;
-        ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del()
-        ElmMapMarkerIconGetFunc icon_get;
+        Elm_Map_Marker_Get_Func get;
+        Elm_Map_Marker_Del_Func del; //if NULL the object will be destroyed with evas_object_del()
+        Elm_Map_Marker_Icon_Get_Func icon_get;
      } func;
 };
 
@@ -139,7 +207,7 @@ struct _Elm_Map_Group_Class
    void *data;
    struct
      {
-        ElmMapGroupIconGetFunc icon_get;
+        Elm_Map_Group_Icon_Get_Func icon_get;
      } func;
 
    Eina_Bool hide : 1;
@@ -372,6 +440,8 @@ struct _Widget_Data
    Eina_List *route;
    Eina_List *track;
    Eina_List *names;
+
+   Eina_List *overlays;
 };
 
 static char *_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
@@ -421,6 +491,7 @@ static const char SIG_ROUTE_LOAD[] = "route,load";
 static const char SIG_ROUTE_LOADED[] = "route,loaded";
 static const char SIG_NAME_LOAD[] = "name,load";
 static const char SIG_NAME_LOADED[] = "name,loaded";
+static const char SIG_OVERLAY_CLICKED[] = "overlay,clicked";
 static const Evas_Smart_Cb_Description _signals[] = {
        {SIG_CHANGED, ""},
        {SIG_CLICKED, ""},
@@ -442,6 +513,7 @@ static const Evas_Smart_Cb_Description _signals[] = {
        {SIG_ROUTE_LOADED, ""},
        {SIG_NAME_LOAD, ""},
        {SIG_NAME_LOADED, ""},
+       {SIG_OVERLAY_CLICKED, ""},
        {NULL, NULL}
 };
 
@@ -452,15 +524,15 @@ module_list_cb(Eina_Module *m, void *data)
    Widget_Data *wd = data;
 
    Map_Sources_Tab *s;
-   ElmMapModuleSourceFunc source;
-   ElmMapModuleZoomMinFunc zoom_min;
-   ElmMapModuleZoomMaxFunc zoom_max;
-   ElmMapModuleUrlFunc url;
-   ElmMapModuleRouteSourceFunc route_source;
-   ElmMapModuleRouteUrlFunc route_url;
-   ElmMapModuleNameUrlFunc name_url;
-   ElmMapModuleGeoIntoCoordFunc geo_into_coord;
-   ElmMapModuleCoordIntoGeoFunc coord_into_geo;
+   Elm_Map_Module_Source_Func source;
+   Elm_Map_Module_Zoom_Min_Func zoom_min;
+   Elm_Map_Module_Zoom_Max_Func zoom_max;
+   Elm_Map_Module_Url_Func url;
+   Elm_Map_Module_Route_Source_Func route_source;
+   Elm_Map_Module_Route_Url_Func route_url;
+   Elm_Map_Module_Name_Url_Func name_url;
+   Elm_Map_Module_Geo_Into_Coord_Func geo_into_coord;
+   Elm_Map_Module_Coord_Into_Geo_Func coord_into_geo;
    const char *file;
 
    file = eina_module_file_get(m);
@@ -651,6 +723,22 @@ _obj_place(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coor
 }
 
 static void
+_region_show(void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
+   int x, y, w, h;
+
+   elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat,
+                                        dd->wd->size.w, &x, &y);
+   _viewport_size_get(dd->wd, &w, &h);
+   x = x - (w / 2);
+   y = y - (h / 2);
+   elm_smart_scroller_child_region_show(dd->wd->scr, x, y, w, h);
+   evas_object_smart_changed(dd->wd->pan_smart);
+}
+
+static void
 _bubble_update(Marker_Bubble *bubble, Eina_List *contents)
 {
    EINA_SAFETY_ON_NULL_RETURN(bubble);
@@ -1090,7 +1178,6 @@ _marker_place(Widget_Data *wd)
      }
 }
 
-
 static void
 _grid_item_coord_get(Grid_Item *gi, int *x, int *y, int *w, int *h)
 {
@@ -1835,2477 +1922,3828 @@ _mouse_wheel_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, voi
 }
 
 static void
-_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+_region_max_min_get(Eina_List *overlays, double *max_longitude, double *min_longitude, double *max_latitude, double *min_latitude)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
-   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
-
-   sd->wd->pan_x = x;
-   sd->wd->pan_y = y;
-   evas_object_smart_changed(obj);
+   double max_lon = -180, min_lon = 180;
+   double max_lat = -90, min_lat = 90;
+   Elm_Map_Overlay *overlay;
+   EINA_LIST_FREE(overlays, overlay)
+     {
+        double lon, lat;
+        if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+          {
+             Overlay_Default *ovl = overlay->ovl;
+             lon = ovl->lon;
+             lat = ovl->lat;
+          }
+        else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+          {
+             // FIXME: class center coord is alright??
+             Overlay_Class *ovl = overlay->ovl;
+             double max_lo, min_lo, max_la, min_la;
+             _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la,
+                                 &min_la);
+             lon = (max_lo + min_lo) / 2;
+             lat = (max_la + min_la) / 2;
+          }
+        else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
+          {
+             Overlay_Bubble *ovl = overlay->ovl;
+             lon = ovl->lon;
+             lat = ovl->lat;
+          }
+        else
+          {
+             WRN("Not supported overlay type: %d", overlay->type);
+             continue;
+          }
+        if (lon> max_lon) max_lon = lon;
+        if (lon< min_lon) min_lon = lon;
+        if (lat > max_lat) max_lat = lat;
+        if (lat < min_lat) min_lat = lat;
+     }
+   if (max_longitude) *max_longitude = max_lon;
+   if (min_longitude) *min_longitude = min_lon;
+   if (max_latitude) *max_latitude = max_lat;
+   if (min_latitude) *min_latitude = min_lat;
+}
+
+static Evas_Object *
+_icon_dup(Evas_Object *icon, Evas_Object *parent)
+{
+   if (!icon || !parent) return NULL;
+   // Evas_Object do not support object duplication??
+   const char *file = NULL, *group = NULL;
+   Eina_Bool scale_up, scale_down;
+
+   Evas_Object *dup = elm_icon_add(parent);
+   elm_icon_file_get(icon, &file, &group);
+   elm_icon_file_set(dup, file, group);
+   elm_icon_animated_set(dup, elm_icon_animated_get(icon));
+   elm_icon_animated_play_set(dup, elm_icon_animated_play_get(icon));
+   elm_icon_standard_set(dup, elm_icon_standard_get(icon));
+   elm_icon_order_lookup_set(dup, elm_icon_order_lookup_get(icon));
+   elm_icon_no_scale_set(dup, elm_icon_no_scale_get(icon));
+   elm_icon_scale_get(icon, &scale_up, &scale_down);
+   elm_icon_scale_set(dup, scale_up, scale_down);
+   elm_icon_fill_outside_set(dup, elm_icon_fill_outside_get(icon));
+   elm_icon_prescale_set(dup, elm_icon_prescale_get(icon));
+   elm_icon_aspect_fixed_set(dup, elm_icon_aspect_fixed_get(icon));
+   return dup;
+}
+
+static Evas_Object *
+_overlay_layout_new(Widget_Data *wd, const char *group)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL);
+   Evas_Object *obj = elm_layout_add(wd->obj);
+   evas_object_smart_member_add(obj, wd->pan_smart);
+   evas_object_stack_above(obj, wd->sep_maps_markers);
+   elm_layout_theme_set(obj, "map/marker", group,  elm_widget_style_get(wd->obj));
+   return obj;
 }
 
 static void
-_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+_overlay_layout_update(Widget_Data *wd, Evas_Object *layout, Evas_Object *icon, const char *text, const char *group)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
-   if (x) *x = sd->wd->pan_x;
-   if (y) *y = sd->wd->pan_y;
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(layout);
+
+   Evas_Object *prev_icon = elm_object_part_content_get(layout, "elm.icon");
+   if (icon && (prev_icon != icon))
+     {
+        elm_layout_theme_set(layout, "map/marker", "empty",
+                             elm_widget_style_get(wd->obj));
+        elm_object_part_content_set(layout, "elm.icon", icon);
+     }
+   else if (text)
+     {
+        if (group) elm_layout_theme_set(layout, "map/marker", group,
+                                        elm_widget_style_get(wd->obj));
+        edje_object_part_text_set(elm_layout_edje_get(layout), "elm.text", text);
+     }
 }
 
 static void
-_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+_overlay_clicked_cb(void *data, Evas *e __UNUSED__,  Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
-   Evas_Coord ow, oh;
-   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
-   ow = sd->wd->size.w - ow;
-   oh = sd->wd->size.h - oh;
-   if (ow < 0) ow = 0;
-   if (oh < 0) oh = 0;
-   if (x) *x = ow;
-   if (y) *y = oh;
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Elm_Map_Overlay *overlay = data;
+
+   evas_object_smart_callback_call(overlay->wd->obj, SIG_OVERLAY_CLICKED,
+                                   overlay);
+   if (overlay->cb) overlay->cb(overlay->cb_data, overlay->wd->obj,
+                                overlay);
 }
 
 static void
-_pan_min_get(Evas_Object *obj __UNUSED__, Evas_Coord *x, Evas_Coord *y)
+_overlay_default_cb_add(Overlay_Default *ovl, Evas_Object_Event_Cb cb, void *data)
 {
-   if (x) *x = 0;
-   if (y) *y = 0;
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   EINA_SAFETY_ON_NULL_RETURN(data);
+
+   // FIXME: Add icon or object event callback
+   evas_object_event_callback_add(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb,
+                                  data);
 }
 
 static void
-_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+_overlay_default_cb_del(Overlay_Default *ovl, Evas_Object_Event_Cb cb)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
-   if (w) *w = sd->wd->size.w;
-   if (h) *h = sd->wd->size.h;
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   // FIXME: Add icon or object event callback
+   evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb);
 }
 
 static void
-_pan_add(Evas_Object *obj)
+_overlay_default_hide(Overlay_Default *ovl)
 {
-   Pan *sd;
-   Evas_Object_Smart_Clipped_Data *cd;
-   parent_sc.add(obj);
-   cd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(cd);
-   sd = ELM_NEW(Pan);
-   sd->__clipped_data = *cd;
-   free(cd);
-   evas_object_smart_data_set(obj, sd);
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   if (ovl->obj) evas_object_hide(ovl->obj);
+   if (ovl->layout) evas_object_hide(ovl->layout);
 }
 
 static void
-_pan_resize(Evas_Object *obj, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
+_overlay_default_show(Widget_Data *wd, Overlay_Default *ovl)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
+   Evas_Object *disp;
+   Evas_Coord px, py;
+   Evas_Coord x, y, w, h;
 
-   _sizing_eval(sd->wd);
-   elm_map_zoom_mode_set(sd->wd->obj, sd->wd->mode);
-   evas_object_smart_changed(obj);
+   if (ovl->obj)
+     {
+        disp = ovl->obj;
+        evas_object_geometry_get(disp, NULL, NULL, &w, &h);
+        if (w <= 0 || h <= 0) evas_object_size_hint_min_get(disp, &w, &h);
+     }
+   else
+     {
+        disp = ovl->layout;
+        w = ovl->w;
+        h = ovl->h;
+     }
+
+   _pan_geometry_get(wd, &px, &py);
+   _coord_rotate(ovl->x + px, ovl->y + py, wd->rotate.cx,  wd->rotate.cy,
+                 wd->rotate.d, &x, &y);
+   _obj_place(disp, x - (w / 2), y - (h / 2), w, h);
 }
 
 static void
-_pan_calculate(Evas_Object *obj)
+_overlay_default_update(Widget_Data *wd, Overlay_Default *ovl, Evas_Object *obj, Evas_Object *icon, Overlay_Class *ovl_clas, const char *text, const char *group)
 {
-   Pan *sd = evas_object_smart_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(sd);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
 
-   Evas_Coord w, h;
-   evas_object_geometry_get(sd->wd->pan_smart, NULL, NULL, &w, &h);
-   if (w <= 0 || h <= 0) return;
+   elm_map_utils_convert_geo_into_coord(wd->obj, ovl->lon, ovl->lat,
+                                        wd->size.w, &ovl->x, &ovl->y);
 
-   _grid_place(sd->wd);
-   _marker_place(sd->wd);
-   _route_place(sd->wd);
-   _track_place(sd->wd);
-   _delayed_do(sd->wd);
+   if (obj)
+     {
+        if (ovl->obj == obj) return;
+        if (ovl->obj) evas_object_del(ovl->obj);
+        ovl->obj = obj;
+     }
+   else if (!(ovl->obj) && icon)
+     {
+        if (ovl->icon == icon) return;
+        if (ovl->icon) evas_object_del(ovl->icon);
+        ovl->icon = icon;
+       _overlay_layout_update(wd, ovl->layout, ovl->icon, NULL, NULL);
+
+     }
+   else if (!(ovl->obj) && !(ovl->icon) && (ovl_clas) &&
+            ((ovl_clas->obj) || (ovl_clas->icon)))
+     {
+        // Inherit icon from group overlay's ojbect or icon
+
+        // FIXME: It is hard to duplicate evas object :-)
+        /*
+        if (ovl_clas->obj && (ovl_clas->obj != ovl->clas_obj_ref))
+          {
+             if (ovl->clas_obj) evas_object_del(ovl->clas_obj);
+             ovl->clas_obj_ref = ovl_clas->obj;
+             ovl->clas_obj = _obj_dup(ovl->clas_obj_ref, ovl->layout);
+             _overlay_layout_update(wd, ovl->layout, ovl->clas_obj, NULL, NULL);
+          }
+        */
+        if (ovl_clas->icon && (ovl_clas->icon != ovl->clas_icon_ref))
+          {
+             if (ovl->clas_icon) evas_object_del(ovl->clas_icon);
+             ovl->clas_icon_ref = ovl_clas->icon;
+             ovl->clas_icon = _icon_dup(ovl->clas_icon_ref, ovl->layout);
+             _overlay_layout_update(wd, ovl->layout, ovl->clas_icon, NULL, NULL);
+        }
+     }
+   else if (!(ovl->obj) && !(ovl->icon) && !(ovl->clas_icon) && text)
+     {
+        _overlay_layout_update(wd, ovl->layout, NULL, text, group);
+     }
 }
 
 static void
-_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+_overlay_default_free(Overlay_Default *ovl)
 {
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   evas_object_smart_changed(obj);
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   if (ovl->obj) evas_object_del(ovl->obj);
+   if (ovl->icon) evas_object_del(ovl->icon);
+   if (ovl->clas_icon) evas_object_del(ovl->clas_icon);
+   evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _overlay_clicked_cb);
+   if (ovl->layout) evas_object_del(ovl->layout);
+   free(ovl);
 }
 
-static void
-_hold_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+static Overlay_Default *
+_overlay_default_new(Widget_Data *wd, double lon, double lat, const char *group)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Widget_Data *wd = data;
-   elm_smart_scroller_hold_set(wd->scr, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL);
+
+   Overlay_Default *ovl = ELM_NEW(Overlay_Default);
+   _edj_marker_size_get(wd, &(ovl->w), &(ovl->h));
+   ovl->layout = _overlay_layout_new(wd, group);
+   ovl->lon = lon;
+   ovl->lat = lat;
+   return ovl;
 }
 
 static void
-_hold_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+_overlay_group_clicked_cb(void *data, Evas *e __UNUSED__,  Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
 {
    EINA_SAFETY_ON_NULL_RETURN(data);
-   Widget_Data *wd = data;
-   elm_smart_scroller_hold_set(wd->scr, 0);
+   Overlay_Group *ovl = data;
+
+   evas_object_smart_callback_call(ovl->clas->wd->obj, SIG_OVERLAY_CLICKED,
+                                   ovl->clas);
+   if (ovl->clas->cb) ovl->clas->cb(ovl->clas->cb_data, ovl->clas->wd->obj,
+                                    ovl->clas);
 }
 
 static void
-_freeze_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+_overlay_group_cb_add(Overlay_Group *ovl)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Widget_Data *wd = data;
-   elm_smart_scroller_freeze_set(wd->scr, 1);
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   _overlay_default_cb_add(ovl->ovl, _overlay_group_clicked_cb, ovl);
 }
 
 static void
-_freeze_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+_overlay_group_cb_del(Overlay_Group *ovl)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Widget_Data *wd = data;
-   elm_smart_scroller_freeze_set(wd->scr, 0);
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   _overlay_default_cb_del(ovl->ovl, _overlay_group_clicked_cb);
 }
 
 static void
-_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+_overlay_group_update(Widget_Data *wd, Overlay_Group *grp, Eina_List *members)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(grp);
 
-   if (elm_widget_focus_get(obj))
+   Eina_List *l;
+   Elm_Map_Overlay *overlay;
+   Evas_Coord sum_x = 0, sum_y = 0, cnt = 0;
+
+   if (grp->members) eina_list_free(grp->members);
+   grp->members = members;
+
+   if (!grp->members || eina_list_count(grp->members) <= 0)
      {
-        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,focus", "elm");
-        evas_object_focus_set(wd->obj, EINA_TRUE);
+        _overlay_default_hide(grp->ovl);
+        return;
      }
-   else
+   EINA_LIST_FOREACH(grp->members, l, overlay)
      {
-        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,unfocus", "elm");
-        evas_object_focus_set(wd->obj, EINA_FALSE);
+        Overlay_Default *df = overlay->ovl;
+        sum_x += df->x;
+        sum_y += df->y;
+        cnt++;
      }
+
+   Overlay_Class *ovl_clas = grp->clas->ovl;
+
+   char text[128];
+   snprintf(text, sizeof(text), "%d", cnt);
+   _overlay_default_update(wd, grp->ovl, NULL, NULL, ovl_clas, text, "radio2");
+
+   grp->ovl->x = sum_x / cnt;
+   grp->ovl->y = sum_y / cnt;
 }
 
 static void
-_del_hook(Evas_Object *obj)
+_overlay_group_free(Overlay_Group *grp, Elm_Map_Overlay *club_owner)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(grp);
 
-   Eina_List *l, *ll;
-   Evas_Object *p;
-   Path_Node *n;
-   Path_Waypoint *w;
-   Ecore_Event_Handler *h;
-   Elm_Map_Route *r;
-   Elm_Map_Name *na;
-   Evas_Object *route;
-   Elm_Map_Marker *marker;
-   Elm_Map_Group_Class *group_clas;
-   Elm_Map_Marker_Class *clas;
-   Delayed_Data *dd;
-   int idx = 0;
-   Map_Sources_Tab *s;
+   _overlay_default_cb_del(grp->ovl, _overlay_group_clicked_cb);
+   _overlay_default_free(grp->ovl);
+   if (grp->clas) elm_map_overlay_class_remove(grp->clas, club_owner);
+   if (grp->members) eina_list_free(grp->members);
+   free(grp);
+}
 
-   EINA_LIST_FOREACH(wd->route, l, r)
-     {
-        EINA_LIST_FREE(r->path, p)
-          {
-             evas_object_del(p);
-          }
+static Overlay_Group *
+_overlay_group_new(Widget_Data *wd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-        EINA_LIST_FREE(r->waypoint, w)
-          {
-             if (w->point) eina_stringshare_del(w->point);
-             free(w);
-          }
+   Overlay_Group *grp = ELM_NEW(Overlay_Group);
+   grp->ovl = ELM_NEW(Overlay_Default);
+   grp->ovl = _overlay_default_new(wd, -1, -1, "radio2");
+   grp->ovl->w *= 2;
+   grp->ovl->h *= 2;
+   return grp;
+}
 
-        EINA_LIST_FREE(r->nodes, n)
-          {
-             if (n->pos.address) eina_stringshare_del(n->pos.address);
-             free(n);
-          }
+static void
+_overlay_class_update(Widget_Data *wd, Overlay_Class *clas, Evas_Object *obj, Evas_Object *icon)
+{
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(clas);
 
-        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);
-     }
-
-   EINA_LIST_FREE(wd->names, na)
+   if (obj && (clas->obj != obj))
      {
-        if (na->address) free(na->address);
-        if (na->handler) ecore_event_handler_del(na->handler);
-        if (na->ud.fname)
-          {
-             ecore_file_remove(na->ud.fname);
-             free(na->ud.fname);
-             na->ud.fname = NULL;
-          }
+        if (clas->obj) evas_object_del(clas->obj);
+        clas->obj = icon;
      }
-
-   EINA_LIST_FREE(wd->track, route)
+   else if (icon && (clas->icon != icon))
      {
-        evas_object_del(route);
+        if (clas->icon) evas_object_del(clas->icon);
+        clas->icon = icon;
      }
+}
 
+static void
+_overlay_class_free(Overlay_Class *clas)
+{
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   if (clas->icon) evas_object_del(clas->icon);
+   if (clas->members) eina_list_free(clas->members);
+   free(clas);
+}
 
-   EINA_LIST_FOREACH_SAFE(wd->markers, l, ll, marker)
-      elm_map_marker_remove(marker);
-   eina_list_free(wd->markers);
-
-   EINA_LIST_FREE(wd->group_classes, group_clas)
-     {
-        eina_list_free(group_clas->markers);
-        if (group_clas->style) eina_stringshare_del(group_clas->style);
-        free(group_clas);
-     }
-
-   EINA_LIST_FREE(wd->marker_classes, clas)
-     {
-        if (clas->style) eina_stringshare_del(clas->style);
-        free(clas);
-     }
+static Overlay_Class *
+_overlay_class_new(Widget_Data *wd, Elm_Map_Overlay *clas)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   Overlay_Class *ovl = ELM_NEW(Overlay_Class);
+   ovl->clas = clas;
+   ovl->icon = NULL;
+   ovl->zoom_max = OVERLAY_CLASS_ZOOM_MAX;
+   return ovl;
+}
 
-   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
-   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+static void
+_overlay_bubble_cb_add(Overlay_Bubble *ovl, Elm_Map_Overlay *overlay)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   evas_object_event_callback_add(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _overlay_clicked_cb, overlay);
+}
 
-   if (wd->delayed_jobs) EINA_LIST_FREE(wd->delayed_jobs, dd) free(dd);
+static void
+_overlay_bubble_cb_del(Overlay_Bubble *ovl)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ovl);
+   evas_object_event_callback_del(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _overlay_clicked_cb);
+}
 
-   if (wd->user_agent) eina_stringshare_del(wd->user_agent);
-   if (wd->ua) eina_hash_free(wd->ua);
-   if (wd->download_idler) ecore_idler_del(wd->download_idler);
-   eina_list_free(wd->download_list);
+static void
+_overlay_bubble_hide(Overlay_Bubble *bubble)
+{
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   if (bubble->obj) evas_object_hide(bubble->obj);
+}
 
-   if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
-   if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
+static void
+_overlay_bubble_update(Overlay_Bubble *bubble)
+{
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   if ((!bubble->pobj) && (bubble->lon >= 0) && (bubble->lat >= 0))
+     {
+        elm_map_utils_convert_geo_into_coord(bubble->wd->obj, bubble->lon,
+                                             bubble->lat, bubble->wd->size.w,
+                                             &bubble->x, &bubble->y);
+     }
+}
 
-   _grid_all_clear(wd);
+static void
+_overlay_bubble_show(Overlay_Bubble *bubble)
+{
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   Evas_Coord x, y;
 
-   for (idx = 0; wd->src_names[idx]; idx++)
-      eina_stringshare_del(wd->src_names[idx]);
+   if ((bubble->x < 0) || (bubble->y < 0)) return;
+   Evas_Coord px, py;
+   _pan_geometry_get(bubble->wd, &px, &py);
+   _coord_rotate(bubble->x + px, bubble->y + py, bubble->wd->rotate.cx,
+                 bubble->wd->rotate.cy, bubble->wd->rotate.d, &x, &y);
+   x = x - (bubble->w / 2);
+   y = y - (bubble->h / 2);
+   _obj_place(bubble->obj, x, y, bubble->w, bubble->h);
+   //evas_object_raise(bubble->obj);
+}
 
-   EINA_LIST_FREE(wd->srcs, s) free(s);
+static void
+_overlay_bubble_chase(Overlay_Bubble *bubble)
+{
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   EINA_SAFETY_ON_NULL_RETURN(bubble->pobj);
 
-   if (wd->map) evas_map_free(wd->map);
+   Evas_Coord x, y, w;
+   evas_object_geometry_get(bubble->pobj, &x, &y, &w, NULL);
+   x = x + (w / 2) - (bubble->w / 2);
+   y = y - bubble->h;
+   _obj_place(bubble->obj, x, y, bubble->w, bubble->h);
+   evas_object_raise(bubble->obj);
+}
 
-   free(wd);
+static void
+_overlay_bubble_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   _overlay_bubble_hide(data);
 }
 
 static void
-_del_pre_hook(Evas_Object *obj)
+_overlay_bubble_chase_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   _overlay_bubble_chase(data);
 }
 
 static void
-_theme_hook(Evas_Object *obj)
+_overlay_bubble_free(Overlay_Bubble* bubble)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
 
-   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
-   _sizing_eval(wd);
+   evas_object_del(bubble->bx);
+   evas_object_del(bubble->sc);
+   evas_object_del(bubble->obj);
+   if (bubble->pobj)
+     {
+        evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_HIDE,
+                                            _overlay_bubble_hide_cb, bubble);
+        evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_SHOW,
+                                            _overlay_bubble_chase_cb, bubble);
+        evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_MOVE,
+                                            _overlay_bubble_chase_cb, bubble);
+     }
+   free(bubble);
 }
 
-static Eina_Bool
-_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
+static Overlay_Bubble*
+_overlay_bubble_new(Widget_Data *wd)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   Evas_Coord x, y;
-   Evas_Coord vh;
-   Evas_Coord step_x, step_y, page_x, page_y;
+   Evas_Coord h;
+   const char *s;
+   Overlay_Bubble *bubble = ELM_NEW(Overlay_Bubble);
+   bubble->wd = wd;
 
-   if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
-   Evas_Event_Key_Down *ev = event_info;
-   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
+   bubble->obj = edje_object_add(evas_object_evas_get(wd->obj));
+   _elm_theme_object_set(wd->obj, bubble->obj , "map", "marker_bubble",
+                         elm_widget_style_get(wd->obj));
+   evas_object_event_callback_add(bubble->obj, EVAS_CALLBACK_MOUSE_UP,
+                                  _overlay_bubble_chase_cb, bubble);
 
-   elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
-   elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
-   elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
-   _viewport_size_get(wd, NULL, &vh);
+   bubble->sc = elm_scroller_add(bubble->obj);
+   elm_widget_style_set(bubble->sc, "map_bubble");
+   elm_scroller_content_min_limit(bubble->sc, EINA_FALSE, EINA_TRUE);
+   elm_scroller_policy_set(bubble->sc, ELM_SCROLLER_POLICY_AUTO,
+                           ELM_SCROLLER_POLICY_OFF);
+   elm_scroller_bounce_set(bubble->sc, _elm_config->thumbscroll_bounce_enable,
+                           EINA_FALSE);
+   edje_object_part_swallow(bubble->obj, "elm.swallow.content", bubble->sc);
 
-   if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
+   bubble->bx = elm_box_add(bubble->sc);
+   evas_object_size_hint_align_set(bubble->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bubble->bx, EVAS_HINT_EXPAND,
+                                    EVAS_HINT_EXPAND);
+   elm_box_horizontal_set(bubble->bx, EINA_TRUE);
+   elm_object_content_set(bubble->sc, bubble->bx);
+
+   s = edje_object_data_get(bubble->obj, "size_w");
+   if (s) bubble->w = atoi(s);
+   else bubble->w = 0;
+
+   edje_object_size_min_calc(bubble->obj, NULL, &(bubble->h));
+   s = edje_object_data_get(bubble->obj, "size_h");
+   if (s) h = atoi(s);
+   else h = 0;
+   if (bubble->h < h) bubble->h = h;
+
+   bubble->lon = -1;
+   bubble->lat = -1;
+   bubble->x = -1;
+   bubble->y = -1;
+   return bubble;
+}
+
+static void
+_overlay_grouping(Eina_List *members, Elm_Map_Overlay *overlay)
+{
+   EINA_SAFETY_ON_NULL_RETURN(members);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   // Currently support only basic overlay type
+   EINA_SAFETY_ON_FALSE_RETURN(overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT);
+
+   Eina_List *l;
+   Elm_Map_Overlay *overlay_memb;
+   Eina_List *club_members = NULL;
+
+   // Grouping only supports overlay default
+   Overlay_Default *ovl = (Overlay_Default *)overlay->ovl;
+   EINA_LIST_FOREACH(members, l, overlay_memb)
      {
-        x -= step_x;
+        Overlay_Default *ovl_memb = overlay_memb->ovl;
+        if ((overlay_memb->hide) ||
+            (overlay_memb->zoom_min > overlay_memb->wd->zoom)) continue;
+        if (overlay == overlay_memb || overlay_memb->grp_in) continue;
+        if (ELM_RECTS_INTERSECT(ovl_memb->x, ovl_memb->y, ovl_memb->w,
+                                ovl_memb->h, ovl->x, ovl->y,
+                                ovl->w * OVERLAY_GROUPING_SCALE,
+                                ovl->h * OVERLAY_GROUPING_SCALE))
+          {
+             // Join group.
+             overlay_memb->grp_boss = EINA_FALSE;
+             overlay_memb->grp_in = EINA_TRUE;
+             club_members = eina_list_append(club_members, overlay_memb);
+             _overlay_group_update(overlay_memb->wd, overlay_memb->grp, NULL);
+             _overlay_group_cb_del(overlay_memb->grp);
+          }
      }
-   else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
+
+   if (eina_list_count(club_members) >= 1)
      {
-        x += step_x;
+        // Mark as boss
+        overlay->grp_boss = EINA_TRUE;
+        overlay->grp_in = EINA_TRUE;
+        club_members = eina_list_append(club_members, overlay);
+        _overlay_group_update(overlay->wd, overlay->grp, club_members);
+        _overlay_group_cb_del(overlay->grp);
+        _overlay_group_cb_add(overlay->grp);
      }
-   else if ((!strcmp(ev->keyname, "Up"))  || (!strcmp(ev->keyname, "KP_Up")))
+}
+
+static void
+_overlay_display(Widget_Data *wd, Elm_Map_Overlay *overlay)
+{
+   Eina_Bool hide = EINA_FALSE;
+
+   if ((overlay->grp_in) || (overlay->hide) || (overlay->zoom_min > wd->zoom))
+      hide = EINA_TRUE;
+   if ((overlay->grp->clas) && ((overlay->grp->clas->hide) ||
+                                (overlay->grp->clas->zoom_min > wd->zoom)))
+      hide = EINA_TRUE;
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        y -= step_y;
+        if (hide) _overlay_default_hide(overlay->ovl);
+        else _overlay_default_show(wd, overlay->ovl);
      }
-   else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
      {
-        y += step_y;
+        if (hide) _overlay_bubble_hide(overlay->ovl);
+        else _overlay_bubble_show(overlay->ovl);
      }
-   else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
+}
+
+static void
+_overlay_place(Widget_Data *wd)
+{
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   Eina_List *l, *ll;
+   Elm_Map_Overlay *overlay, *grp;
+
+   if (eina_list_count(wd->overlays) == 0) return;
+
+   // Reset overlays coord & grp except class type
+   EINA_LIST_FOREACH(wd->overlays, l, overlay)
      {
-        if (page_y < 0)
-          y -= -(page_y * vh) / 100;
-        else
-          y -= page_y;
+
+        if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) continue;
+        if (overlay->paused) continue;
+        if ((overlay->grp) && (overlay->grp->clas) &&
+            (overlay->grp->clas->paused)) continue;
+        if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+          {
+             Overlay_Class *ovl_grp = NULL;
+             if (overlay->grp->clas) ovl_grp = overlay->grp->clas->ovl;
+             _overlay_default_update(wd, overlay->ovl, NULL, NULL, ovl_grp, NULL,
+                                     NULL);
+           }
+        else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
+           _overlay_bubble_update(overlay->ovl);
+        // Reset grp flags
+        overlay->grp_in = EINA_FALSE;
+        overlay->grp_boss = EINA_FALSE;
+        _overlay_group_update(wd, overlay->grp, NULL);
      }
-   else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
+
+   // Classify into group idol or follwer
+   EINA_LIST_FOREACH(wd->overlays, l, grp)
      {
-        if (page_y < 0)
-          y += -(page_y * vh) / 100;
-        else
-          y += page_y;
+        Elm_Map_Overlay *idol;
+        Overlay_Class *ovl;
+
+        if (grp->type != ELM_MAP_OVERLAY_TYPE_CLASS) continue;
+        if ((grp->hide) || (grp->zoom_min > wd->zoom)) continue;
+
+        ovl = grp->ovl;
+        if (ovl->zoom_max < wd->zoom) continue;
+        EINA_LIST_FOREACH(ovl->members, ll, idol)
+          {
+             if (!idol->grp_in) _overlay_grouping(ovl->members, idol);
+          }
      }
-   else if (!strcmp(ev->keyname, "KP_Add"))
+
+   // Place overlays
+   EINA_LIST_FOREACH(wd->overlays, l, overlay)
+      if (overlay->type != ELM_MAP_OVERLAY_TYPE_CLASS)
+         _overlay_display(wd, overlay);
+
+   // Place group overlays
+   EINA_LIST_FOREACH(wd->overlays, l, overlay)
      {
-        zoom_with_animation(wd, wd->zoom + 1, 10);
-        return EINA_TRUE;
+        if (overlay->grp_boss) _overlay_default_show(wd, overlay->grp->ovl);
      }
-   else if (!strcmp(ev->keyname, "KP_Subtract"))
+}
+
+static Evas_Object *
+_overlay_obj_get(Elm_Map_Overlay *overlay)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        zoom_with_animation(wd, wd->zoom - 1, 10);
-        return EINA_TRUE;
+        Overlay_Default *ovl = overlay->ovl;
+        return ovl->layout;
+     }
+   else
+     {
+        ERR("Not supported overlay type: %d", overlay->type);
+        return NULL;
      }
-   else return EINA_FALSE;
-
-   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
-   elm_smart_scroller_child_pos_set(wd->scr, x, y);
-
-   return EINA_TRUE;
 }
 
-static Eina_Bool
-cb_dump_name_attrs(void *data, const char *key, const char *value)
+static void
+_overlays_show(void *data)
 {
-   Name_Dump *dump = (Name_Dump*)data;
-   if (!dump) return EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
 
-   if (!strncmp(key, NOMINATIM_ATTR_LON, sizeof(NOMINATIM_ATTR_LON))) dump->lon = atof(value);
-   else if (!strncmp(key, NOMINATIM_ATTR_LAT, sizeof(NOMINATIM_ATTR_LAT))) dump->lat = atof(value);
+   int zoom;
+   double max_lon, min_lon, max_lat, min_lat;
+   Evas_Coord vw, vh;
 
-   return EINA_TRUE;
+   _region_max_min_get(dd->overlays, &max_lon, &min_lon, &max_lat, &min_lat);
+   dd->lon = (max_lon + min_lon) / 2;
+   dd->lat = (max_lat + min_lat) / 2;
+
+   zoom = dd->wd->src->zoom_min;
+   _viewport_size_get(dd->wd, &vw, &vh);
+   while (zoom <= dd->wd->src->zoom_max)
+     {
+        Evas_Coord size, max_x, max_y, min_x, min_y;
+        size = pow(2.0, zoom) * dd->wd->tsize;
+        elm_map_utils_convert_geo_into_coord(dd->wd->obj, min_lon, max_lat,
+                                             size, &min_x, &max_y);
+        elm_map_utils_convert_geo_into_coord(dd->wd->obj, max_lon, min_lat,
+                                             size, &max_x, &min_y);
+        if ((max_x - min_x) > vw || (max_y - min_y) > vh) break;
+        zoom++;
+     }
+   zoom--;
+
+   zoom_do(dd->wd, zoom);
+   _region_show(dd);
+   evas_object_smart_changed(dd->wd->pan_smart);
 }
 
-static Eina_Bool
-cb_route_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
 {
-   Route_Dump *dump = data;
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+
+   sd->wd->pan_x = x;
+   sd->wd->pan_y = y;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+   if (x) *x = sd->wd->pan_x;
+   if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+   Evas_Coord ow, oh;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   ow = sd->wd->size.w - ow;
+   oh = sd->wd->size.h - oh;
+   if (ow < 0) ow = 0;
+   if (oh < 0) oh = 0;
+   if (x) *x = ow;
+   if (y) *y = oh;
+}
+
+static void
+_pan_min_get(Evas_Object *obj __UNUSED__, Evas_Coord *x, Evas_Coord *y)
+{
+   if (x) *x = 0;
+   if (y) *y = 0;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+   if (w) *w = sd->wd->size.w;
+   if (h) *h = sd->wd->size.h;
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+   Pan *sd;
+   Evas_Object_Smart_Clipped_Data *cd;
+   parent_sc.add(obj);
+   cd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(cd);
+   sd = ELM_NEW(Pan);
+   sd->__clipped_data = *cd;
+   free(cd);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+
+   _sizing_eval(sd->wd);
+   elm_map_zoom_mode_set(sd->wd->obj, sd->wd->mode);
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(sd);
+
+   Evas_Coord w, h;
+   evas_object_geometry_get(sd->wd->pan_smart, NULL, NULL, &w, &h);
+   if (w <= 0 || h <= 0) return;
+
+   _grid_place(sd->wd);
+   _marker_place(sd->wd);
+   _overlay_place(sd->wd);
+   _route_place(sd->wd);
+   _track_place(sd->wd);
+   _delayed_do(sd->wd);
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   evas_object_smart_changed(obj);
+}
+
+static void
+_hold_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Widget_Data *wd = data;
+   elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Widget_Data *wd = data;
+   elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Widget_Data *wd = data;
+   elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Widget_Data *wd = data;
+   elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   if (elm_widget_focus_get(obj))
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,focus", "elm");
+        evas_object_focus_set(wd->obj, EINA_TRUE);
+     }
+   else
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,unfocus", "elm");
+        evas_object_focus_set(wd->obj, EINA_FALSE);
+     }
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   Eina_List *l, *ll;
+   Evas_Object *p;
+   Path_Node *n;
+   Path_Waypoint *w;
+   Ecore_Event_Handler *h;
+   Elm_Map_Route *r;
+   Elm_Map_Name *na;
+   Evas_Object *route;
+   Elm_Map_Marker *marker;
+   Elm_Map_Group_Class *group_clas;
+   Elm_Map_Marker_Class *clas;
+   Elm_Map_Overlay *overlay;
+   Delayed_Data *dd;
+   int idx = 0;
+   Map_Sources_Tab *s;
+
+   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);
+     }
+
+   EINA_LIST_FREE(wd->names, na)
+     {
+        if (na->address) free(na->address);
+        if (na->handler) ecore_event_handler_del(na->handler);
+        if (na->ud.fname)
+          {
+             ecore_file_remove(na->ud.fname);
+             free(na->ud.fname);
+             na->ud.fname = NULL;
+          }
+     }
+
+   EINA_LIST_FREE(wd->track, route)
+     {
+        evas_object_del(route);
+     }
+
+
+   EINA_LIST_FOREACH_SAFE(wd->markers, l, ll, marker)
+      elm_map_marker_remove(marker);
+   eina_list_free(wd->markers);
+
+   EINA_LIST_FREE(wd->group_classes, group_clas)
+     {
+        eina_list_free(group_clas->markers);
+        if (group_clas->style) eina_stringshare_del(group_clas->style);
+        free(group_clas);
+     }
+
+   EINA_LIST_FREE(wd->marker_classes, clas)
+     {
+        if (clas->style) eina_stringshare_del(clas->style);
+        free(clas);
+     }
+
+   EINA_LIST_FREE(wd->overlays, overlay) elm_map_overlay_del(overlay);
+
+   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
+   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+
+   if (wd->delayed_jobs) EINA_LIST_FREE(wd->delayed_jobs, dd) free(dd);
+
+   if (wd->user_agent) eina_stringshare_del(wd->user_agent);
+   if (wd->ua) eina_hash_free(wd->ua);
+   if (wd->download_idler) ecore_idler_del(wd->download_idler);
+   eina_list_free(wd->download_list);
+
+   if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
+   if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
+
+   _grid_all_clear(wd);
+
+   for (idx = 0; wd->src_names[idx]; idx++)
+      eina_stringshare_del(wd->src_names[idx]);
+
+   EINA_LIST_FREE(wd->srcs, s) free(s);
+
+   if (wd->map) evas_map_free(wd->map);
+
+   free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
+   _sizing_eval(wd);
+}
+
+static Eina_Bool
+_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+
+   Evas_Coord x, y;
+   Evas_Coord vh;
+   Evas_Coord step_x, step_y, page_x, page_y;
+
+   if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
+   Evas_Event_Key_Down *ev = event_info;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
+
+   elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
+   elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
+   elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
+   _viewport_size_get(wd, NULL, &vh);
+
+   if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
+     {
+        x -= step_x;
+     }
+   else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
+     {
+        x += step_x;
+     }
+   else if ((!strcmp(ev->keyname, "Up"))  || (!strcmp(ev->keyname, "KP_Up")))
+     {
+        y -= step_y;
+     }
+   else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
+     {
+        y += step_y;
+     }
+   else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
+     {
+        if (page_y < 0)
+          y -= -(page_y * vh) / 100;
+        else
+          y -= page_y;
+     }
+   else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
+     {
+        if (page_y < 0)
+          y += -(page_y * vh) / 100;
+        else
+          y += page_y;
+     }
+   else if (!strcmp(ev->keyname, "KP_Add"))
+     {
+        zoom_with_animation(wd, wd->zoom + 1, 10);
+        return EINA_TRUE;
+     }
+   else if (!strcmp(ev->keyname, "KP_Subtract"))
+     {
+        zoom_with_animation(wd, wd->zoom - 1, 10);
+        return EINA_TRUE;
+     }
+   else return EINA_FALSE;
+
+   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+   elm_smart_scroller_child_pos_set(wd->scr, x, y);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+cb_dump_name_attrs(void *data, const char *key, const char *value)
+{
+   Name_Dump *dump = (Name_Dump*)data;
+   if (!dump) return EINA_FALSE;
+
+   if (!strncmp(key, NOMINATIM_ATTR_LON, sizeof(NOMINATIM_ATTR_LON))) dump->lon = atof(value);
+   else if (!strncmp(key, NOMINATIM_ATTR_LAT, sizeof(NOMINATIM_ATTR_LAT))) dump->lat = atof(value);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+cb_route_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+{
+   Route_Dump *dump = data;
+   if (!dump) return EINA_FALSE;
+
+   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;
+             }
+         }
+        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;
+      default:
+        break;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+cb_name_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+{
+   Name_Dump *dump = data;
    if (!dump) return EINA_FALSE;
 
-   switch (type)
-     {
-      case EINA_SIMPLE_XML_OPEN:
-      case EINA_SIMPLE_XML_OPEN_EMPTY:
-        {
-           const char *attrs;
+   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, NOMINATIM_RESULT, sizeof(NOMINATIM_RESULT) - 1)) dump->id = NAME_XML_NAME;
+                else dump->id = NAME_XML_NONE;
+
+                eina_simple_xml_attributes_parse
+                  (attrs, length - (attrs - value), cb_dump_name_attrs, dump);
+             }
+        }
+        break;
+      case EINA_SIMPLE_XML_DATA:
+        {
+           char *buf = malloc(length + 1);
+           if (!buf) return EINA_FALSE;
+           snprintf(buf, length + 1, "%s", value);
+           if (dump->id == NAME_XML_NAME) dump->address = strdup(buf);
+           free(buf);
+        }
+        break;
+      default:
+        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_route_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++)
+               {
+                  Path_Waypoint *wp = ELM_NEW(Path_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);
+                  Path_Node *n = ELM_NEW(Path_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_polygon_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 void
+_parse_name(void *data)
+{
+   Elm_Map_Name *n = (Elm_Map_Name*)data;
+   if (!n || !n->ud.fname) return;
+
+   FILE *f;
+
+   Name_Dump dump = {0, NULL, 0.0, 0.0};
+
+   f = fopen(n->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_name_dump, &dump);
+                       free(buf);
+                    }
+               }
+          }
+        fclose(f);
+
+        if (dump.address)
+          {
+             INF("[%lf : %lf] ADDRESS : %s", n->lon, n->lat, dump.address);
+             n->address = strdup(dump.address);
+          }
+        n->lon = dump.lon;
+        n->lat = dump.lat;
+     }
+}
+
+Grid *_get_current_grid(Widget_Data *wd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   Eina_List *l;
+   Grid *g = NULL, *ret = NULL;
+   EINA_LIST_FOREACH(wd->grids, l, g)
+     {
+        if (wd->zoom == g->zoom)
+          {
+             ret = g;
+             break;
+          }
+     }
+   return ret;
+}
+
+static Eina_Bool
+_route_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);
+
+   _route_place(wd);
+
+   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 Eina_Bool
+_name_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Url_Complete *ev = event;
+   Elm_Map_Name *n = (Elm_Map_Name*)data;
+   Widget_Data *wd = n->wd;
+
+   if ((!n) || (!ev)) return EINA_TRUE;
+   Elm_Map_Name *nn = ecore_con_url_data_get(n->con_url);
+   ecore_con_url_data_set(n->con_url, NULL);
+   if (n!=nn) return EINA_TRUE;
+
+   if (n->ud.fd) fclose(n->ud.fd);
+   _parse_name(n);
+
+   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_NAME_LOADED, NULL);
+   return EINA_TRUE;
+}
+
+static Elm_Map_Name *
+_utils_convert_name(const Evas_Object *obj, int method, char *address, double lon, double lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char buf[PATH_MAX];
+   char *source;
+   int fd;
+
+   if ((!wd) || (!wd->src)) return NULL;
+   Elm_Map_Name *name = ELM_NEW(Elm_Map_Name);
+
+   snprintf(buf, sizeof(buf), DEST_NAME_XML_FILE);
+   fd = mkstemp(buf);
+   if (fd < 0)
+     {
+        free(name);
+        return NULL;
+     }
+
+   name->con_url = ecore_con_url_new(NULL);
+   name->ud.fname = strdup(buf);
+   INF("xml file : %s", name->ud.fname);
+
+   name->ud.fd = fdopen(fd, "w+");
+   if ((!name->con_url) || (!name->ud.fd))
+     {
+        ecore_con_url_free(name->con_url);
+        free(name);
+        return NULL;
+     }
+
+   name->wd = wd;
+   name->handler = ecore_event_handler_add (ECORE_CON_EVENT_URL_COMPLETE, _name_complete_cb, name);
+   name->method = method;
+   if (method == ELM_MAP_NAME_METHOD_SEARCH) name->address = strdup(address);
+   else if (method == ELM_MAP_NAME_METHOD_REVERSE) name->address = NULL;
+   name->lon = lon;
+   name->lat = lat;
+
+   source = wd->src->name_url_cb(wd->obj, method, address, lon, lat);
+   INF("name url = %s", source);
 
-           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;
-             }
-         }
-        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;
-      default:
-        break;
-     }
+   wd->names = eina_list_append(wd->names, name);
+   ecore_con_url_url_set(name->con_url, source);
+   ecore_con_url_fd_set(name->con_url, fileno(name->ud.fd));
+   ecore_con_url_data_set(name->con_url, name);
+
+   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_NAME_LOAD, NULL);
+   ecore_con_url_get(name->con_url);
+   if (source) free(source);
+
+   return name;
 
-   return EINA_TRUE;
 }
 
-static Eina_Bool
-cb_name_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+static Evas_Event_Flags
+_pinch_zoom_start_cb(void *data, void *event_info __UNUSED__)
 {
-   Name_Dump *dump = data;
-   if (!dump) return EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(data, EVAS_EVENT_FLAG_NONE);
+   Widget_Data *wd = 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, NOMINATIM_RESULT, sizeof(NOMINATIM_RESULT) - 1)) dump->id = NAME_XML_NAME;
-                else dump->id = NAME_XML_NONE;
+   wd->pinch_zoom = wd->zoom_detail;
+   return EVAS_EVENT_FLAG_NONE;
+}
 
-                eina_simple_xml_attributes_parse
-                  (attrs, length - (attrs - value), cb_dump_name_attrs, dump);
-             }
-        }
-        break;
-      case EINA_SIMPLE_XML_DATA:
-        {
-           char *buf = malloc(length + 1);
-           if (!buf) return EINA_FALSE;
-           snprintf(buf, length + 1, "%s", value);
-           if (dump->id == NAME_XML_NAME) dump->address = strdup(buf);
-           free(buf);
-        }
-        break;
-      default:
-        break;
+static Evas_Event_Flags
+_pinch_zoom_cb(void *data, void *event_info)
+{
+   Widget_Data *wd = data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
+
+   if (!wd->paused)
+     {
+        Elm_Gesture_Zoom_Info *ei = event_info;
+        zoom_do(wd, wd->pinch_zoom + ei->zoom - 1);
      }
+   return EVAS_EVENT_FLAG_NONE;
+}
 
-   return EINA_TRUE;
+static Evas_Event_Flags
+_pinch_rotate_cb(void *data, void *event_info)
+{
+   Widget_Data *wd = data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
+
+   if (!wd->paused)
+     {
+        int x, y, w, h;
+        Elm_Gesture_Rotate_Info *ei = event_info;
+        evas_object_geometry_get(wd->obj, &x, &y, &w, &h);
+
+        wd->rotate.d = wd->rotate.a + ei->angle - ei->base_angle;
+        wd->rotate.cx = x + ((double)w * 0.5);
+        wd->rotate.cy = y + ((double)h * 0.5);
+
+        evas_object_smart_changed(wd->pan_smart);
+     }
+   return EVAS_EVENT_FLAG_NONE;
 }
 
-static void
-_parse_kml(void *data)
+static Evas_Event_Flags
+_pinch_rotate_end_cb(void *data, void *event_info __UNUSED__)
 {
-   Elm_Map_Route *r = (Elm_Map_Route*)data;
-   if (!r || !r->ud.fname) return;
+   Widget_Data *wd = data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
 
-   FILE *f;
-   char **str;
-   unsigned int ele, idx;
-   double lon, lat;
-   Evas_Object *path;
+   wd->rotate.a = wd->rotate.d;
 
-   Route_Dump dump = {0, r->ud.fname, 0.0, NULL, NULL};
+   return EVAS_EVENT_FLAG_NONE;
+}
 
-   f = fopen(r->ud.fname, "rb");
-   if (f)
+static void
+_zoom_mode_set(void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
+
+   dd->wd->mode = dd->mode;
+   if (dd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
      {
-        long sz;
+        Evas_Coord w, h;
+        Evas_Coord vw, vh;
 
-        fseek(f, 0, SEEK_END);
-        sz = ftell(f);
-        if (sz > 0)
-          {
-             char *buf;
+        double zoom;
+        double diff;
 
-             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_route_dump, &dump);
-                       free(buf);
-                    }
-               }
-          }
-        fclose(f);
+        w = dd->wd->size.w;
+        h = dd->wd->size.h;
+        zoom = dd->wd->zoom_detail;
+        _viewport_size_get(dd->wd, &vw, &vh);
 
-        if (dump.distance) r->info.distance = dump.distance;
-        if (dump.description)
+        if (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
           {
-             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++)
+             if ((w < vw) && (h < vh))
                {
-                  Path_Waypoint *wp = ELM_NEW(Path_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);
-                    }
+                  diff = 0.01;
+                  while ((w < vw) && (h < vh))
+                  {
+                     zoom += diff;
+                     w = pow(2.0, zoom) * dd->wd->tsize;
+                     h = pow(2.0, zoom) * dd->wd->tsize;
+                  }
                }
-             if (str && str[0])
+             else
                {
-                  free(str[0]);
-                  free(str);
+                  diff = -0.01;
+                  while ((w > vw) || (h > vh))
+                  {
+                     zoom += diff;
+                     w = pow(2.0, zoom) * dd->wd->tsize;
+                     h = pow(2.0, zoom) * dd->wd->tsize;
+                  }
                }
-          }
-        else WRN("description is not found !");
 
-        if (dump.coordinates)
+          }
+        else if (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
           {
-             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++)
+             if ((w < vw) || (h < vh))
                {
-                  sscanf(str[idx], "%lf,%lf", &lon, &lat);
-                  Path_Node *n = ELM_NEW(Path_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_polygon_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);
-                    }
+                  diff = 0.01;
+                  while ((w < vw) || (h < vh))
+                  {
+                     zoom += diff;
+                     w = pow(2.0, zoom) * dd->wd->tsize;
+                     h = pow(2.0, zoom) * dd->wd->tsize;
+                  }
                }
-             if (str && str[0])
+             else
                {
-                  free(str[0]);
-                  free(str);
+                  diff = -0.01;
+                  while ((w > vw) && (h > vh))
+                  {
+                     zoom += diff;
+                     w = pow(2.0, zoom) * dd->wd->tsize;
+                     h = pow(2.0, zoom) * dd->wd->tsize;
+                  }
                }
           }
+       zoom_with_animation(dd->wd, zoom, 10);
      }
 }
 
 static void
-_parse_name(void *data)
+_zoom_set(void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
+
+   if (dd->wd->paused) zoom_do(dd->wd, dd->zoom);
+   else zoom_with_animation(dd->wd, dd->zoom, 10);
+   evas_object_smart_changed(dd->wd->pan_smart);
+}
+
+static void
+_region_bring_in(void *data)
 {
-   Elm_Map_Name *n = (Elm_Map_Name*)data;
-   if (!n || !n->ud.fname) return;
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
+   int x, y, w, h;
 
-   FILE *f;
+   elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat,
+                                        dd->wd->size.w, &x, &y);
+   _viewport_size_get(dd->wd, &w, &h);
+   x = x - (w / 2);
+   y = y - (h / 2);
+   elm_smart_scroller_region_bring_in(dd->wd->scr, x, y, w, h);
+   evas_object_smart_changed(dd->wd->pan_smart);
+}
 
-   Name_Dump dump = {0, NULL, 0.0, 0.0};
+static void
+_marker_list_show(void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Delayed_Data *dd = data;
+   int zoom;
+   double max_lon = -180, min_lon = 180;
+   double max_lat = -90, min_lat = 90;
+   Evas_Coord vw, vh;
+   Elm_Map_Marker *marker;
 
-   f = fopen(n->ud.fname, "rb");
-   if (f)
+   EINA_LIST_FREE(dd->markers, marker)
      {
-        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_name_dump, &dump);
-                       free(buf);
-                    }
-               }
-          }
-        fclose(f);
-
-        if (dump.address)
-          {
-             INF("[%lf : %lf] ADDRESS : %s", n->lon, n->lat, dump.address);
-             n->address = strdup(dump.address);
-          }
-        n->lon = dump.lon;
-        n->lat = dump.lat;
+        if (marker->longitude > max_lon) max_lon = marker->longitude;
+        if (marker->longitude < min_lon) min_lon = marker->longitude;
+        if (marker->latitude > max_lat) max_lat = marker->latitude;
+        if (marker->latitude < min_lat) min_lat = marker->latitude;
      }
-}
+   dd->lon = (max_lon + min_lon) / 2;
+   dd->lat = (max_lat + min_lat) / 2;
 
-Grid *_get_current_grid(Widget_Data *wd)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
-   Eina_List *l;
-   Grid *g = NULL, *ret = NULL;
-   EINA_LIST_FOREACH(wd->grids, l, g)
+   zoom = dd->wd->src->zoom_min;
+   _viewport_size_get(dd->wd, &vw, &vh);
+   while (zoom <= dd->wd->src->zoom_max)
      {
-        if (wd->zoom == g->zoom)
-          {
-             ret = g;
-             break;
-          }
+        Evas_Coord size, max_x, max_y, min_x, min_y;
+        size = pow(2.0, zoom) * dd->wd->tsize;
+        elm_map_utils_convert_geo_into_coord(dd->wd->obj, min_lon, max_lat, size, &min_x, &max_y);
+        elm_map_utils_convert_geo_into_coord(dd->wd->obj, max_lon, min_lat, size, &max_x, &min_y);
+        if ((max_x - min_x) > vw || (max_y - min_y) > vh) break;
+        zoom++;
      }
-   return ret;
+   zoom--;
+
+   zoom_do(dd->wd, zoom);
+   _region_show(dd);
+   evas_object_smart_changed(dd->wd->pan_smart);
 }
 
-static Eina_Bool
-_route_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+static char *
+_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
-   Ecore_Con_Event_Url_Complete *ev = event;
-   Elm_Map_Route *r = (Elm_Map_Route*)data;
-   Widget_Data *wd = r->wd;
+   char buf[PATH_MAX];
+   // ((x+y+zoom)%3)+'a' is requesting map images from distributed tile servers (eg., a, b, c)
+   snprintf(buf, sizeof(buf), "http://%c.tile.openstreetmap.org/%d/%d/%d.png",
+            ((x + y + zoom) % 3) + 'a', zoom, x, y);
+   return strdup(buf);
+}
 
-   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;
+static char *
+_osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "http://%c.tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
+            ((x + y + zoom) % 3) + 'a', zoom, x, y);
+   return strdup(buf);
+}
 
-   if (r->ud.fd) fclose(r->ud.fd);
-   _parse_kml(r);
+static char *
+_cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "http://%c.tile.opencyclemap.org/cycle/%d/%d/%d.png",
+            (( x + y + zoom) % 3) + 'a', zoom, x, y);
+   return strdup(buf);
+}
 
-   _route_place(wd);
+static char *
+_mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "http://otile%d.mqcdn.com/tiles/1.0.0/osm/%d/%d/%d.png",
+            ((x + y + zoom) % 4) + 1, zoom, x, y);
+   return strdup(buf);
+}
 
-   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 char *
+_mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "http://oatile%d.mqcdn.com/naip/%d/%d/%d.png",
+           ((x + y + zoom) % 4) + 1, zoom, x, y);
+   return strdup(buf);
 }
 
-static Eina_Bool
-_name_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
 {
-   Ecore_Con_Event_Url_Complete *ev = event;
-   Elm_Map_Name *n = (Elm_Map_Name*)data;
-   Widget_Data *wd = n->wd;
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%lf&flon=%lf&tlat=%lf&tlon=%lf&v=%s&fast=%d&instructions=1",
+            ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
 
-   if ((!n) || (!ev)) return EINA_TRUE;
-   Elm_Map_Name *nn = ecore_con_url_data_get(n->con_url);
-   ecore_con_url_data_set(n->con_url, NULL);
-   if (n!=nn) return EINA_TRUE;
+   return strdup(buf);
+}
 
-   if (n->ud.fd) fclose(n->ud.fd);
-   _parse_name(n);
+// 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);
 
-   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_NAME_LOADED, NULL);
-   return EINA_TRUE;
+   return strdup(buf);
 }
+*/
 
-static Elm_Map_Name *
-_utils_convert_name(const Evas_Object *obj, int method, char *address, double lon, double lat)
+// 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)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
    char buf[PATH_MAX];
-   char *source;
-   int fd;
+   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);
 
-   if ((!wd) || (!wd->src)) return NULL;
-   Elm_Map_Name *name = ELM_NEW(Elm_Map_Name);
+   return strdup(buf);
+}
+*/
 
-   snprintf(buf, sizeof(buf), DEST_NAME_XML_FILE);
-   fd = mkstemp(buf);
-   if (fd < 0)
-     {
-        free(name);
-        return NULL;
-     }
+static char *
+_nominatim_url_cb(Evas_Object *obj, int method, char *name, double lon, double lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) strdup("");
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, strdup(""));
 
-   name->con_url = ecore_con_url_new(NULL);
-   name->ud.fname = strdup(buf);
-   INF("xml file : %s", name->ud.fname);
+   char **str;
+   unsigned int ele, idx;
+   char search_url[PATH_MAX];
+   char buf[PATH_MAX];
 
-   name->ud.fd = fdopen(fd, "w+");
-   if ((!name->con_url) || (!name->ud.fd))
+   if (method == ELM_MAP_NAME_METHOD_SEARCH)
      {
-        ecore_con_url_free(name->con_url);
-        free(name);
-        return NULL;
-     }
-
-   name->wd = wd;
-   name->handler = ecore_event_handler_add (ECORE_CON_EVENT_URL_COMPLETE, _name_complete_cb, name);
-   name->method = method;
-   if (method == ELM_MAP_NAME_METHOD_SEARCH) name->address = strdup(address);
-   else if (method == ELM_MAP_NAME_METHOD_REVERSE) name->address = NULL;
-   name->lon = lon;
-   name->lat = lat;
-
-   source = wd->src->name_url_cb(wd->obj, method, address, lon, lat);
-   INF("name url = %s", source);
-
-   wd->names = eina_list_append(wd->names, name);
-   ecore_con_url_url_set(name->con_url, source);
-   ecore_con_url_fd_set(name->con_url, fileno(name->ud.fd));
-   ecore_con_url_data_set(name->con_url, name);
-
-   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_NAME_LOAD, NULL);
-   ecore_con_url_get(name->con_url);
-   if (source) free(source);
+        search_url[0] = '\0';
+        str = eina_str_split_full(name, " ", 0, &ele);
+        for (idx = 0; idx < ele; idx++)
+          {
+             eina_strlcat(search_url, str[idx], sizeof(search_url));
+             if (!(idx == (ele-1)))
+                eina_strlcat(search_url, "+", sizeof(search_url));
+          }
+        snprintf(buf, sizeof(buf),
+                 "%s/search?q=%s&format=xml&polygon=0&addressdetails=0",
+                 NAME_NOMINATIM_URL, search_url);
 
-   return name;
+        if (str && str[0])
+          {
+             free(str[0]);
+             free(str);
+          }
+     }
+   else if (method == ELM_MAP_NAME_METHOD_REVERSE)
+      snprintf(buf, sizeof(buf),
+               "%s/reverse?format=xml&lat=%lf&lon=%lf&zoom=%d&addressdetails=0",
+               NAME_NOMINATIM_URL, lat, lon, (int)wd->zoom);
+   else strcpy(buf, "");
 
+   return strdup(buf);
 }
 
-static Evas_Event_Flags
-_pinch_zoom_start_cb(void *data, void *event_info __UNUSED__)
+#endif
+
+EAPI Evas_Object *
+elm_map_add(Evas_Object *parent)
 {
-   EINA_SAFETY_ON_NULL_RETURN_VAL(data, EVAS_EVENT_FLAG_NONE);
-   Widget_Data *wd = data;
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Object *obj;
+   Evas_Coord minw, minh;
 
-   wd->pinch_zoom = wd->zoom_detail;
-   return EVAS_EVENT_FLAG_NONE;
-}
+   ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
+   ELM_SET_WIDTYPE(widtype, "map");
+   elm_widget_type_set(obj, "map");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_event_hook_set(obj, _event_hook);
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, wd);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, wd);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, wd);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _mouse_down, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
+                                  _mouse_up, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
+                                  _mouse_wheel_cb,wd);
+   wd->obj = obj;
 
-static Evas_Event_Flags
-_pinch_zoom_cb(void *data, void *event_info)
-{
-   Widget_Data *wd = data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
+   wd->scr = elm_smart_scroller_add(e);
+   elm_widget_sub_object_add(obj, wd->scr);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
+   elm_widget_resize_object_set(obj, wd->scr);
+   elm_smart_scroller_wheel_disabled_set(wd->scr, EINA_TRUE);
+   elm_smart_scroller_bounce_allow_set(wd->scr,
+                                       _elm_config->thumbscroll_bounce_enable,
+                                       _elm_config->thumbscroll_bounce_enable);
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, wd);
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr, wd);
+   evas_object_smart_callback_add(wd->scr, "drag", _scr, wd);
+   evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, wd);
+   evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, wd);
 
-   if (!wd->paused)
+   if (!smart)
      {
-        Elm_Gesture_Zoom_Info *ei = event_info;
-        zoom_do(wd, wd->pinch_zoom + ei->zoom - 1);
+        evas_object_smart_clipped_smart_set(&parent_sc);
+        sc = parent_sc;
+        sc.name = "elm_map_pan";
+        sc.version = EVAS_SMART_CLASS_VERSION;
+        sc.add = _pan_add;
+        sc.resize = _pan_resize;
+        sc.move = _pan_move;
+        sc.calculate = _pan_calculate;
+        smart = evas_smart_class_new(&sc);
      }
-   return EVAS_EVENT_FLAG_NONE;
-}
-
-static Evas_Event_Flags
-_pinch_rotate_cb(void *data, void *event_info)
-{
-   Widget_Data *wd = data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
-
-   if (!wd->paused)
+   if (smart)
      {
-        int x, y, w, h;
-        Elm_Gesture_Rotate_Info *ei = event_info;
-        evas_object_geometry_get(wd->obj, &x, &y, &w, &h);
+        Pan *pan;
+        wd->pan_smart = evas_object_smart_add(e, smart);
+        pan = evas_object_smart_data_get(wd->pan_smart);
+        pan->wd = wd;
+     }
+   elm_widget_sub_object_add(obj, wd->pan_smart);
 
-        wd->rotate.d = wd->rotate.a + ei->angle - ei->base_angle;
-        wd->rotate.cx = x + ((double)w * 0.5);
-        wd->rotate.cy = y + ((double)h * 0.5);
+   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+                                     _pan_set, _pan_get, _pan_max_get,
+                                     _pan_min_get, _pan_child_size_get);
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
+                             &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
 
-        evas_object_smart_changed(wd->pan_smart);
-     }
-   return EVAS_EVENT_FLAG_NONE;
-}
+   wd->ges = elm_gesture_layer_add(obj);
+   if (!wd->ges) ERR("elm_gesture_layer_add() failed");
+   elm_gesture_layer_attach(wd->ges, obj);
+   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
+                            _pinch_zoom_start_cb, wd);
+   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
+                            _pinch_zoom_cb, wd);
+   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE,
+                            _pinch_rotate_cb, wd);
+   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END,
+                            _pinch_rotate_end_cb, wd);
+   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT,
+                            _pinch_rotate_end_cb, wd);
 
-static Evas_Event_Flags
-_pinch_rotate_end_cb(void *data, void *event_info __UNUSED__)
-{
-   Widget_Data *wd = data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
+   wd->sep_maps_markers = evas_object_rectangle_add(evas_object_evas_get(obj));
+   elm_widget_sub_object_add(obj, wd->sep_maps_markers);
+   evas_object_smart_member_add(wd->sep_maps_markers, wd->pan_smart);
 
-   wd->rotate.a = wd->rotate.d;
+   wd->map = evas_map_new(EVAS_MAP_POINT);
 
-   return EVAS_EVENT_FLAG_NONE;
-}
+   source_init(wd);
+   wd->tsize = DEFAULT_TILE_SIZE; // FIXME: It should be hard-coded ? or can get from provider?
 
-static void
-_zoom_mode_set(void *data)
-{
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Delayed_Data *dd = data;
+   wd->id = ((int)getpid() << 16) | idnum;
+   idnum++;
+   _grid_all_create(wd);
 
-   dd->wd->mode = dd->mode;
-   if (dd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
-     {
-        Evas_Coord w, h;
-        Evas_Coord vw, vh;
+   zoom_do(wd, 0);
 
-        double zoom;
-        double diff;
+   wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
+   wd->markers_max_num = MARER_MAX_NUMBER;
 
-        w = dd->wd->size.w;
-        h = dd->wd->size.h;
-        zoom = dd->wd->zoom_detail;
-        _viewport_size_get(dd->wd, &vw, &vh);
+   // 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 (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
-          {
-             if ((w < vw) && (h < vh))
-               {
-                  diff = 0.01;
-                  while ((w < vw) && (h < vh))
-                  {
-                     zoom += diff;
-                     w = pow(2.0, zoom) * dd->wd->tsize;
-                     h = pow(2.0, zoom) * dd->wd->tsize;
-                  }
-               }
-             else
-               {
-                  diff = -0.01;
-                  while ((w > vw) || (h > vh))
-                  {
-                     zoom += diff;
-                     w = pow(2.0, zoom) * dd->wd->tsize;
-                     h = pow(2.0, zoom) * dd->wd->tsize;
-                  }
-               }
+   if (!ecore_file_download_protocol_available("http://"))
+      ERR("Ecore must be built with curl support for the map widget!");
 
-          }
-        else if (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
-          {
-             if ((w < vw) || (h < vh))
-               {
-                  diff = 0.01;
-                  while ((w < vw) || (h < vh))
-                  {
-                     zoom += diff;
-                     w = pow(2.0, zoom) * dd->wd->tsize;
-                     h = pow(2.0, zoom) * dd->wd->tsize;
-                  }
-               }
-             else
-               {
-                  diff = -0.01;
-                  while ((w > vw) && (h > vh))
-                  {
-                     zoom += diff;
-                     w = pow(2.0, zoom) * dd->wd->tsize;
-                     h = pow(2.0, zoom) * dd->wd->tsize;
-                  }
-               }
-          }
-       zoom_with_animation(dd->wd, zoom, 10);
-     }
+   return obj;
+#else
+   (void) parent;
+   return NULL;
+#endif
 }
 
-static void
-_zoom_set(void *data)
+EAPI void
+elm_map_zoom_set(Evas_Object *obj, int zoom)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Delayed_Data *dd = data;
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(wd->src);
 
-   if (dd->wd->paused) zoom_do(dd->wd, dd->zoom);
-   else zoom_with_animation(dd->wd, dd->zoom, 10);
-   evas_object_smart_changed(dd->wd->pan_smart);
+   if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL) return;
+   if (zoom < 0) zoom = 0;
+   if (wd->zoom == zoom) return;
+   if (zoom > wd->src->zoom_max) zoom = wd->src->zoom_max;
+   if (zoom < wd->src->zoom_min) zoom = wd->src->zoom_min;
+
+   Delayed_Data *data = ELM_NEW(Delayed_Data);
+   data->func = _zoom_set;
+   data->wd = wd;
+   data->zoom = zoom;
+   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
+   evas_object_smart_changed(data->wd->pan_smart);
+#else
+   (void) obj;
+   (void) zoom;
+#endif
 }
 
-static void
-_region_bring_in(void *data)
+EAPI int
+elm_map_zoom_get(const Evas_Object *obj)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Delayed_Data *dd = data;
-   int x, y, w, h;
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
 
-   elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat,
-                                        dd->wd->size.w, &x, &y);
-   _viewport_size_get(dd->wd, &w, &h);
-   x = x - (w / 2);
-   y = y - (h / 2);
-   elm_smart_scroller_region_bring_in(dd->wd->scr, x, y, w, h);
-   evas_object_smart_changed(dd->wd->pan_smart);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, 0);
+   return wd->zoom;
+#else
+   (void) obj;
+   return 0;
+#endif
 }
 
-static void
-_region_show(void *data)
+EAPI void
+elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Delayed_Data *dd = data;
-   int x, y, w, h;
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat,
-                                        dd->wd->size.w, &x, &y);
-   _viewport_size_get(dd->wd, &w, &h);
-   x = x - (w / 2);
-   y = y - (h / 2);
-   elm_smart_scroller_child_region_show(dd->wd->scr, x, y, w, h);
-   evas_object_smart_changed(dd->wd->pan_smart);
+   if ((mode == ELM_MAP_ZOOM_MODE_MANUAL) && (wd->mode == !!mode)) return;
+
+   Delayed_Data *data = ELM_NEW(Delayed_Data);
+   data->mode = mode;
+   data->func = _zoom_mode_set;
+   data->wd = wd;
+   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
+   evas_object_smart_changed(data->wd->pan_smart);
+#else
+   (void) obj;
+   (void) mode;
+#endif
 }
 
-static void
-_marker_list_show(void *data)
+EAPI Elm_Map_Zoom_Mode
+elm_map_zoom_mode_get(const Evas_Object *obj)
 {
-   EINA_SAFETY_ON_NULL_RETURN(data);
-   Delayed_Data *dd = data;
-   int zoom;
-   double max_lon = -180, min_lon = 180;
-   double max_lat = -90, min_lat = 90;
-   Evas_Coord vw, vh;
-   Elm_Map_Marker *marker;
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ZOOM_MODE_MANUAL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ELM_MAP_ZOOM_MODE_MANUAL);
 
-   EINA_LIST_FREE(dd->markers, marker)
-     {
-        if (marker->longitude > max_lon) max_lon = marker->longitude;
-        if (marker->longitude < min_lon) min_lon = marker->longitude;
-        if (marker->latitude > max_lat) max_lat = marker->latitude;
-        if (marker->latitude < min_lat) min_lat = marker->latitude;
-     }
-   dd->lon = (max_lon + min_lon) / 2;
-   dd->lat = (max_lat + min_lat) / 2;
+   return wd->mode;
+#else
+   (void) obj;
+   return ELM_MAP_ZOOM_MODE_MANUAL;
+#endif
+}
 
-   zoom = dd->wd->src->zoom_min;
-   _viewport_size_get(dd->wd, &vw, &vh);
-   while (zoom <= dd->wd->src->zoom_max)
-     {
-        Evas_Coord size, max_x, max_y, min_x, min_y;
-        size = pow(2.0, zoom) * dd->wd->tsize;
-        elm_map_utils_convert_geo_into_coord(dd->wd->obj, min_lon, max_lat, size, &min_x, &max_y);
-        elm_map_utils_convert_geo_into_coord(dd->wd->obj, max_lon, min_lat, size, &max_x, &min_y);
-        if ((max_x - min_x) > vw || (max_y - min_y) > vh) break;
-        zoom++;
-     }
-   zoom--;
+EAPI void
+elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
 
-   zoom_do(dd->wd, zoom);
-   _region_show(dd);
-   evas_object_smart_changed(dd->wd->pan_smart);
+   Delayed_Data *data = ELM_NEW(Delayed_Data);
+   data->func = _region_bring_in;
+   data->wd = wd;
+   data->lon = lon;
+   data->lat = lat;
+   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
+   evas_object_smart_changed(data->wd->pan_smart);
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+#endif
 }
 
-static char *
-_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+EAPI void
+elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
 {
-   char buf[PATH_MAX];
-   // ((x+y+zoom)%3)+'a' is requesting map images from distributed tile servers (eg., a, b, c)
-   snprintf(buf, sizeof(buf), "http://%c.tile.openstreetmap.org/%d/%d/%d.png",
-            ((x + y + zoom) % 3) + 'a', zoom, x, y);
-   return strdup(buf);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   Delayed_Data *data = ELM_NEW(Delayed_Data);
+   data->func = _region_show;
+   data->wd = wd;
+   data->lon = lon;
+   data->lat = lat;
+   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
+   evas_object_smart_changed(data->wd->pan_smart);
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+#endif
 }
 
-static char *
-_osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+EAPI void
+elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat)
 {
-   char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf),
-            "http://%c.tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
-            ((x + y + zoom) % 3) + 'a', zoom, x, y);
-   return strdup(buf);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   double tlon, tlat;
+   Evas_Coord px, py, vw, vh;
+
+   _pan_geometry_get(wd, &px, &py);
+   _viewport_size_get(wd, &vw, &vh);
+   elm_map_utils_convert_coord_into_geo(obj, vw/2 - px, vh/2 -py, wd->size.w,
+                                        &tlon, &tlat);
+   if (lon) *lon = tlon;
+   if (lat) *lat = tlat;
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+#endif
 }
 
-static char *
-_cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+EAPI void
+elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
 {
-   char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf),
-            "http://%c.tile.opencyclemap.org/cycle/%d/%d/%d.png",
-            (( x + y + zoom) % 3) + 'a', zoom, x, y);
-   return strdup(buf);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   if (wd->paused == !!paused) return;
+   wd->paused = !!paused;
+   if (wd->paused)
+     {
+        if (wd->zoom_animator)
+          {
+             if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
+             wd->zoom_animator = NULL;
+             zoom_do(wd, wd->zoom);
+          }
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                "elm,state,busy,stop", "elm");
+     }
+   else
+     {
+        if (wd->download_num >= 1)
+           edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                   "elm,state,busy,start", "elm");
+     }
+#else
+   (void) obj;
+   (void) paused;
+#endif
 }
 
-static char *
-_mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+EAPI void
+elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
 {
-   char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf),
-            "http://otile%d.mqcdn.com/tiles/1.0.0/osm/%d/%d/%d.png",
-            ((x + y + zoom) % 4) + 1, zoom, x, y);
-   return strdup(buf);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   if (wd->paused_markers == !!paused) return;
+   wd->paused_markers = paused;
+#else
+   (void) obj;
+   (void) paused;
+#endif
 }
 
-static char *
-_mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
+EAPI Eina_Bool
+elm_map_paused_get(const Evas_Object *obj)
 {
-   char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf), "http://oatile%d.mqcdn.com/naip/%d/%d/%d.png",
-           ((x + y + zoom) % 4) + 1, zoom, x, y);
-   return strdup(buf);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+
+   return wd->paused;
+#else
+   (void) obj;
+   return EINA_FALSE;
+#endif
 }
 
-static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+EAPI Eina_Bool
+elm_map_paused_markers_get(const Evas_Object *obj)
 {
-   char buf[PATH_MAX];
-   snprintf(buf, sizeof(buf),
-            "%s?flat=%lf&flon=%lf&tlat=%lf&tlon=%lf&v=%s&fast=%d&instructions=1",
-            ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
 
-   return strdup(buf);
+   return wd->paused_markers;
+#else
+   (void) obj;
+   return EINA_FALSE;
+#endif
 }
 
-// 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)
+EAPI void
+elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
 {
-   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);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   return strdup(buf);
+   if (try_num) *try_num = wd->try_num;
+   if (finish_num) *finish_num = wd->finish_num;
+#else
+   (void) obj;
+   (void) try_num;
+   (void) finish_num;
+#endif
 }
-*/
 
-// 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)
+EAPI void
+elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat)
 {
-   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);
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   return strdup(buf);
+   int zoom = floor(log(size / 256) / log(2));
+   if ((wd->src) && (wd->src->coord_into_geo))
+     {
+        if (wd->src->coord_into_geo(obj, zoom, x, y, size, lon, lat)) return;
+     }
+
+   if (lon) *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)));
+     }
+#else
+   (void) obj;
+   (void) x;
+   (void) y;
+   (void) size;
+   (void) lon;
+   (void) lat;
+#endif
 }
-*/
 
-static char *
-_nominatim_url_cb(Evas_Object *obj, int method, char *name, 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)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype) strdup("");
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, strdup(""));
-
-   char **str;
-   unsigned int ele, idx;
-   char search_url[PATH_MAX];
-   char buf[PATH_MAX];
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   if (method == ELM_MAP_NAME_METHOD_SEARCH)
+   int zoom = floor(log(size / 256) / log(2));
+   if ((wd->src) && (wd->src->geo_into_coord))
      {
-        search_url[0] = '\0';
-        str = eina_str_split_full(name, " ", 0, &ele);
-        for (idx = 0; idx < ele; idx++)
-          {
-             eina_strlcat(search_url, str[idx], sizeof(search_url));
-             if (!(idx == (ele-1)))
-                eina_strlcat(search_url, "+", sizeof(search_url));
-          }
-        snprintf(buf, sizeof(buf),
-                 "%s/search?q=%s&format=xml&polygon=0&addressdetails=0",
-                 NAME_NOMINATIM_URL, search_url);
-
-        if (str && str[0])
-          {
-             free(str[0]);
-             free(str);
-          }
+        if (wd->src->geo_into_coord(obj, zoom, lon, lat, size, x, y)) return;
      }
-   else if (method == ELM_MAP_NAME_METHOD_REVERSE)
-      snprintf(buf, sizeof(buf),
-               "%s/reverse?format=xml&lat=%lf&lon=%lf&zoom=%d&addressdetails=0",
-               NAME_NOMINATIM_URL, lat, lon, (int)wd->zoom);
-   else strcpy(buf, "");
 
-   return strdup(buf);
+   if (x) *x = floor((lon + 180.0) / 360.0 * size);
+   if (y)
+      *y = floor((1.0 - log(tan(lat * ELM_PI / 180.0) + (1.0 / cos(lat * ELM_PI / 180.0)))
+                 / ELM_PI) / 2.0 * size);
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+   (void) size;
+   (void) x;
+   (void) y;
+#endif
+}
+
+EAPI Elm_Map_Name *
+elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_REVERSE, NULL, lon, lat);
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+   return NULL;
+#endif
 }
 
+EAPI Elm_Map_Name *
+elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   if (!address) return NULL;
+   return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_SEARCH, address, 0.0, 0.0);
+#else
+   (void) obj;
+   (void) address;
+   return NULL;
 #endif
+}
 
-EAPI Evas_Object *
-elm_map_add(Evas_Object *parent)
+EINA_DEPRECATED EAPI void
+elm_map_utils_rotate_coord(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, const Evas_Coord cx, const Evas_Coord cy, const double degree, Evas_Coord *xx, Evas_Coord *yy)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   Evas *e;
-   Widget_Data *wd;
-   Evas_Object *obj;
-   Evas_Coord minw, minh;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   _coord_rotate(x, y, cx, cy, degree, xx, yy);
+#else
+   (void) x;
+   (void) y;
+   (void) cx;
+   (void) cy;
+   (void) degree;
+   (void) xx;
+   (void) yy;
+#endif
+}
 
-   ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
-   ELM_SET_WIDTYPE(widtype, "map");
-   elm_widget_type_set(obj, "map");
-   elm_widget_sub_object_add(parent, obj);
-   elm_widget_data_set(obj, wd);
-   elm_widget_can_focus_set(obj, EINA_TRUE);
-   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
-   elm_widget_del_hook_set(obj, _del_hook);
-   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
-   elm_widget_theme_hook_set(obj, _theme_hook);
-   elm_widget_event_hook_set(obj, _event_hook);
-   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, wd);
-   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, wd);
-   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, wd);
-   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, wd);
-   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
-                                  _mouse_down, wd);
-   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
-                                  _mouse_up, wd);
-   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
-                                  _mouse_wheel_cb,wd);
-   wd->obj = obj;
+EAPI void
+elm_map_canvas_to_geo_convert(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, double *lon, double *lat)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(lon);
+   EINA_SAFETY_ON_NULL_RETURN(lat);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   wd->scr = elm_smart_scroller_add(e);
-   elm_widget_sub_object_add(obj, wd->scr);
-   elm_smart_scroller_widget_set(wd->scr, obj);
-   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
-   elm_widget_resize_object_set(obj, wd->scr);
-   elm_smart_scroller_wheel_disabled_set(wd->scr, EINA_TRUE);
-   elm_smart_scroller_bounce_allow_set(wd->scr,
-                                       _elm_config->thumbscroll_bounce_enable,
-                                       _elm_config->thumbscroll_bounce_enable);
-   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
-                                  _changed_size_hints, wd);
-   evas_object_smart_callback_add(wd->scr, "scroll", _scr, wd);
-   evas_object_smart_callback_add(wd->scr, "drag", _scr, wd);
-   evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, wd);
-   evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, wd);
+   Evas_Coord px, py, vw, vh;
+   _pan_geometry_get(wd, &px, &py);
+   _viewport_size_get(wd, &vw, &vh);
+   _coord_rotate(x - px, y - py, (vw / 2) - px, (vh / 2) - py, -wd->rotate.d,
+                 &x, &y);
+   elm_map_utils_convert_coord_into_geo(obj, x, y, wd->size.w, lon, lat);
+#else
+   (void) obj;
+   (void) x;
+   (void) y;
+   (void) lon;
+   (void) lat;
+#endif
+}
 
-   if (!smart)
-     {
-        evas_object_smart_clipped_smart_set(&parent_sc);
-        sc = parent_sc;
-        sc.name = "elm_map_pan";
-        sc.version = EVAS_SMART_CLASS_VERSION;
-        sc.add = _pan_add;
-        sc.resize = _pan_resize;
-        sc.move = _pan_move;
-        sc.calculate = _pan_calculate;
-        smart = evas_smart_class_new(&sc);
-     }
-   if (smart)
-     {
-        Pan *pan;
-        wd->pan_smart = evas_object_smart_add(e, smart);
-        pan = evas_object_smart_data_get(wd->pan_smart);
-        pan->wd = wd;
-     }
-   elm_widget_sub_object_add(obj, wd->pan_smart);
+EAPI Elm_Map_Marker *
+elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *group_clas, void *data)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(clas, NULL);
+
+   Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
+   marker->wd = wd;
+   marker->clas = clas;
+   marker->group_clas = group_clas;
+   marker->longitude = lon;
+   marker->latitude = lat;
+   marker->data = data;
+   marker->x = 0;
+   marker->y = 0;
+   _edj_marker_size_get(wd, &marker->w, &marker->h);
 
-   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
-                                     _pan_set, _pan_get, _pan_max_get,
-                                     _pan_min_get, _pan_child_size_get);
-   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
-                             &minw, &minh);
-   evas_object_size_hint_min_set(obj, minw, minh);
+   marker->obj = elm_layout_add(wd->obj);
+   evas_object_smart_member_add(marker->obj, wd->pan_smart);
+   evas_object_stack_above(marker->obj, wd->sep_maps_markers);
 
-   wd->ges = elm_gesture_layer_add(obj);
-   if (!wd->ges) ERR("elm_gesture_layer_add() failed");
-   elm_gesture_layer_attach(wd->ges, obj);
-   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
-                            _pinch_zoom_start_cb, wd);
-   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
-                            _pinch_zoom_cb, wd);
-   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE,
-                            _pinch_rotate_cb, wd);
-   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END,
-                            _pinch_rotate_end_cb, wd);
-   elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT,
-                            _pinch_rotate_end_cb, wd);
+   edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
+                                   "open", "elm", _marker_bubble_open_cb,
+                                   marker);
+   edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
+                                   "bringin", "elm", _marker_bringin_cb,
+                                   marker);
 
-   wd->sep_maps_markers = evas_object_rectangle_add(evas_object_evas_get(obj));
-   elm_widget_sub_object_add(obj, wd->sep_maps_markers);
-   evas_object_smart_member_add(wd->sep_maps_markers, wd->pan_smart);
+   wd->markers = eina_list_append(wd->markers, marker);
+   if (marker->group_clas) group_clas->markers = eina_list_append(group_clas->markers,
+                                                                  marker);
+   evas_object_smart_changed(wd->pan_smart);
+   return marker;
+#else
+   (void) obj;
+   (void) lon;
+   (void) lat;
+   (void) clas;
+   (void) group_clas;
+   (void) data;
+   return NULL;
+#endif
+}
 
-   wd->map = evas_map_new(EVAS_MAP_POINT);
+EAPI void
+elm_map_marker_remove(Elm_Map_Marker *marker)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(marker);
+   Widget_Data *wd = marker->wd;
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   source_init(wd);
-   wd->tsize = DEFAULT_TILE_SIZE; // FIXME: It should be hard-coded ? or can get from provider?
+   if ((marker->content) && (marker->clas->func.del))
+      marker->clas->func.del(wd->obj, marker, marker->data, marker->content);
 
-   wd->id = ((int)getpid() << 16) | idnum;
-   idnum++;
-   _grid_all_create(wd);
+   if (marker->bubble) _bubble_free(marker->bubble);
+   if (marker->group) _marker_group_free(marker->group);
 
-   zoom_do(wd, 0);
+   if (marker->group_clas)
+      marker->group_clas->markers = eina_list_remove(marker->group_clas->markers, marker);
+   wd->markers = eina_list_remove(wd->markers, marker);
 
-   wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
-   wd->markers_max_num = MARER_MAX_NUMBER;
+   evas_object_del(marker->obj);
+   free(marker);
 
-   // 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);
+   evas_object_smart_changed(wd->pan_smart);
+#else
+   (void) marker;
+#endif
+}
 
-   if (!ecore_file_download_protocol_available("http://"))
-      ERR("Ecore must be built with curl support for the map widget!");
+EAPI void
+elm_map_marker_region_get(const Elm_Map_Marker *marker, double *lon, double *lat)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(marker);
+   if (lon) *lon = marker->longitude;
+   if (lat) *lat = marker->latitude;
+#else
+   (void) marker;
+   (void) lon;
+   (void) lat;
+#endif
+}
 
-   return obj;
+EAPI void
+elm_map_marker_bring_in(Elm_Map_Marker *marker)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(marker);
+   elm_map_geo_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
 #else
-   (void) parent;
-   return NULL;
+   (void) marker;
 #endif
 }
 
 EAPI void
-elm_map_zoom_set(Evas_Object *obj, int zoom)
+elm_map_marker_show(Elm_Map_Marker *marker)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-   EINA_SAFETY_ON_NULL_RETURN(wd->src);
+   EINA_SAFETY_ON_NULL_RETURN(marker);
+   elm_map_geo_region_show(marker->wd->obj, marker->longitude, marker->latitude);
+#else
+   (void) marker;
+#endif
+}
 
-   if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL) return;
-   if (zoom < 0) zoom = 0;
-   if (wd->zoom == zoom) return;
-   if (zoom > wd->src->zoom_max) zoom = wd->src->zoom_max;
-   if (zoom < wd->src->zoom_min) zoom = wd->src->zoom_min;
+EAPI void
+elm_map_markers_list_show(Eina_List *markers)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(markers);
+   EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(markers));
+
+   Elm_Map_Marker *marker;
+   marker = eina_list_data_get(markers);
 
    Delayed_Data *data = ELM_NEW(Delayed_Data);
-   data->func = _zoom_set;
-   data->wd = wd;
-   data->zoom = zoom;
+   data->func = _marker_list_show;
+   data->wd = marker->wd;
+   data->markers = eina_list_clone(markers);
    data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
    evas_object_smart_changed(data->wd->pan_smart);
 #else
-   (void) obj;
-   (void) zoom;
+   (void) markers;
 #endif
 }
 
-EAPI int
-elm_map_zoom_get(const Evas_Object *obj)
+EAPI void
+elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, 0);
-   return wd->zoom;
+   wd->markers_max_num = max;
 #else
    (void) obj;
-   return 0;
+   (void) max;
+#endif
+}
+
+EAPI Evas_Object *
+elm_map_marker_object_get(const Elm_Map_Marker *marker)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN_VAL(marker, NULL);
+   return marker->content;
+#else
+   (void) marker;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
+elm_map_marker_update(Elm_Map_Marker *marker)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(marker);
+   Widget_Data *wd = marker->wd;
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   _marker_update(marker);
+#else
+   (void) marker;
+#endif
+}
+
+EAPI void
+elm_map_bubbles_close(Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   Delayed_Data *data = ELM_NEW(Delayed_Data);
-   data->mode = mode;
-   data->func = _zoom_mode_set;
-   data->wd = wd;
-   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
-   evas_object_smart_changed(data->wd->pan_smart);
+   Eina_List *l;
+   Elm_Map_Marker *marker;
+   EINA_LIST_FOREACH(wd->markers, l, marker)
+     {
+        if (marker->bubble) _bubble_free(marker->bubble);
+        marker->bubble = NULL;
+
+        if (marker->group)
+          {
+             if (marker->group->bubble) _bubble_free(marker->group->bubble);
+             marker->group->bubble = NULL;
+          }
+     }
 #else
    (void) obj;
-   (void) mode;
 #endif
 }
 
-EAPI Elm_Map_Zoom_Mode
-elm_map_zoom_mode_get(const Evas_Object *obj)
+EAPI Elm_Map_Group_Class *
+elm_map_group_class_new(Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ZOOM_MODE_MANUAL;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ELM_MAP_ZOOM_MODE_MANUAL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   return wd->mode;
+   Elm_Map_Group_Class *clas = ELM_NEW(Elm_Map_Group_Class);
+   clas->wd = wd;
+   clas->zoom_displayed = 0;
+   clas->zoom_grouped = 255;
+   eina_stringshare_replace(&clas->style, "radio");
+
+   wd->group_classes = eina_list_append(wd->group_classes, clas);
+
+   return clas;
 #else
    (void) obj;
-   return ELM_MAP_ZOOM_MODE_MANUAL;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
+elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   eina_stringshare_replace(&clas->style, style);
+#else
+   (void) clas;
+   (void) style;
+#endif
+}
 
-   Delayed_Data *data = ELM_NEW(Delayed_Data);
-   data->func = _region_bring_in;
-   data->wd = wd;
-   data->lon = lon;
-   data->lat = lat;
-   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
-   evas_object_smart_changed(data->wd->pan_smart);
+EAPI void
+elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, Elm_Map_Group_Icon_Get_Func icon_get)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->func.icon_get = icon_get;
 #else
-   (void) obj;
-   (void) lon;
-   (void) lat;
+   (void) clas;
+   (void) icon_get;
 #endif
 }
 
 EAPI void
-elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
+elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-
-   Delayed_Data *data = ELM_NEW(Delayed_Data);
-   data->func = _region_show;
-   data->wd = wd;
-   data->lon = lon;
-   data->lat = lat;
-   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
-   evas_object_smart_changed(data->wd->pan_smart);
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->data = data;
 #else
-   (void) obj;
-   (void) lon;
-   (void) lat;
+   (void) clas;
+   (void) data;
 #endif
 }
 
 EAPI void
-elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat)
+elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   double tlon, tlat;
-   Evas_Coord px, py, vw, vh;
-
-   _pan_geometry_get(wd, &px, &py);
-   _viewport_size_get(wd, &vw, &vh);
-   elm_map_utils_convert_coord_into_geo(obj, vw/2 - px, vh/2 -py, wd->size.w,
-                                        &tlon, &tlat);
-   if (lon) *lon = tlon;
-   if (lat) *lat = tlat;
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->zoom_displayed = zoom;
 #else
-   (void) obj;
-   (void) lon;
-   (void) lat;
+   (void) clas;
+   (void) zoom;
 #endif
 }
 
 EAPI void
-elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
+elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   if (wd->paused == !!paused) return;
-   wd->paused = !!paused;
-   if (wd->paused)
-     {
-        if (wd->zoom_animator)
-          {
-             if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
-             wd->zoom_animator = NULL;
-             zoom_do(wd, wd->zoom);
-          }
-        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
-                                "elm,state,busy,stop", "elm");
-     }
-   else
-     {
-        if (wd->download_num >= 1)
-           edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
-                                   "elm,state,busy,start", "elm");
-     }
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->zoom_grouped = zoom;
 #else
-   (void) obj;
-   (void) paused;
+   (void) clas;
+   (void) zoom;
 #endif
 }
 
 EAPI void
-elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
+elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(clas);
 
-   if (wd->paused_markers == !!paused) return;
-   wd->paused_markers = paused;
+   clas->hide = hide;
+   evas_object_smart_changed(wd->pan_smart);
 #else
    (void) obj;
-   (void) paused;
+   (void) clas;
+   (void) hide;
 #endif
 }
 
-EAPI Eina_Bool
-elm_map_paused_get(const Evas_Object *obj)
+EAPI Elm_Map_Marker_Class *
+elm_map_marker_class_new(Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   return wd->paused;
+   Elm_Map_Marker_Class *clas = ELM_NEW(Elm_Map_Marker_Class);
+   eina_stringshare_replace(&clas->style, "radio");
+
+   wd->marker_classes = eina_list_append(wd->marker_classes, clas);
+   return clas;
 #else
    (void) obj;
-   return EINA_FALSE;
+   return NULL;
 #endif
 }
 
-EAPI Eina_Bool
-elm_map_paused_markers_get(const Evas_Object *obj)
+EAPI void
+elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
-
-   return wd->paused_markers;
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   eina_stringshare_replace(&clas->style, style);
 #else
-   (void) obj;
-   return EINA_FALSE;
+   (void) clas;
+   (void) style;
 #endif
 }
 
 EAPI void
-elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
+elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Icon_Get_Func icon_get)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   if (try_num) *try_num = wd->try_num;
-   if (finish_num) *finish_num = wd->finish_num;
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->func.icon_get = icon_get;
 #else
-   (void) obj;
-   (void) try_num;
-   (void) finish_num;
+   (void) clas;
+   (void) icon_get;
 #endif
 }
 
 EAPI void
-elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat)
+elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Get_Func get)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   int zoom = floor(log(size / 256) / log(2));
-   if ((wd->src) && (wd->src->coord_into_geo))
-     {
-        if (wd->src->coord_into_geo(obj, zoom, x, y, size, lon, lat)) return;
-     }
-
-   if (lon) *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)));
-     }
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->func.get = get;
 #else
-   (void) obj;
-   (void) x;
-   (void) y;
-   (void) size;
-   (void) lon;
-   (void) lat;
+   (void) clas;
+   (void) get;
 #endif
 }
 
 EAPI void
-elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y)
+elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Del_Func del)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   int zoom = floor(log(size / 256) / log(2));
-   if ((wd->src) && (wd->src->geo_into_coord))
-     {
-        if (wd->src->geo_into_coord(obj, zoom, lon, lat, size, x, y)) return;
-     }
-
-   if (x) *x = floor((lon + 180.0) / 360.0 * size);
-   if (y)
-      *y = floor((1.0 - log(tan(lat * ELM_PI / 180.0) + (1.0 / cos(lat * ELM_PI / 180.0)))
-                 / ELM_PI) / 2.0 * size);
+   EINA_SAFETY_ON_NULL_RETURN(clas);
+   clas->func.del = del;
 #else
-   (void) obj;
-   (void) lon;
-   (void) lat;
-   (void) size;
-   (void) x;
-   (void) y;
+   (void) clas;
+   (void) del;
 #endif
 }
 
-EAPI Elm_Map_Name *
-elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat)
+EAPI const char **
+elm_map_source_names_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_REVERSE, NULL, lon, lat);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+
+   return wd->src_names;
 #else
    (void) obj;
-   (void) lon;
-   (void) lat;
    return NULL;
 #endif
 }
 
-EAPI Elm_Map_Name *
-elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address)
+EAPI void
+elm_map_source_name_set(Evas_Object *obj, const char *source_name)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   if (!address) return NULL;
-   return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_SEARCH, address, 0.0, 0.0);
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   Map_Sources_Tab *s;
+   Eina_List *l;
+   int zoom;
+
+   if (wd->src)
+     {
+        if (!strcmp(wd->src->name, source_name)) return;
+        if (!wd->src->url_cb) return;
+     }
+
+   _grid_all_clear(wd);
+   EINA_LIST_FOREACH(wd->srcs, l, s)
+     {
+        if (!strcmp(s->name, source_name))
+          {
+             wd->src = s;
+             break;
+          }
+     }
+   zoom = wd->zoom;
+   wd->zoom = -1;
+
+   if (wd->src)
+     {
+        if (wd->src->zoom_max < zoom)
+          zoom = wd->src->zoom_max;
+        if (wd->src->zoom_min > zoom)
+          zoom = wd->src->zoom_min;
+        if (wd->src->zoom_max < wd->zoom_max) wd->zoom_max = wd->src->zoom_max;
+        if (wd->src->zoom_min > wd->zoom_min) wd->zoom_min = wd->src->zoom_min;
+     }
+   _grid_all_create(wd);
+   zoom_do(wd, zoom);
 #else
    (void) obj;
-   (void) address;
-   return NULL;
+   (void) source_name;
 #endif
 }
 
-EINA_DEPRECATED EAPI void
-elm_map_utils_rotate_coord(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, const Evas_Coord cx, const Evas_Coord cy, const double degree, Evas_Coord *xx, Evas_Coord *yy)
+EAPI const char *
+elm_map_source_name_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   _coord_rotate(x, y, cx, cy, degree, xx, yy);
-#else
-   (void) x;
-   (void) y;
-   (void) cx;
-   (void) cy;
-   (void) degree;
-   (void) xx;
-   (void) yy;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if ((!wd) || (!wd->src)) return NULL;
+   return wd->src->name;
+#else
+   (void) obj;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_canvas_to_geo_convert(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, double *lon, double *lat)
+elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(lon);
-   EINA_SAFETY_ON_NULL_RETURN(lat);
    EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   Evas_Coord px, py, vw, vh;
-   _pan_geometry_get(wd, &px, &py);
-   _viewport_size_get(wd, &vw, &vh);
-   _coord_rotate(x - px, y - py, (vw / 2) - px, (vh / 2) - py, -wd->rotate.d,
-                 &x, &y);
-   elm_map_utils_convert_coord_into_geo(obj, x, y, wd->size.w, lon, lat);
+   wd->route_source = source;
 #else
    (void) obj;
-   (void) x;
-   (void) y;
-   (void) lon;
-   (void) lat;
+   (void) source;
 #endif
 }
 
-EAPI Elm_Map_Marker *
-elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *group_clas, void *data)
+EAPI Elm_Map_Route_Sources
+elm_map_route_source_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ROUTE_SOURCE_YOURS;
    Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ELM_MAP_ROUTE_SOURCE_YOURS);
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(clas, NULL);
-
-   Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
-   marker->wd = wd;
-   marker->clas = clas;
-   marker->group_clas = group_clas;
-   marker->longitude = lon;
-   marker->latitude = lat;
-   marker->data = data;
-   marker->x = 0;
-   marker->y = 0;
-   _edj_marker_size_get(wd, &marker->w, &marker->h);
-
-   marker->obj = elm_layout_add(wd->obj);
-   evas_object_smart_member_add(marker->obj, wd->pan_smart);
-   evas_object_stack_above(marker->obj, wd->sep_maps_markers);
-
-   edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
-                                   "open", "elm", _marker_bubble_open_cb,
-                                   marker);
-   edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
-                                   "bringin", "elm", _marker_bringin_cb,
-                                   marker);
-
-   wd->markers = eina_list_append(wd->markers, marker);
-   if (marker->group_clas) group_clas->markers = eina_list_append(group_clas->markers,
-                                                                  marker);
-   evas_object_smart_changed(wd->pan_smart);
-   return marker;
+   return wd->route_source;
 #else
    (void) obj;
-   (void) lon;
-   (void) lat;
-   (void) clas;
-   (void) group_clas;
-   (void) data;
-   return NULL;
+   return ELM_MAP_ROUTE_SOURCE_YOURS;
 #endif
 }
 
 EAPI void
-elm_map_marker_remove(Elm_Map_Marker *marker)
+elm_map_source_zoom_max_set(Evas_Object *obj, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(marker);
-   Widget_Data *wd = marker->wd;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(wd->src);
 
-   if ((marker->content) && (marker->clas->func.del))
-      marker->clas->func.del(wd->obj, marker, marker->data, marker->content);
-
-   if (marker->bubble) _bubble_free(marker->bubble);
-   if (marker->group) _marker_group_free(marker->group);
-
-   if (marker->group_clas)
-      marker->group_clas->markers = eina_list_remove(marker->group_clas->markers, marker);
-   wd->markers = eina_list_remove(wd->markers, marker);
+   if ((zoom > wd->src->zoom_max) || (zoom < wd->src->zoom_min)) return;
+   wd->zoom_max = zoom;
+#else
+   (void) obj;
+   (void) zoom;
+#endif
+}
 
-   evas_object_del(marker->obj);
-   free(marker);
+EAPI int
+elm_map_source_zoom_max_get(const Evas_Object *obj)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   ELM_CHECK_WIDTYPE(obj, widtype) 18;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, -1);
 
-   evas_object_smart_changed(wd->pan_smart);
+   return wd->zoom_max;
 #else
-   (void) marker;
+   (void) obj;
+   return 18;
 #endif
 }
 
 EAPI void
-elm_map_marker_region_get(const Elm_Map_Marker *marker, double *lon, double *lat)
+elm_map_source_zoom_min_set(Evas_Object *obj, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(marker);
-   if (lon) *lon = marker->longitude;
-   if (lat) *lat = marker->latitude;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(wd->src);
+
+   if ((zoom > wd->src->zoom_max) || (zoom < wd->src->zoom_min)) return;
+   wd->zoom_min = zoom;
 #else
-   (void) marker;
-   (void) lon;
-   (void) lat;
+   (void) obj;
+   (void) zoom;
 #endif
 }
 
-EAPI void
-elm_map_marker_bring_in(Elm_Map_Marker *marker)
+EAPI int
+elm_map_source_zoom_min_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(marker);
-   elm_map_geo_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, -1);
+
+   return wd->zoom_min;
 #else
-   (void) marker;
+   (void) obj;
+   return 0;
 #endif
 }
 
 EAPI void
-elm_map_marker_show(Elm_Map_Marker *marker)
+elm_map_user_agent_set(Evas_Object *obj, const char *user_agent)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(marker);
-   elm_map_geo_region_show(marker->wd->obj, marker->longitude, marker->latitude);
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(user_agent);
+
+   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);
 #else
-   (void) marker;
+   (void) obj;
+   (void) user_agent;
 #endif
 }
 
-EAPI void
-elm_map_markers_list_show(Eina_List *markers)
+EAPI const char *
+elm_map_user_agent_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(markers);
-   EINA_SAFETY_ON_TRUE_RETURN(!eina_list_count(markers));
-
-   Elm_Map_Marker *marker;
-   marker = eina_list_data_get(markers);
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   Delayed_Data *data = ELM_NEW(Delayed_Data);
-   data->func = _marker_list_show;
-   data->wd = marker->wd;
-   data->markers = eina_list_clone(markers);
-   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
-   evas_object_smart_changed(data->wd->pan_smart);
+   return wd->user_agent;
 #else
-   (void) markers;
+   (void) obj;
+   return NULL;
 #endif
 }
 
-EAPI void
-elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
+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)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   char buf[PATH_MAX];
+   char *source;
+   char *type_name = NULL;
+   int fd;
 
-   wd->markers_max_num = max;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, NULL);
+
+   Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
+
+   snprintf(buf, sizeof(buf), DEST_ROUTE_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);
+
+   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, _route_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 = wd->src->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;
 #else
    (void) obj;
-   (void) max;
+   (void) type;
+   (void) method;
+   (void) flon;
+   (void) flat;
+   (void) tlon;
+   (void) tlat;
+   return NULL;
 #endif
 }
 
-EAPI Evas_Object *
-elm_map_marker_object_get(const Elm_Map_Marker *marker)
+EAPI void
+elm_map_route_remove(Elm_Map_Route *route)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN_VAL(marker, NULL);
-   return marker->content;
+   EINA_SAFETY_ON_NULL_RETURN(route);
+
+   Path_Waypoint *w;
+   Path_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;
+     }
 #else
-   (void) marker;
-   return NULL;
+   (void) route;
 #endif
 }
 
 EAPI void
-elm_map_marker_update(Elm_Map_Marker *marker)
+elm_map_route_color_set(Elm_Map_Route *route, int r, int g , int b, int a)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(marker);
-   Widget_Data *wd = marker->wd;
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   _marker_update(marker);
+   EINA_SAFETY_ON_NULL_RETURN(route);
+   route->color.r = r;
+   route->color.g = g;
+   route->color.b = b;
+   route->color.a = a;
 #else
-   (void) marker;
+   (void) route;
+   (void) r;
+   (void) g;
+   (void) b;
+   (void) a;
 #endif
 }
 
 EAPI void
-elm_map_bubbles_close(Evas_Object *obj)
+elm_map_route_color_get(const Elm_Map_Route *route, int *r, int *g , int *b, int *a)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   Eina_List *l;
-   Elm_Map_Marker *marker;
-   EINA_LIST_FOREACH(wd->markers, l, marker)
-     {
-        if (marker->bubble) _bubble_free(marker->bubble);
-        marker->bubble = NULL;
-
-        if (marker->group)
-          {
-             if (marker->group->bubble) _bubble_free(marker->group->bubble);
-             marker->group->bubble = NULL;
-          }
-     }
+   EINA_SAFETY_ON_NULL_RETURN(route);
+   if (r) *r = route->color.r;
+   if (g) *g = route->color.g;
+   if (b) *b = route->color.b;
+   if (a) *a = route->color.a;
 #else
-   (void) obj;
+   (void) route;
+   (void) r;
+   (void) g;
+   (void) b;
+   (void) a;
 #endif
 }
 
-EAPI Elm_Map_Group_Class *
-elm_map_group_class_new(Evas_Object *obj)
+EAPI double
+elm_map_route_distance_get(const Elm_Map_Route *route)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
-
-   Elm_Map_Group_Class *clas = ELM_NEW(Elm_Map_Group_Class);
-   clas->wd = wd;
-   clas->zoom_displayed = 0;
-   clas->zoom_grouped = 255;
-   eina_stringshare_replace(&clas->style, "radio");
-
-   wd->group_classes = eina_list_append(wd->group_classes, clas);
-
-   return clas;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(route, 0.0);
+   return route->info.distance;
 #else
-   (void) obj;
-   return NULL;
+   (void) route;
+   return 0.0;
 #endif
 }
 
-EAPI void
-elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style)
+EAPI const char*
+elm_map_route_node_get(const Elm_Map_Route *route)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   eina_stringshare_replace(&clas->style, style);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
+   return route->info.nodes;
 #else
-   (void) clas;
-   (void) style;
+   (void) route;
+   return NULL;
 #endif
 }
 
-EAPI void
-elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get)
+EAPI const char*
+elm_map_route_waypoint_get(const Elm_Map_Route *route)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->func.icon_get = icon_get;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
+   return route->info.waypoints;
 #else
-   (void) clas;
-   (void) icon_get;
+   (void) route;
+   return NULL;
 #endif
 }
 
-EAPI void
-elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data)
+EAPI const char *
+elm_map_name_address_get(const Elm_Map_Name *name)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->data = data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
+   return name->address;
 #else
-   (void) clas;
-   (void) data;
+   (void) name;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom)
+elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->zoom_displayed = zoom;
+   EINA_SAFETY_ON_NULL_RETURN(name);
+   if (lon) *lon = name->lon;
+   if (lat) *lat = name->lat;
 #else
-   (void) clas;
-   (void) zoom;
+   (void) name;
+   (void) lon;
+   (void) lat;
 #endif
 }
 
 EAPI void
-elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom)
+elm_map_name_remove(Elm_Map_Name *name)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->zoom_grouped = zoom;
+   EINA_SAFETY_ON_NULL_RETURN(name);
+   if (name->address)
+     {
+        free(name->address);
+        name->address = NULL;
+     }
+   if (name->handler)
+     {
+        ecore_event_handler_del(name->handler);
+        name->handler = NULL;
+     }
+   if (name->ud.fname)
+     {
+        ecore_file_remove(name->ud.fname);
+        free(name->ud.fname);
+        name->ud.fname = NULL;
+     }
 #else
-   (void) clas;
-   (void) zoom;
+   (void) name;
 #endif
 }
 
 EAPI void
-elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide)
+elm_map_rotate_set(Evas_Object *obj, double degree, Evas_Coord cx, Evas_Coord cy)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN(wd);
-   EINA_SAFETY_ON_NULL_RETURN(clas);
 
-   clas->hide = hide;
+   wd->rotate.d = degree;
+   wd->rotate.cx = cx;
+   wd->rotate.cy = cy;
+
    evas_object_smart_changed(wd->pan_smart);
 #else
    (void) obj;
-   (void) clas;
-   (void) hide;
+   (void) degree;
+   (void) cx;
+   (void) cy;
 #endif
 }
 
-EAPI Elm_Map_Marker_Class *
-elm_map_marker_class_new(Evas_Object *obj)
+EAPI void
+elm_map_rotate_get(const Evas_Object *obj, double *degree, Evas_Coord *cx, Evas_Coord *cy)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
-
-   Elm_Map_Marker_Class *clas = ELM_NEW(Elm_Map_Marker_Class);
-   eina_stringshare_replace(&clas->style, "radio");
+   EINA_SAFETY_ON_NULL_RETURN(wd);
 
-   wd->marker_classes = eina_list_append(wd->marker_classes, clas);
-   return clas;
+   if (degree) *degree = wd->rotate.d;
+   if (cx) *cx = wd->rotate.cx;
+   if (cy) *cy = wd->rotate.cy;
 #else
    (void) obj;
-   return NULL;
+   (void) degree;
+   (void) cx;
+   (void) cy;
 #endif
 }
 
 EAPI void
-elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style)
+elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   eina_stringshare_replace(&clas->style, style);
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   if ((!wd->wheel_disabled) && (disabled))
+     evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
+   else if ((wd->wheel_disabled) && (!disabled))
+     evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
+   wd->wheel_disabled = !!disabled;
 #else
-   (void) clas;
-   (void) style;
+   (void) obj;
+   (void) disabled;
 #endif
 }
 
-EAPI void
-elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get)
+EAPI Eina_Bool
+elm_map_wheel_disabled_get(const Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->func.icon_get = icon_get;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+
+   return wd->wheel_disabled;
 #else
-   (void) clas;
-   (void) icon_get;
+   (void) obj;
+   return EINA_FALSE;
 #endif
 }
 
-EAPI void
-elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get)
+#ifdef ELM_EMAP
+EAPI Evas_Object *
+elm_map_track_add(Evas_Object *obj, EMap_Route *emap)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->func.get = get;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+
+   Evas_Object *route = elm_route_add(obj);
+   elm_route_emap_set(route, emap);
+   wd->track = eina_list_append(wd->track, route);
+
+   return route;
 #else
-   (void) clas;
-   (void) get;
+   (void) obj;
+   (void) emap;
+   return NULL;
 #endif
 }
+#endif
 
 EAPI void
-elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del)
+elm_map_track_remove(Evas_Object *obj, Evas_Object *route)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(clas);
-   clas->func.del = del;
+   ELM_CHECK_WIDTYPE(obj, widtype) ;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN(wd);
+
+   wd->track = eina_list_remove(wd->track, route);
+   evas_object_del(route);
 #else
-   (void) clas;
-   (void) del;
+   (void) obj;
+   (void) route;
 #endif
 }
 
-EAPI const char **
-elm_map_source_names_get(const Evas_Object *obj)
+EAPI Elm_Map_Overlay *
+elm_map_overlay_add(Evas_Object *obj, double lon, double lat)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
    EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   return wd->src_names;
+   Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
+   overlay->wd = wd;
+   overlay->type = ELM_MAP_OVERLAY_TYPE_DEFAULT;
+   overlay->ovl = _overlay_default_new(wd, lon, lat, "radio");
+   _overlay_default_cb_add(overlay->ovl, _overlay_clicked_cb, overlay);
+   overlay->grp = _overlay_group_new(wd);
+   wd->overlays = eina_list_append(wd->overlays, overlay);
+
+   evas_object_smart_changed(wd->pan_smart);
+   return overlay;
 #else
    (void) obj;
+   (void) lon;
+   (void) lat;
    return NULL;
 #endif
 }
 
 EAPI void
-elm_map_source_name_set(Evas_Object *obj, const char *source_name)
+elm_map_overlay_del(Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-
-   Map_Sources_Tab *s;
-   Eina_List *l;
-   int zoom;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   if (wd->src)
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        if (!strcmp(wd->src->name, source_name)) return;
-        if (!wd->src->url_cb) return;
+        _overlay_default_cb_del(overlay->ovl, _overlay_clicked_cb);
+        _overlay_default_free(overlay->ovl);
      }
-
-   _grid_all_clear(wd);
-   EINA_LIST_FOREACH(wd->srcs, l, s)
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
      {
-        if (!strcmp(s->name, source_name))
-          {
-             wd->src = s;
-             break;
-          }
+        _overlay_bubble_cb_del(overlay->ovl);
+        _overlay_bubble_free(overlay->ovl);
      }
-   zoom = wd->zoom;
-   wd->zoom = -1;
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+      _overlay_class_free(overlay->ovl);
 
-   if (wd->src)
+   if (overlay->grp)
      {
-        if (wd->src->zoom_max < zoom)
-          zoom = wd->src->zoom_max;
-        if (wd->src->zoom_min > zoom)
-          zoom = wd->src->zoom_min;
-        if (wd->src->zoom_max < wd->zoom_max) wd->zoom_max = wd->src->zoom_max;
-        if (wd->src->zoom_min > wd->zoom_min) wd->zoom_min = wd->src->zoom_min;
+        _overlay_group_cb_del(overlay->grp);
+        _overlay_group_free(overlay->grp, overlay);
      }
-   _grid_all_create(wd);
-   zoom_do(wd, zoom);
+
+   overlay->wd->overlays = eina_list_remove(overlay->wd->overlays, overlay);
+   evas_object_smart_changed(overlay->wd->pan_smart);
+
+   free(overlay);
 #else
-   (void) obj;
-   (void) source_name;
+   (void) overlay;
 #endif
 }
 
-EAPI const char *
-elm_map_source_name_get(const Evas_Object *obj)
+EAPI Elm_Map_Overlay_Type
+elm_map_overlay_type_get(Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, ELM_MAP_OVERLAY_TYPE_NONE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, ELM_MAP_OVERLAY_TYPE_NONE);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) ELM_MAP_OVERLAY_TYPE_NONE;
 
-   if ((!wd) || (!wd->src)) return NULL;
-   return wd->src->name;
+   return overlay->type;
 #else
-   (void) obj;
-   return NULL;
+   (void) overlay;
+   return OVERLAY_TYPE_NONE;
 #endif
 }
 
 EAPI void
-elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source)
+elm_map_overlay_data_set(Elm_Map_Overlay *overlay, void *data)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   wd->route_source = source;
+   overlay->data = data;
 #else
-   (void) obj;
-   (void) source;
+   (void) overlay;
+   (void) data;
 #endif
 }
 
-EAPI Elm_Map_Route_Sources
-elm_map_route_source_get(const Evas_Object *obj)
+EAPI void *
+elm_map_overlay_data_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ROUTE_SOURCE_YOURS;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ELM_MAP_ROUTE_SOURCE_YOURS);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
 
-   return wd->route_source;
+   return overlay->data;
 #else
-   (void) obj;
-   return ELM_MAP_ROUTE_SOURCE_YOURS;
+   (void) overlay;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_source_zoom_max_set(Evas_Object *obj, int zoom)
+elm_map_overlay_hide_set(Elm_Map_Overlay *overlay, Eina_Bool hide)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-   EINA_SAFETY_ON_NULL_RETURN(wd->src);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   if ((zoom > wd->src->zoom_max) || (zoom < wd->src->zoom_min)) return;
-   wd->zoom_max = zoom;
+   if (overlay->hide == !!hide) return;
+   overlay->hide = hide;
+
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) obj;
-   (void) zoom;
+   (void) overlay;
+   (void) hide;
 #endif
 }
 
-EAPI int
-elm_map_source_zoom_max_get(const Evas_Object *obj)
+EAPI Eina_Bool
+elm_map_overlay_hide_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) 18;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE;
 
-   return wd->zoom_max;
+   return overlay->hide;
 #else
-   (void) obj;
-   return 18;
+   (void) overlay;
+   return EINA_FALSE;
 #endif
 }
 
 EAPI void
-elm_map_source_zoom_min_set(Evas_Object *obj, int zoom)
+elm_map_overlay_displayed_zoom_min_set(Elm_Map_Overlay *overlay, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-   EINA_SAFETY_ON_NULL_RETURN(wd->src);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   if ((zoom > wd->src->zoom_max) || (zoom < wd->src->zoom_min)) return;
-   wd->zoom_min = zoom;
+   overlay->zoom_min = zoom;
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) obj;
+   (void) overlay;
    (void) zoom;
 #endif
 }
 
 EAPI int
-elm_map_source_zoom_min_get(const Evas_Object *obj)
+elm_map_overlay_displayed_zoom_min_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) 0;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, 0);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, 0);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) 0;
 
-   return wd->zoom_min;
+   return overlay->zoom_min;
 #else
-   (void) obj;
+   (void) overlay;
    return 0;
 #endif
 }
 
 EAPI void
-elm_map_user_agent_set(Evas_Object *obj, const char *user_agent)
+elm_map_overlay_paused_set(Elm_Map_Overlay *overlay, Eina_Bool paused)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
-   EINA_SAFETY_ON_NULL_RETURN(user_agent);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   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);
-#else
-   (void) obj;
-   (void) user_agent;
-#endif
-}
-
-EAPI const char *
-elm_map_user_agent_get(const Evas_Object *obj)
-{
-#ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+   if (overlay->paused == !!paused) return;
+   overlay->paused = paused;
 
-   return wd->user_agent;
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) obj;
-   return NULL;
+   (void) overlay;
+   (void) paused;
 #endif
 }
 
-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)
+EAPI Eina_Bool
+elm_map_overlay_paused_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   char buf[PATH_MAX];
-   char *source;
-   char *type_name = NULL;
-   int fd;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src, NULL);
-
-   Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
-
-   snprintf(buf, sizeof(buf), DEST_ROUTE_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);
-
-   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, _route_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 = wd->src->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);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE;
 
-   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;
-#else
-   (void) obj;
-   (void) type;
-   (void) method;
-   (void) flon;
-   (void) flat;
-   (void) tlon;
-   (void) tlat;
-   return NULL;
+   return overlay->paused;
+#else
+   (void) overlay;
+   return EINA_FALSE;
 #endif
 }
 
 EAPI void
-elm_map_route_remove(Elm_Map_Route *route)
+elm_map_overlay_show(Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(route);
-
-   Path_Waypoint *w;
-   Path_Node *n;
-   Evas_Object *p;
-   Ecore_Event_Handler *h;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
 
-   EINA_LIST_FREE(route->path, p)
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        evas_object_del(p);
+        Overlay_Default *ovl = overlay->ovl;
+        elm_map_geo_region_show(overlay->wd->obj, ovl->lon, ovl->lat);
      }
-
-   EINA_LIST_FREE(route->waypoint, w)
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
      {
-        if (w->point) eina_stringshare_del(w->point);
-        free(w);
+        Overlay_Bubble *ovl = overlay->ovl;
+        elm_map_geo_region_show(overlay->wd->obj, ovl->lon, ovl->lat);
      }
-
-   EINA_LIST_FREE(route->nodes, n)
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
      {
-        if (n->pos.address) eina_stringshare_del(n->pos.address);
-        free(n);
+        Overlay_Class *ovl = overlay->ovl;
+        double lon, lat, max_lo, min_lo, max_la, min_la;
+        _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la, &min_la);
+        lon = (max_lo + min_lo) / 2;
+        lat = (max_la + min_la) / 2;
+        elm_map_geo_region_show(overlay->wd->obj, lon, lat);
      }
+   else ERR("Not supported overlay type: %d", overlay->type);
 
-   EINA_LIST_FREE(route->handlers, h)
+   evas_object_smart_changed(overlay->wd->pan_smart);
+#else
+   (void) overlay;
+#endif
+}
+
+EAPI void
+elm_map_overlays_show(Eina_List *overlays)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(overlays);
+   EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(overlays));
+
+   Elm_Map_Overlay *overlay;
+   overlay = eina_list_data_get(overlays);
+
+   Delayed_Data *data = ELM_NEW(Delayed_Data);
+   data->func = _overlays_show;
+   data->wd = overlay->wd;
+   data->overlays = eina_list_clone(overlays);
+   data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
+   evas_object_smart_changed(data->wd->pan_smart);
+#else
+   (void) overlays;
+#endif
+}
+
+EAPI void
+elm_map_overlay_geo_set(Elm_Map_Overlay *overlay, double lon, double lat)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        ecore_event_handler_del(h);
+        Overlay_Default *ovl = overlay->ovl;
+        ovl->lon = lon;
+        ovl->lat = lat;
      }
-
-   if (route->ud.fname)
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
      {
-        ecore_file_remove(route->ud.fname);
-        free(route->ud.fname);
-        route->ud.fname = NULL;
+        Overlay_Bubble *ovl = overlay->ovl;
+        ovl->lon = lon;
+        ovl->lat = lat;
      }
+   else ERR("Not supported overlay type: %d", overlay->type);
+
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) route;
+   (void) overlay;
+   (void) lon;
+   (void) lat;
 #endif
 }
 
 EAPI void
-elm_map_route_color_set(Elm_Map_Route *route, int r, int g , int b, int a)
+elm_map_overlay_geo_get(const Elm_Map_Overlay *overlay, double *lon, double *lat)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(route);
-   route->color.r = r;
-   route->color.g = g;
-   route->color.b = b;
-   route->color.a = a;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+     {
+        const Overlay_Default *ovl = overlay->ovl;
+        if (lon) *lon = ovl->lon;
+        if (lat) *lat = ovl->lat;
+     }
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
+     {
+        const Overlay_Bubble *ovl = overlay->ovl;
+        if (lon) *lon = ovl->lon;
+        if (lat) *lat = ovl->lat;
+     }
+   else ERR("Not supported overlay type: %d", overlay->type);
 #else
-   (void) route;
-   (void) r;
-   (void) g;
-   (void) b;
-   (void) a;
+   (void) overlay;
+   (void) lon;
+   (void) lat;
 #endif
 }
 
 EAPI void
-elm_map_route_color_get(const Elm_Map_Route *route, int *r, int *g , int *b, int *a)
+elm_map_overlay_icon_set(Elm_Map_Overlay *overlay, Evas_Object *icon)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(route);
-   if (r) *r = route->color.r;
-   if (g) *g = route->color.g;
-   if (b) *b = route->color.b;
-   if (a) *a = route->color.a;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(icon);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+      _overlay_default_update(overlay->wd, overlay->ovl, NULL, icon,
+                              NULL, NULL, NULL);
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+      _overlay_class_update(overlay->wd, overlay->ovl, NULL, icon);
+   else ERR("Not supported overlay type: %d", overlay->type);
+
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) route;
-   (void) r;
-   (void) g;
-   (void) b;
-   (void) a;
+   (void) overlay;
+   (void) icon;
 #endif
 }
 
-EAPI double
-elm_map_route_distance_get(const Elm_Map_Route *route)
+EAPI const Evas_Object *
+elm_map_overlay_icon_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN_VAL(route, 0.0);
-   return route->info.distance;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+     {
+        const Overlay_Default *ovl = overlay->ovl;
+        return elm_object_part_content_get(ovl->layout, "elm.icon");
+     }
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+     {
+        const Overlay_Class *ovl = overlay->ovl;
+        return ovl->icon;
+     }
+   else
+     {
+        ERR("Not supported overlay type: %d", overlay->type);
+        return NULL;
+     }
 #else
-   (void) route;
-   return 0.0;
+   (void) overlay;
+   return NULL;
 #endif
 }
 
-EAPI const char*
-elm_map_route_node_get(const Elm_Map_Route *route)
+EAPI void
+elm_map_overlay_content_set(Elm_Map_Overlay *overlay, Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
-   return route->info.nodes;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+      _overlay_default_update(overlay->wd, overlay->ovl, obj, NULL, NULL,
+                                 NULL, NULL);
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+      _overlay_class_update(overlay->wd, overlay->ovl, obj, NULL);
+   else ERR("Not supported overlay type: %d", overlay->type);
+
+   evas_object_smart_changed(overlay->wd->pan_smart);
 #else
-   (void) route;
-   return NULL;
+   (void) overlay;
+   (void) obj;
 #endif
 }
 
-EAPI const char*
-elm_map_route_waypoint_get(const Elm_Map_Route *route)
+EAPI const Evas_Object *
+elm_map_overlay_content_get(const Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
-   return route->info.waypoints;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
+
+   if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
+     {
+        const Overlay_Default *ovl = overlay->ovl;
+        return elm_object_part_content_get(ovl->layout, "elm.icon");
+     }
+   else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
+     {
+        const Overlay_Class *ovl = overlay->ovl;
+        return ovl->icon;
+     }
+   else
+     {
+        ERR("Not supported overlay type: %d", overlay->type);
+        return NULL;
+     }
 #else
-   (void) route;
+   (void) overlay;
    return NULL;
 #endif
 }
 
-EAPI const char *
-elm_map_name_address_get(const Elm_Map_Name *name)
+EAPI void
+elm_map_overlay_get_cb_set(Elm_Map_Overlay *overlay, Elm_Map_Overlay_Get_Cb get_cb, void *data)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
-   return name->address;
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
+   ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
+
+   overlay->cb = get_cb;
+   overlay->cb_data = data;
 #else
-   (void) name;
-   return NULL;
+   (void) overlay;
+   (void) get_cb;
+   (void) data;
 #endif
 }
 
-EAPI void
-elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
+EAPI Elm_Map_Overlay *
+elm_map_overlay_class_add(Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(name);
-   if (lon) *lon = name->lon;
-   if (lat) *lat = name->lat;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
+
+   Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
+   overlay->wd = wd;
+   overlay->type = ELM_MAP_OVERLAY_TYPE_CLASS;
+   overlay->ovl = _overlay_class_new(wd, overlay);
+   overlay->grp = NULL;
+   wd->overlays = eina_list_append(wd->overlays, overlay);
+
+   evas_object_smart_changed(wd->pan_smart);
+   return overlay;
 #else
-   (void) name;
-   (void) lon;
-   (void) lat;
+   (void) obj;
+   return NULL;
 #endif
 }
 
 EAPI void
-elm_map_name_remove(Elm_Map_Name *name)
+elm_map_overlay_class_append(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   EINA_SAFETY_ON_NULL_RETURN(name);
-   if (name->address)
-     {
-        free(name->address);
-        name->address = NULL;
-     }
-   if (name->handler)
+   EINA_SAFETY_ON_NULL_RETURN(group);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(group->wd);
+   ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
+
+   if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT)
      {
-        ecore_event_handler_del(name->handler);
-        name->handler = NULL;
+        ERR("Currently group supports only default overlays");
+        return;
      }
-   if (name->ud.fname)
+
+   Overlay_Class *ovl = group->ovl;
+   if (eina_list_data_find(ovl->members, overlay))
      {
-        ecore_file_remove(name->ud.fname);
-        free(name->ud.fname);
-        name->ud.fname = NULL;
+        ERR("Already added overlay into group");
+        return;
      }
+   ovl->members = eina_list_append(ovl->members, overlay);
+   overlay->grp->clas = group;
+
+  evas_object_smart_changed(group->wd->pan_smart);
 #else
-   (void) name;
+   (void) group;
+   (void) overlay;
 #endif
 }
 
 EAPI void
-elm_map_rotate_set(Evas_Object *obj, double degree, Evas_Coord cx, Evas_Coord cy)
+elm_map_overlay_class_remove(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(group);
+   EINA_SAFETY_ON_NULL_RETURN(overlay);
+   EINA_SAFETY_ON_NULL_RETURN(group->wd);
+   ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
 
-   wd->rotate.d = degree;
-   wd->rotate.cx = cx;
-   wd->rotate.cy = cy;
+    if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT)
+     {
+        ERR("Currently group supports only default overlays");
+        return;
+     }
+   Overlay_Class *ovl = group->ovl;
+   ovl->members = eina_list_remove(ovl->members, overlay);
+   overlay->grp->clas = NULL;
+   _overlay_group_update(group->wd, overlay->grp, NULL);
 
-   evas_object_smart_changed(wd->pan_smart);
+  evas_object_smart_changed(group->wd->pan_smart);
 #else
-   (void) obj;
-   (void) degree;
-   (void) cx;
-   (void) cy;
+   (void) group;
+   (void) overlay;
 #endif
 }
 
 EAPI void
-elm_map_rotate_get(const Evas_Object *obj, double *degree, Evas_Coord *cx, Evas_Coord *cy)
+elm_map_overlay_class_zoom_max_set(Elm_Map_Overlay *group, int zoom)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(group);
+   EINA_SAFETY_ON_NULL_RETURN(group->wd);
+   ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
 
-   if (degree) *degree = wd->rotate.d;
-   if (cx) *cx = wd->rotate.cx;
-   if (cy) *cy = wd->rotate.cy;
+   Overlay_Class *ovl = group->ovl;
+   if (ovl->zoom_max == !!zoom) return;
+   ovl->zoom_max = zoom;
+
+   evas_object_smart_changed(group->wd->pan_smart);
 #else
-   (void) obj;
-   (void) degree;
-   (void) cx;
-   (void) cy;
+   (void) group;
+   (void) zoom;
 #endif
 }
 
-EAPI void
-elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+EAPI int
+elm_map_overlay_class_zoom_max_get(const Elm_Map_Overlay *group)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype);
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(group, OVERLAY_CLASS_ZOOM_MAX);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(group->wd, OVERLAY_CLASS_ZOOM_MAX);
+   ELM_CHECK_WIDTYPE(group->wd->obj, widtype) OVERLAY_CLASS_ZOOM_MAX;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(group->type == ELM_MAP_OVERLAY_TYPE_CLASS, OVERLAY_CLASS_ZOOM_MAX);
 
-   if ((!wd->wheel_disabled) && (disabled))
-     evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
-   else if ((wd->wheel_disabled) && (!disabled))
-     evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
-   wd->wheel_disabled = !!disabled;
+   const Overlay_Class *ovl = group->ovl;
+   return ovl->zoom_max;
 #else
-   (void) obj;
-   (void) disabled;
+   (void) group;
+   return OVERLAY_CLASS_ZOOM_MAX;
 #endif
 }
 
-EAPI Eina_Bool
-elm_map_wheel_disabled_get(const Evas_Object *obj)
+EAPI Elm_Map_Overlay *
+elm_map_overlay_bubble_add(Evas_Object *obj)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
 
-   return wd->wheel_disabled;
+   Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
+   overlay->wd = wd;
+   overlay->type = ELM_MAP_OVERLAY_TYPE_BUBBLE;
+   overlay->ovl =  _overlay_bubble_new(wd);
+   _overlay_bubble_cb_add(overlay->ovl, overlay);
+   overlay->grp = _overlay_group_new(wd);
+   wd->overlays = eina_list_append(wd->overlays, overlay);
+
+   evas_object_smart_changed(wd->pan_smart);
+   return overlay;
 #else
    (void) obj;
-   return EINA_FALSE;
+   return NULL;
 #endif
 }
 
-#ifdef ELM_EMAP
-EAPI Evas_Object *
-elm_map_track_add(Evas_Object *obj, EMap_Route *emap)
+EAPI void
+elm_map_overlay_bubble_follow(Elm_Map_Overlay *bubble, Elm_Map_Overlay *parent)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   EINA_SAFETY_ON_NULL_RETURN(parent);
+   ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
 
-   Evas_Object *route = elm_route_add(obj);
-   elm_route_emap_set(route, emap);
-   wd->track = eina_list_append(wd->track, route);
+   Overlay_Bubble *ovl = bubble->ovl;
+   Evas_Object *pobj = _overlay_obj_get(parent);
+   if (!pobj) return;
 
-   return route;
+   if (ovl->pobj)
+     {
+        evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_HIDE,
+                                            _overlay_bubble_hide_cb, ovl);
+        evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_SHOW,
+                                            _overlay_bubble_chase_cb, ovl);
+        evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_MOVE,
+                                            _overlay_bubble_chase_cb, ovl);
+     }
+
+   ovl->pobj = pobj;
+   evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_HIDE,
+                                  _overlay_bubble_hide_cb, ovl);
+   evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_SHOW,
+                                  _overlay_bubble_chase_cb, ovl);
+   evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_MOVE,
+                                  _overlay_bubble_chase_cb, ovl);
+
+   _overlay_bubble_chase(ovl);
+   evas_object_smart_changed(bubble->wd->pan_smart);
 #else
-   (void) obj;
-   (void) emap;
-   return NULL;
+   (void) bubble;
+   (void) parent;
 #endif
 }
+
+EAPI void
+elm_map_overlay_bubble_content_append(Elm_Map_Overlay *bubble, Evas_Object *content)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   EINA_SAFETY_ON_NULL_RETURN(content);
+   ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
+
+   Overlay_Bubble *bb = bubble->ovl;
+   elm_box_pack_end(bb->bx, content);
+
+   evas_object_smart_changed(bubble->wd->pan_smart);
+#else
+   (void) bubble;
+   (void) content;
 #endif
+}
 
 EAPI void
-elm_map_track_remove(Evas_Object *obj, Evas_Object *route)
+elm_map_overlay_bubble_content_clear(Elm_Map_Overlay *bubble)
 {
 #ifdef HAVE_ELEMENTARY_ECORE_CON
-   ELM_CHECK_WIDTYPE(obj, widtype) ;
-   Widget_Data *wd = elm_widget_data_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(wd);
+   EINA_SAFETY_ON_NULL_RETURN(bubble);
+   ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
+   EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
 
-   wd->track = eina_list_remove(wd->track, route);
-   evas_object_del(route);
+   Overlay_Bubble *bb = bubble->ovl;
+   elm_box_clear(bb->bx);
+
+   evas_object_smart_changed(bubble->wd->pan_smart);
 #else
-   (void) obj;
-   (void) route;
+   (void) bubble;
 #endif
 }
index e3d3540..c2cc612 100644 (file)
@@ -81,9 +81,9 @@
  */
 typedef enum
 {
-   ELM_MAP_ZOOM_MODE_MANUAL, /**< Zoom controlled manually by elm_map_zoom_set(). It's set by default. */
-   ELM_MAP_ZOOM_MODE_AUTO_FIT, /**< Zoom until map fits inside the scroll frame with no pixels outside this area. */
-   ELM_MAP_ZOOM_MODE_AUTO_FILL, /**< Zoom until map fills scroll, ensuring no pixels are left unfilled. */
+   ELM_MAP_ZOOM_MODE_MANUAL,      /**< Zoom controlled manually by elm_map_zoom_set(). It's set by default. */
+   ELM_MAP_ZOOM_MODE_AUTO_FIT,    /**< Zoom until map fits inside the scroll frame with no pixels outside this area. */
+   ELM_MAP_ZOOM_MODE_AUTO_FILL,   /**< Zoom until map fills scroll, ensuring no pixels are left unfilled. */
    ELM_MAP_ZOOM_MODE_LAST
 } Elm_Map_Zoom_Mode;
 
@@ -98,9 +98,9 @@ typedef enum
  */
 typedef enum
 {
-   ELM_MAP_ROUTE_SOURCE_YOURS, /**< Routing service http://www.yournavigation.org/ . Set by default.*/
-   ELM_MAP_ROUTE_SOURCE_MONAV, /**< MoNav offers exact routing without heuristic assumptions. Its routing core is based on Contraction Hierarchies. It's not working with Map yet. */
-   ELM_MAP_ROUTE_SOURCE_ORS, /**< Open Route Service: http://www.openrouteservice.org/ . It's not working with Map yet. */
+   ELM_MAP_ROUTE_SOURCE_YOURS,   /**< Routing service http://www.yournavigation.org/ . Set by default.*/
+   ELM_MAP_ROUTE_SOURCE_MONAV,   /**< MoNav offers exact routing without heuristic assumptions. Its routing core is based on Contraction Hierarchies. It's not working with Map yet. */
+   ELM_MAP_ROUTE_SOURCE_ORS,     /**< Open Route Service: http://www.openrouteservice.org/ . It's not working with Map yet. */
    ELM_MAP_ROUTE_SOURCE_LAST
 } Elm_Map_Route_Sources;
 
@@ -119,9 +119,9 @@ typedef enum
  */
 typedef enum
 {
-   ELM_MAP_ROUTE_TYPE_MOTOCAR, /**< Route should consider an automobile will be used. */
-   ELM_MAP_ROUTE_TYPE_BICYCLE, /**< Route should consider a bicycle will be used by the user. */
-   ELM_MAP_ROUTE_TYPE_FOOT, /**< Route should consider user will be walking. */
+   ELM_MAP_ROUTE_TYPE_MOTOCAR,   /**< Route should consider an automobile will be used. */
+   ELM_MAP_ROUTE_TYPE_BICYCLE,   /**< Route should consider a bicycle will be used by the user. */
+   ELM_MAP_ROUTE_TYPE_FOOT,      /**< Route should consider user will be walking. */
    ELM_MAP_ROUTE_TYPE_LAST
 } Elm_Map_Route_Type;
 
@@ -134,11 +134,31 @@ typedef enum
  */
 typedef enum
 {
-   ELM_MAP_ROUTE_METHOD_FASTEST, /**< Route should prioritize time. */
+   ELM_MAP_ROUTE_METHOD_FASTEST,  /**< Route should prioritize time. */
    ELM_MAP_ROUTE_METHOD_SHORTEST, /**< Route should prioritized distance. */
    ELM_MAP_ROUTE_METHOD_LAST
 } Elm_Map_Route_Method;
 
+/**
+ * Set overlay type to be used. This type is resolved
+ * when the overlay is created.
+ * You can get this value by elm_map_overlay_type_get().
+ *
+ * @see elm_map_overlay_type_get()
+ * @see elm_map_overlay_add()
+ * @see elm_map_overlay_class_add()
+ * @see elm_map_overlay_bubble_add()
+ *
+ * @ingroup Map
+ */
+typedef enum _Elm_Map_Overlay_Type
+{
+   ELM_MAP_OVERLAY_TYPE_NONE = 0,
+   ELM_MAP_OVERLAY_TYPE_DEFAULT,
+   ELM_MAP_OVERLAY_TYPE_CLASS,
+   ELM_MAP_OVERLAY_TYPE_BUBBLE
+} Elm_Map_Overlay_Type;
+
 typedef enum
 {
    ELM_MAP_NAME_METHOD_SEARCH,
@@ -146,27 +166,29 @@ typedef enum
    ELM_MAP_NAME_METHOD_LAST
 } Elm_Map_Name_Method;
 
-typedef struct _Elm_Map_Marker       Elm_Map_Marker; /**< A marker to be shown in a specific point of the map. Can be created with elm_map_marker_add() and deleted with elm_map_marker_remove(). */
+typedef struct _Elm_Map_Marker       Elm_Map_Marker;       /**< A marker to be shown in a specific point of the map. Can be created with elm_map_marker_add() and deleted with elm_map_marker_remove(). */
 typedef struct _Elm_Map_Marker_Class Elm_Map_Marker_Class; /**< Each marker must be associated to a class. It's required to add a mark. The class defines the style of the marker when a marker is displayed alone (not grouped). A new class can be created with elm_map_marker_class_new(). */
-typedef struct _Elm_Map_Group_Class  Elm_Map_Group_Class; /**< Each marker must be associated to a group class. It's required to add a mark. The group class defines the style of the marker when a marker is grouped to other markers. Markers with the same group are grouped if they are close. A new group class can be created with elm_map_marker_group_class_new(). */
-typedef struct _Elm_Map_Route        Elm_Map_Route; /**< A route to be shown in the map. Can be created with elm_map_route_add() and deleted with elm_map_route_remove(). */
-typedef struct _Elm_Map_Name         Elm_Map_Name; /**< A handle for specific coordinates. */
-typedef struct _Elm_Map_Track        Elm_Map_Track;
-
-typedef Evas_Object               *(*ElmMapMarkerGetFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Bubble content fetching class function for marker classes. When the user click on a marker, a bubble is displayed with a content. */
-typedef void                       (*ElmMapMarkerDelFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o); /**< Function to delete bubble content for marker classes. */
-typedef Evas_Object               *(*ElmMapMarkerIconGetFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Icon fetching class function for marker classes. */
-typedef Evas_Object               *(*ElmMapGroupIconGetFunc)(Evas_Object *obj, void *data); /**< Icon fetching class function for markers group classes. */
-
-typedef char                      *(*ElmMapModuleSourceFunc)(void);
-typedef int                        (*ElmMapModuleZoomMinFunc)(void);
-typedef int                        (*ElmMapModuleZoomMaxFunc)(void);
-typedef char                      *(*ElmMapModuleUrlFunc)(Evas_Object *obj, int x, int y, int zoom);
-typedef int                        (*ElmMapModuleRouteSourceFunc)(void);
-typedef char                      *(*ElmMapModuleRouteUrlFunc)(Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat);
-typedef char                      *(*ElmMapModuleNameUrlFunc)(Evas_Object *obj, int method, char *name, double lon, double lat);
-typedef Eina_Bool                  (*ElmMapModuleGeoIntoCoordFunc)(const Evas_Object *obj, int zoom, double lon, double lat, int size, int *x, int *y);
-typedef Eina_Bool                  (*ElmMapModuleCoordIntoGeoFunc)(const Evas_Object *obj, int zoom, int x, int y, int size, double *lon, double *lat);
+typedef struct _Elm_Map_Group_Class  Elm_Map_Group_Class;  /**< Each marker must be associated to a group class. It's required to add a mark. The group class defines the style of the marker when a marker is grouped to other markers. Markers with the same group are grouped if they are close. A new group class can be created with elm_map_marker_group_class_new(). */
+typedef struct _Elm_Map_Route        Elm_Map_Route;        /**< A route to be shown in the map. Can be created with elm_map_route_add() and deleted with elm_map_route_remove(). */
+typedef struct _Elm_Map_Name         Elm_Map_Name;         /**< A handle for specific coordinates. */
+typedef struct _Elm_Map_Overlay      Elm_Map_Overlay;      /**< A overlay to be shown in a specific point of the map. This can be created by elm_map_overlay_add() and similar functions and deleted by elm_map_overlay_del(). */
+
+typedef Evas_Object               *(*Elm_Map_Marker_Get_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Bubble content fetching class function for marker classes. When the user click on a marker, a bubble is displayed with a content. */
+typedef void                       (*Elm_Map_Marker_Del_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o); /**< Function to delete bubble content for marker classes. */
+typedef Evas_Object               *(*Elm_Map_Marker_Icon_Get_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Icon fetching class function for marker classes. */
+typedef Evas_Object               *(*Elm_Map_Group_Icon_Get_Func)(Evas_Object *obj, void *data); /**< Icon fetching class function for markers group classes. */
+
+typedef void                       (*Elm_Map_Overlay_Get_Cb)(void *data, Evas_Object *map, Elm_Map_Overlay *overlay);   /**< Get callback function for the overlay. */
+
+typedef char                      *(*Elm_Map_Module_Source_Func)(void);
+typedef int                        (*Elm_Map_Module_Zoom_Min_Func)(void);
+typedef int                        (*Elm_Map_Module_Zoom_Max_Func)(void);
+typedef char                      *(*Elm_Map_Module_Url_Func)(Evas_Object *obj, int x, int y, int zoom);
+typedef int                        (*Elm_Map_Module_Route_Source_Func)(void);
+typedef char                      *(*Elm_Map_Module_Route_Url_Func)(Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+typedef char                      *(*Elm_Map_Module_Name_Url_Func)(Evas_Object *obj, int method, char *name, double lon, double lat);
+typedef Eina_Bool                  (*Elm_Map_Module_Geo_Into_Coord_Func)(const Evas_Object *obj, int zoom, double lon, double lat, int size, int *x, int *y);
+typedef Eina_Bool                  (*Elm_Map_Module_Coord_Into_Geo_Func)(const Evas_Object *obj, int zoom, int x, int y, int size, double *lon, double *lat);
 
 /**
  * Add a new map widget to the given parent Elementary (container) object.
@@ -345,7 +367,7 @@ EAPI void                  elm_map_paused_set(Evas_Object *obj, Eina_Bool paused
  *
  * @param obj The map object.
  * @return @c EINA_TRUE means map is pause. @c EINA_FALSE indicates
- * it is not. If @p obj is @c NULL, @c EINA_FALSE is returned.
+ * it is not.
  *
  * This gets the current paused state for the map object.
  *
@@ -389,7 +411,7 @@ EAPI void                  elm_map_paused_markers_set(Evas_Object *obj, Eina_Boo
  *
  * @param obj The map object.
  * @return @c EINA_TRUE means map @b won't display markers or @c EINA_FALSE
- * indicates it will. If @p obj is @c NULL, @c EINA_FALSE is returned.
+ * indicates it will.
  *
  * This gets the current markers paused state for the map object.
  *
@@ -661,12 +683,12 @@ EAPI void                  elm_map_marker_show(Elm_Map_Marker *marker);
 EAPI void                  elm_map_markers_list_show(Eina_List *markers);
 
 /**
- * Get the Evas object returned by the ElmMapMarkerGetFunc callback
+ * Get the Evas object returned by the Elm_Map_Marker_Get_Func callback
  *
  * @param marker The marker which content should be returned.
  * @return Return the evas object if it exists, else @c NULL.
  *
- * To set callback function #ElmMapMarkerGetFunc for the marker class,
+ * To set callback function #Elm_Map_Marker_Get_Func for the marker class,
  * elm_map_marker_class_get_cb_set() should be used.
  *
  * This content is what will be inside the bubble that will be displayed
@@ -691,8 +713,8 @@ EAPI Evas_Object          *elm_map_marker_object_get(const Elm_Map_Marker *marke
  * @param marker The marker to be updated.
  *
  * If a content is set to this marker, it will call function to delete it,
- * #ElmMapMarkerDelFunc, and then will fetch the content again with
- * #ElmMapMarkerGetFunc.
+ * #Elm_Map_Marker_Del_Func, and then will fetch the content again with
+ * #Elm_Map_Marker_Get_Func.
  *
  * These functions are set for the marker class with
  * elm_map_marker_class_get_cb_set() and elm_map_marker_class_del_cb_set().
@@ -706,7 +728,7 @@ EAPI void                  elm_map_marker_update(Elm_Map_Marker *marker);
  *
  * @param obj The map object.
  *
- * A bubble is displayed with a content fetched with #ElmMapMarkerGetFunc
+ * A bubble is displayed with a content fetched with #Elm_Map_Marker_Get_Func
  * when the user clicks on a marker.
  *
  * This functions is set for the marker class with
@@ -741,7 +763,7 @@ EAPI void                  elm_map_bubbles_close(Evas_Object *obj);
  *   elm_map_group_class_zoom_grouped_set().
  * - visibility - set if markers will be visible or not, set with
  *   elm_map_group_class_hide_set().
- * - #ElmMapGroupIconGetFunc - used to fetch icon for markers group classes.
+ * - #Elm_Map_Group_Icon_Get_Func - used to fetch icon for markers group classes.
  *   It can be set using elm_map_group_class_icon_cb_set().
  *
  * @see elm_map_marker_add()
@@ -791,7 +813,7 @@ EAPI void                  elm_map_group_class_style_set(Elm_Map_Group_Class *cl
  *
  * @ingroup Map
  */
-EAPI void                  elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get);
+EAPI void                  elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, Elm_Map_Group_Icon_Get_Func icon_get);
 
 /**
  * Set the data associated to the group class.
@@ -877,11 +899,11 @@ EAPI void                  elm_map_group_class_hide_set(Evas_Object *obj, Elm_Ma
  *
  * Some properties and functions can be set by class, as:
  * - style, with elm_map_marker_class_style_set()
- * - #ElmMapMarkerIconGetFunc - used to fetch icon for markers classes.
+ * - #Elm_Map_Marker_Icon_Get_Func - used to fetch icon for markers classes.
  *   It can be set using elm_map_marker_class_icon_cb_set().
- * - #ElmMapMarkerGetFunc - used to fetch bubble content for marker classes.
+ * - #Elm_Map_Marker_Get_Func - used to fetch bubble content for marker classes.
  *   Set using elm_map_marker_class_get_cb_set().
- * - #ElmMapMarkerDelFunc - used to delete bubble content for marker classes.
+ * - #Elm_Map_Marker_Del_Func - used to delete bubble content for marker classes.
  *   Set using elm_map_marker_class_del_cb_set().
  *
  * @see elm_map_marker_add()
@@ -929,7 +951,7 @@ EAPI void                  elm_map_marker_class_style_set(Elm_Map_Marker_Class *
  *
  * @ingroup Map
  */
-EAPI void                  elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get);
+EAPI void                  elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Icon_Get_Func icon_get);
 
 /**
  * Set the bubble content callback function of a marker class.
@@ -950,7 +972,7 @@ EAPI void                  elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class
  *
  * @ingroup Map
  */
-EAPI void                  elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get);
+EAPI void                  elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Get_Func get);
 
 /**
  * Set the callback function used to delete bubble content of a marker class.
@@ -976,7 +998,7 @@ EAPI void                  elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class
  *
  * @ingroup Map
  */
-EAPI void                  elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del);
+EAPI void                  elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Del_Func del);
 
 /**
  * Get the list of available sources.
@@ -1375,7 +1397,7 @@ EAPI void                  elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Boo
  *
  * @param obj The map object.
  * @return @c EINA_TRUE means map is disabled. @c EINA_FALSE indicates
- * it is enabled. If @p obj is @c NULL, @c EINA_FALSE is returned.
+ * it is enabled.
  *
  * Mouse wheel can be used for the user to zoom in or zoom out the map.
  *
@@ -1411,5 +1433,495 @@ EAPI Evas_Object          *elm_map_track_add(Evas_Object *obj, EMap_Route *emap)
 EAPI void                  elm_map_track_remove(Evas_Object *obj, Evas_Object *route);
 
 /**
+ * Add a new overlay to the map object. This overlay has a default type.
+ *
+ * @param obj The map object to add a new overlay.
+ * @param lon The longitude of the overlay.
+ * @param lat The latitude of the overlay.
+ * @return The created overlay or @c NULL upon failure.
+ *
+ * A overlay will be created and shown in a specific point of the map, defined
+ * by @p lon and @p lat.
+ *
+ * The created overlay has a default style layout before content or
+ * icon is set.
+ * If content or icon is set, those are displayed instead of default style
+ * layout.
+ * You can set by using elm_map_overlay_content_set() or
+ * elm_map_overlay_icon_set(). If NULL is set, default style
+ * is shown again.
+ *
+ * Overlay created with this method can be deleted by elm_map_overlay_del().
+ *
+ * @see elm_map_overlay_del()
+ * @see elm_map_overlay_class_add()
+ * @see elm_map_overlay_bubble_add()
+ * @see elm_map_overlay_content_set()
+ * @see elm_map_overlay_icon_set()
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Overlay *     elm_map_overlay_add(Evas_Object *obj, double lon, double lat);
+
+/**
+ * Delete a overlay from the map. This function can delete all types
+ * of overlays.
+ *
+ * @param overlay The overlay to be deleted.
+ *
+ * @see elm_map_overlay_add()
+ * @see elm_map_overlay_class_add()
+ * @see elm_map_overlay_bubble_add()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_del(Elm_Map_Overlay *overlay);
+
+/**
+ * Get the overlay type.
+ *
+ * @param overlay The overlay to return type.
+ * @return Return the overlay type.
+ *
+ * This type is resolved when the overlay is created.
+ *
+ * @see elm_map_overlay_add()
+ * @see elm_map_overlay_class_add()
+ * @see elm_map_overlay_bubble_add()
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Overlay_Type  elm_map_overlay_type_get(Elm_Map_Overlay *overlay);
+
+ /**
+ * Set a pointer of user data for a overlay.
+ *
+ * @param overlay The overlay to own the user data.
+ * @param data A pointer of user data
+ *
+ * @see elm_map_overlay_data_get()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_data_set(Elm_Map_Overlay *overlay, void *data);
+
+/**
+ * Get the user data stored on a overlay.
+ *
+ * @param overlay The overlay to return the user data.
+ * @return A pointer to data stored using elm_map_overlay_data_set(),
+ *         or @c NULL, if none has been set.
+ *
+ * @see elm_map_overlay_data_set()
+ *
+ * @ingroup Map
+ */
+EAPI void *                elm_map_overlay_data_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Set if the overlay is hidden or not.
+ *
+ * @param overlay The overlay to be hidden.
+ * @param hide Use @c EINA_TRUE to hide the overlay or @c EINA_FALSE to show.
+ *
+ * @see elm_map_overlay_hide_get().
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_hide_set(Elm_Map_Overlay *overlay, Eina_Bool hide);
+
+/**
+ * Get a value whether the overlay is hidden or not.
+ *
+ * @param overlay The overlay to return the hidden state.
+ * @return @c EINA_TRUE means the overlay is hidden. @c EINA_FALSE indicates
+ * it is not.
+ *
+ * This gets the current hidden state for the overlay.
+ *
+ * @see elm_map_overlay_hide_set().
+ *
+ * @ingroup Map
+ */
+EAPI Eina_Bool             elm_map_overlay_hide_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Set the minimum zoom from where the overlay is displayed.
+ *
+ * @param overlay The overlay to be set the minimum zoom.
+ * @param zoom The minimum zoom.
+ *
+ * The overlay only will be displayed when the map is displayed at @p zoom
+ * or bigger.
+ *
+ * @see elm_map_overlay_displayed_zoom_min_get().
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_displayed_zoom_min_set(Elm_Map_Overlay *overlay, int zoom);
+
+/**
+ * Get the minimum zoom from where the overlay is displayed.
+ *
+ * @param overlay The overlay to return the minimum zoom.
+ * @return zoom The minimum zoom.
+ *
+ * @see elm_map_overlay_displayed_zoom_min_set().
+ *
+ * @ingroup Map
+ */
+EAPI int                   elm_map_overlay_displayed_zoom_min_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Pause or unpause the overlay.
+ *
+ * @param overlay The overlay to be paused.
+ * @param paused Use @c EINA_TRUE to pause the @p overlay or @c EINA_FALSE
+ * to unpause it.
+ *
+ * This sets the paused state to on (@c EINA_TRUE) or off (@c EINA_FALSE)
+ * for the overlay.
+ *
+ * The default is off.
+ *
+ * This will stop moving the overlay coordinates instantly.
+ * even if map being scrolled or zoomed.
+ *
+ * @see elm_map_overlay_paused_get()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_paused_set(Elm_Map_Overlay *overlay, Eina_Bool paused);
+
+/**
+ * Get a value whether the overlay is paused or not.
+ *
+ * @param overlay The overlay to return paused state.
+ * @return @c EINA_TRUE means overlay is paused. @c EINA_FALSE indicates
+ * it is not.
+ *
+ * This gets the current paused state for the overlay.
+ *
+ * @see elm_map_overlay_paused_set().
+ *
+ * @ingroup Map
+ */
+EAPI Eina_Bool             elm_map_overlay_paused_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Set the content object of the overlay.
+ *
+ * @param overlay The overlay to be set the content.
+ * @param obj The evas object will be used to display the overlay.
+ *
+ * Only default and class type overlay support this function.
+ *
+ * The content should be resized or set size hints before set to the overlay.
+ * <b> Do not modify this object</b> (move, show, hide, del, etc.),
+ * after set.
+ * You can only resize this.
+ *
+ * This content is what will be inside the overlay that will be displayed.
+ * If a content is set, icon and default style layout are no more used before
+ * the content is deleted.
+ *
+ * If @p obj is @c NULL, content inside the overlay is deleted.
+ *
+ * @see elm_map_overlay_content_get().
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_content_set(Elm_Map_Overlay *overlay, Evas_Object *obj);
+
+/**
+ * Get the content object.
+ *
+ * @param overlay The overlay to return the content.
+ * @return Return the evas object if it exists, else @c NULL.
+ *
+ * Only default and class type overlay support this function.
+ *
+ * Returned content is what being inside the overlay that being displayed.
+ *
+ * <b> Do not modify this object</b> (move, show, hide, del, etc.).
+ * You can only resize this.
+ *
+ * The content can be set by elm_map_overlay_content_set().
+ *
+ * @see elm_map_overlay_content_set().
+ *
+ * @ingroup Map
+ */
+EAPI const Evas_Object *   elm_map_overlay_content_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Set a icon of the overlay.
+ *
+ * @param overlay The overlay to be set the icon.
+ * @param icon The icon will be used to display the overlay.
+ *
+ * Only default and class type overlay support this function.
+ *
+ * <b> Do not modify this object</b> (move, show, hide, resize, del, etc.),
+ * after set.
+ *
+ * If icon is set, default style layout will not be used.
+ *
+ * If @p icon is @c NULL, icon inside the overlay will be deleted.
+ *
+ * @see elm_map_overlay_icon_get().
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_icon_set(Elm_Map_Overlay *overlay, Evas_Object *icon);
+
+/**
+ * Get the icon object.
+ *
+ * @param overlay The overlay to return the icon.
+ * @return Return the icon object if it exists, else @c NULL.
+ *
+ * Only default and class type overlay support this function.
+ *
+ * Returned icon is what being inside the overlay that being displayed.
+ *
+ * <b> Do not modify this icon </b> (move, show, hide, resize, del, etc.).
+ *
+ * The icon can be set by elm_map_overlay_icon_set().
+ *
+ * @see elm_map_overlay_icon_set().
+ *
+ * @ingroup Map
+ */
+EAPI const Evas_Object *   elm_map_overlay_icon_get(const Elm_Map_Overlay *overlay);
+
+/**
+ * Set the geographic coordinates of the overlay.
+ *
+ * @param overlay The overlay to be set geographic coordinates.
+ * @param lon Longitude to be set.
+ * @param lat Latitude to be set.
+ *
+ * Only default and bubble type overlay support this function.
+ *
+ * This sets the center coordinates of the overlay. It can be
+ * get by elm_map_overlay_geo_get().
+ *
+ * @see elm_map_overlay_geo_get()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_geo_set(Elm_Map_Overlay *overlay, double lon, double lat);
+
+/**
+ * Get the geographic coordinates of the overlay.
+ *
+ * @param overlay The overlay to return geographic coordinates.
+ * @param lon Pointer to store longitude.
+ * @param lat Pointer to store latitude.
+ *
+ * Only default and bubble type overlay support this function.
+ *
+ * This returns the center coordinates of the overlay. It can be
+ * set by elm_map_overlay_geo_set().
+ *
+ * @see elm_map_overlay_geo_set()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_geo_get(const Elm_Map_Overlay *overlay, double *lon, double *lat);
+
+/**
+ * Show the given overlay at the center of the map, immediately.
+ *
+ * @param overlay The overlay to be center at.
+ *
+ * This causes map to @b redraw its viewport's contents to the
+ * region containing the given @p overlay's coordinates, that will be
+ * moved to the center of the map.
+ *
+ * @see elm_map_overlays_show() if more than one overlay need to be displayed.
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_show(Elm_Map_Overlay *overlay);
+
+/**
+ * Move and zoom the map to display a list of overlays.
+ *
+ * @param overlays A list of #Elm_Map_Overlay handles.
+ *
+ * The map will be centered on the center point of the overlays in the list.
+ * Then the map will be zoomed in order to fit the overlays using the maximum
+ * zoom which allows display of all the overlays.
+ *
+ * @warning All the overlays should belong to the same map object.
+ *
+ * @see elm_map_overlay_show() to show a single overlay.
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlays_show(Eina_List *overlays);
+
+/**
+ * Set the get callback function of the overlay.
+ *
+ * @param overlay The overlay to own the get callback function.
+ * @param get_cb The callback function.
+ *
+ * You can delete this callback function by setting @c NULL.
+ *
+ * @ingroup Map
+ */
+EAPI void elm_map_overlay_get_cb_set(Elm_Map_Overlay *overlay, Elm_Map_Overlay_Get_Cb get_cb, void *data);
+
+
+/**
+ * Add a new class overlay to the map object.
+ * This overlay has a class type.
+ *
+ * @param obj The map object to add a new overlay.
+ * @return The created overlay or @c NULL upon failure.
+ *
+ * This overlay is not shown before overlay members are appended.
+ * if overlay members in the same class are close, group overlays
+ * are created. If they are far away, group overlays are hidden.
+ * When group overlays are shown, they have default style layouts at first.
+ *
+ * You can changed the state (hidden, paused, etc.) or set the content
+ * or icon of the group overlays.
+ * Also these changes have a influence on the overlays in the same class
+ * even if each overlay is alone and is not grouped.
+ *
+ * @see elm_map_overlay_del()
+ * @see elm_map_overlay_add()
+ * @see elm_map_overlay_bubble_add()
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Overlay *     elm_map_overlay_class_add(Evas_Object *obj);
+
+/**
+ * Add a new overlay member to the class overlay.
+ *
+ * @param clas The class overlay to add a new overlay.
+ * @param overlay The overlay to be added to the class overlay.
+ *
+ * @see elm_map_overlay_class_remove()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_class_append(Elm_Map_Overlay *clas, Elm_Map_Overlay *overlay);
+
+/**
+ * Remove a overlay from the class.
+ *
+ * @param clas The class overlay to delete the overlay.
+ * @param overlay The overlay to be deleted from the class overlay.
+ *
+ * @see elm_map_overlay_class_append()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_class_remove(Elm_Map_Overlay *clas, Elm_Map_Overlay *overlay);
+
+/**
+ * Set the maximum zoom from where the overlay members in the class can be
+ * grouped.
+ *
+ * @param clas The overlay class has overlay members.
+ * @param zoom The maximum zoom.
+ *
+ * Overlay members in the class only will be grouped when the map
+ * is displayed at less than @p zoom.
+ *
+ * @see elm_map_overlay_class_zoom_max_get().
+ *
+ * @ingroup Map
+ */
+EAPI
+EAPI void                  elm_map_overlay_class_zoom_max_set(Elm_Map_Overlay *clas, int zoom);
+
+/**
+ * Get the zoom from where the overlay members in the class are no more grouped.
+ *
+ * @param clas The overlay class has overlay members.
+ *
+ * @return The maximum zoom.
+ *
+ * @see elm_map_overlay_class_zoom_max_set().
+ *
+ * @ingroup Map
+ */
+EAPI int                   elm_map_overlay_class_zoom_max_get(const Elm_Map_Overlay *clas);
+
+/**
+ * Add a new bubble overlay to the map object.
+ * This overlay has a bubble type.
+ *
+ * @param obj The map object to add a new overlay.
+ * @return The created overlay or @c NULL upon failure.
+ *
+ * A bubble will not be displayed before geogrphic coordinates are set or
+ * any other overlays are followed.
+ *
+ * This overlay has a bubble style layout and icon or content can not
+ * be set.
+ *
+ * Overlay created with this method can be deleted with elm_map_overlay_del().
+ *
+ * @see elm_map_overlay_del()
+ * @see elm_map_overlay_add()
+ * @see elm_map_overlay_class_add()
+ * @see elm_map_overlay_geo_set()
+ * @see elm_map_overlay_bubble_follow()
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Overlay *     elm_map_overlay_bubble_add(Evas_Object *obj);
+
+/**
+ * Follow a other overlay.
+ *
+ * @param bubble The bubble overlay to follow a parent overlay.
+ * @param parent The parent overlay to be followed by the bubble overlay.
+ *
+ * Bubble overlay will follow the parent overlay's movement (hide, show, move).
+ *
+ * @see elm_map_overlay_bubble_add()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_bubble_follow(Elm_Map_Overlay *bubble, Elm_Map_Overlay *parent);
+
+/**
+ * Add a content object to the bubble overlay.
+ *
+ * @param bubble The bubble overlay to add a content.
+ * @param content The content to be added to the bubble overlay.
+ *
+ * Added contents will be displayed inside the bubble overlay.
+ *
+ * @see elm_map_overlay_bubble_content_clear()
+ *
+ * @ingroup Map
+ */
+EAPI void                  elm_map_overlay_bubble_content_append(Elm_Map_Overlay *bubble, Evas_Object *content);
+
+/**
+ * Clear all contents inside the bubble overlay.
+ *
+ * @param bubble The bubble overlay to clear the contents.
+ *
+ * This will delete all contents inside the bubble overlay.
+ *
+ * @see elm_map_overlay_bubble_content_append()
+ *
+ * @ingroup Map
+ */
+
+EAPI void                  elm_map_overlay_bubble_content_clear(Elm_Map_Overlay *bubble);
+
+/**
  * @}
  */