sorry, I found some build warnings...
I remove warnings and fix coordinate problem..

pls review this new patch.

On Mon, Apr 4, 2011 at 10:16 AM, sangho park <gouach...@gmail.com> wrote:

> did you build ecore with curl?
> elm_map uses ecore_file_download() for getting map.
> as i know, if you don't install curl before building ecore, downloading
> remote feature is disabled.
>
> anyway, I resend new patch except formatting/white space removal patch.
> thanks for your comments, and pls review this patch.
>
> Thanks.
> BR.
>
>
> On Mon, Apr 4, 2011 at 1:31 AM, Daniel Juyung Seo <seojuyu...@gmail.com>wrote:
>
>> Hello, thanks for your patch.
>> But I can't test this on my computer.
>> Do I have to set any option to use elm_map?
>> It was working at the office but not at my home :(
>> When I ran elementary_test "Map", I could just see markers but no map.
>>
>> And can you separate formatting/white space removal patch from your patch?
>> For reviewers it's hard to check the code which has a new feature and
>> formatting fix at the same time.
>>
>> Thanks.
>> Daniel Juyung Seo (SeoZ)
>>
>> On Sat, Apr 2, 2011 at 6:40 PM, sangho park <gouach...@gmail.com> wrote:
>>
>>> Dear all,
>>>
>>> This is a patch for elm_map route feature.
>>> I added some APIs for route to elm_map.c
>>>
>>> there are some route services provided by Open Street Map (yours, open
>>> route
>>> service, monav...)
>>> I just added 'yours' url callback and will add ors, monav)
>>>
>>> and add some test code to test_map.c
>>>
>>> attached fie : route-example.png
>>>
>>> pls review this patch.
>>>
>>> Thanks.
>>> BR
>>>
>>>
>>> ------------------------------------------------------------------------------
>>> Create and publish websites with WebMatrix
>>> Use the most popular FREE web apps or write code yourself;
>>> WebMatrix provides all the features you need to develop and
>>> publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
>>>
>>> _______________________________________________
>>> enlightenment-devel mailing list
>>> enlightenment-devel@lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
>>>
>>>
>>
>
Index: elementary/configure.ac
===================================================================
--- elementary/configure.ac	(리비전 58309)
+++ elementary/configure.ac	(작업 사본)
@@ -209,6 +209,7 @@ PKG_CHECK_MODULES([ELEMENTARY],
     ecore-file >= 1.0.0
     ecore-imf >= 1.0.0
     edje >= 1.0.999
+    libxml-2.0 >= 2.7.0
    ]
 )
 
Index: elementary/src/lib/Elementary.h.in
===================================================================
--- elementary/src/lib/Elementary.h.in	(리비전 58309)
+++ elementary/src/lib/Elementary.h.in	(작업 사본)
@@ -2098,14 +2098,45 @@ extern "C" {
         ELM_MAP_SOURCE_LAST
      } Elm_Map_Sources;
 
-   typedef struct _Elm_Map_Marker       Elm_Map_Marker;
-   typedef struct _Elm_Map_Marker_Class Elm_Map_Marker_Class;
-   typedef struct _Elm_Map_Group_Class  Elm_Map_Group_Class;
+   typedef enum _Elm_Map_Route_Sources
+     {
+        ELM_MAP_ROUTE_SOURCE_YOURS,
+        ELM_MAP_ROUTE_SOURCE_MONAV,
+        ELM_MAP_ROUTE_SOURCE_ORS,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_1,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_2,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_3,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_4,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_5,
+        ELM_MAP_ROUTE_SOURCE_CUSTOM_6,
+        ELM_MAP_ROUTE_SOURCE_MODULE,
+        ELM_MAP_ROUTE_SOURCE_LAST
+     } Elm_Map_Route_Sources;
+
+   typedef enum _Elm_Map_Route_Type
+     {
+        ELM_MAP_ROUTE_MOTOCAR,
+        ELM_MAP_ROUTE_BICYCLE,
+        ELM_MAP_ROUTE_FOOT,
+        ELM_MAP_ROUTE_CUSTOM_1,
+        ELM_MAP_ROUTE_CUSTOM_2,
+        ELM_MAP_ROUTE_CUSTOM_3,
+        ELM_MAP_ROUTE_CUSTOM_4,
+        ELM_MAP_ROUTE_CUSTOM_5,
+        ELM_MAP_ROUTE_CUSTOM_6,
+        ELM_MAP_ROUTE_LAST
+     } Elm_Map_Route_Type;
+
+   typedef struct _Elm_Map_Marker          Elm_Map_Marker;
+   typedef struct _Elm_Map_Marker_Class    Elm_Map_Marker_Class;
+   typedef struct _Elm_Map_Group_Class     Elm_Map_Group_Class;
+   typedef struct _Elm_Map_Route           Elm_Map_Route;
    typedef Evas_Object *(*ElmMapMarkerGetFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
    typedef void         (*ElmMapMarkerDelFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o);
    typedef Evas_Object *(*ElmMapMarkerIconGetFunc)  (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
    typedef Evas_Object *(*ElmMapGroupIconGetFunc)   (Evas_Object *obj, void *data);
    typedef char        *(*ElmMapSourceURLFunc)      (Evas_Object *obj, int x, int y, int zoom);
+   typedef char        *(*ElmMapRouteSourceURLFunc) (Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat);
 
    EAPI Evas_Object          *elm_map_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_zoom_set(Evas_Object *obj, int zoom) EINA_ARG_NONNULL(1);
@@ -2145,13 +2176,19 @@ extern "C" {
    EAPI void                  elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_source_set(Evas_Object *obj, Elm_Map_Sources source) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source) EINA_ARG_NONNULL(1);
    EAPI Elm_Map_Sources       elm_map_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
-   EAPI void                  elm_map_source_custom_api_set(Elm_Map_Sources source, const char *label, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb) EINA_ARG_NONNULL(2, 5);
+   EAPI Elm_Map_Route_Sources elm_map_route_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_source_custom_api_set(Elm_Map_Sources source, const char *label, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb, ElmMapRouteSourceURLFunc route_url_cb) EINA_ARG_NONNULL(2, 5, 6);
    EAPI int                   elm_map_source_zoom_min_get(Elm_Map_Sources source);
    EAPI int                   elm_map_source_zoom_max_get(Elm_Map_Sources source);
    EAPI const char           *elm_map_source_name_get(Elm_Map_Sources source);
    EAPI void                  elm_map_user_agent_set(Evas_Object *obj, const char *user_agent) EINA_ARG_NONNULL(1, 2);
    EAPI const char           *elm_map_user_agent_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Elm_Map_Route        *elm_map_route_add(Evas_Object *obj, Elm_Map_Route_Type type, int method, double flon, double flat, double tlon, double tlat) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_remove(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_route_color_set(Evas_Object *obj, int r, int g , int b, int a) EINA_ARG_NONNULL(1);
+
    /* smart callbacks called:
     * "clicked" - when image clicked
     * "press" - when mouse/finger held down initially on image
Index: elementary/src/lib/elm_map.c
===================================================================
--- elementary/src/lib/elm_map.c	(리비전 58309)
+++ elementary/src/lib/elm_map.c	(작업 사본)
@@ -1,5 +1,8 @@
 #include <Elementary.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
 #include "elm_priv.h"
+#include "Ecore_Con.h"
 
 /**
  * @defgroup Map Map
@@ -53,11 +56,26 @@ typedef struct _Grid_Item Grid_Item;
 typedef struct _Marker_Group Marker_Group;
 typedef struct _Mod_Api Mod_Api;
 typedef struct _Event Event;
+typedef struct _Route_Node Route_Node;
+typedef struct _Route_Waypoint Route_Waypoint;
+typedef struct _Url_Data Url_Data;
 
 #define DEST_DIR_ZOOM_PATH "/tmp/elm_map/%d/%d/"
 #define DEST_DIR_PATH DEST_DIR_ZOOM_PATH"%d/"
 #define DEST_FILE_PATH "%s%d.png"
 
+#define ROUTE_YOURS_URL "http://www.yournavigation.org/api/dev/route.php";
+#define ROUTE_TYPE_MOTORCAR "motocar"
+#define ROUTE_TYPE_BICYCLE "bicycle"
+#define ROUTE_TYPE_FOOT "foot"
+#define YOURS_DISTANCE_XPATH "//prefix:distance"
+#define YOURS_DESCRIPTION_XPATH "//prefix:description"
+#define YOURS_COORDINATES_XPATH "//prefix:coordinates"
+
+// TODO: fix monav & ors url 
+#define ROUTE_MONAV_URL "http://";
+#define ROUTE_ORS_URL "http:///";
+
 // Map sources
 // Currently the size of a tile must be 256*256
 // and the size of the map must be pow(2.0, z)*tile_size
@@ -68,6 +86,8 @@ typedef struct _Map_Sources_Tab
    int zoom_min;
    int zoom_max;
    ElmMapSourceURLFunc url_cb;
+   Elm_Map_Route_Sources route_source;
+   ElmMapRouteSourceURLFunc route_url_cb;
 } Map_Sources_Tab;
 
 #define ZOOM_MAX 18
@@ -85,21 +105,45 @@ static char * _custom4_url_cb(Evas_Object *obj __U
 static char * _custom5_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
 static char * _custom6_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
 
+static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_monva_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom1_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom2_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom3_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom4_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom5_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_route_custom6_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+static char *_routee_module_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
+
 static Map_Sources_Tab map_sources_tab[] =
 {
-     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb},
-     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb},
-     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb},
-     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, _custom2_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, _custom3_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, _custom4_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, _custom5_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, _custom6_url_cb},
-     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb}
+     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_1, _route_custom1_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, _custom2_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_2, _route_custom2_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, _custom3_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_3, _route_custom3_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, _custom4_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_4, _route_custom4_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, _custom5_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_5, _route_custom5_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, _custom6_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_6, _route_custom6_url_cb},
+     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS}
 };
 
+struct _Url_Data
+{
+   Ecore_Con_Url *con_url;
+
+   int (*data_cb)(Url_Data *data);
+   int (*progress_cb)(Url_Data *data, Ecore_Con_Event_Url_Progress *ev);
+
+   char *data;
+   unsigned int size;
+
+   void *user_data;
+};
+
 struct _Elm_Map_Marker_Class
 {
    const char *style;
@@ -175,6 +219,57 @@ struct _Marker_Group
    Eina_Bool delete_object : 1;
 };
 
+struct _Elm_Map_Route
+{
+   Widget_Data *wd;
+
+   Route_Node *n;
+   Route_Waypoint *w;
+   Ecore_Con_Url *con_url;
+
+   int type;
+   int method;
+   int x, y;
+   double flon, flat, tlon, tlat;
+
+   Eina_List *nodes, *path;
+   Eina_List *waypoint;
+
+   struct {
+      int nodes;
+      int waypoints;
+      double dist; /* unit : km */
+   } info;
+
+   Eina_List *handlers;
+   Url_Data ud;
+
+   struct {
+      int r;
+      int g;
+      int b;
+      int a;
+   } color;
+};
+
+struct _Route_Node
+{
+   Widget_Data *wd;
+
+   int idx;
+   struct {
+      double lon, lat;
+      char *address;
+   } pos;
+};
+
+struct _Route_Waypoint
+{
+   Widget_Data *wd;
+
+   const char *point;
+};
+
 struct _Grid_Item
 {
    Widget_Data *wd;
@@ -260,6 +355,7 @@ struct _Widget_Data
    Eina_List *markers_clas; // list of Elm_Map_Markers_Class*
 
    Elm_Map_Sources source;
+   Elm_Map_Route_Sources route_source;
    Mod_Api *api;
    Eina_List *s_event_list;
    int try_num;
@@ -267,6 +363,7 @@ struct _Widget_Data
 
    Eina_Hash *ua;
    const char *user_agent;
+   Elm_Map_Route *route;
 };
 
 struct _Mod_Api
@@ -372,6 +469,8 @@ static void _mouse_multi_down(void *data, Evas *ev
 static void _mouse_multi_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
 static void _mouse_multi_move(void *data, Evas *evas, Evas_Object *obj, void *event_info);
 
+static void route_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
+
 static int
 get_multi_device(Evas_Object *obj)
 {
@@ -463,6 +562,75 @@ ok:
 }
 
 static void
+route_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd || !wd->route) return;
+
+   Eina_List *l;
+   Route_Node *n;
+   Evas_Object *path;
+   int x, y, rx, ry;
+   Evas_Coord size = pow(2.0, wd->zoom)*wd->tsize;
+
+   EINA_LIST_FOREACH(wd->route->path, l, path)
+     {
+        evas_object_hide(path);
+     }
+
+   evas_object_geometry_get(wd->rect, &rx, &ry, NULL, NULL);
+   EINA_LIST_FOREACH(wd->route->nodes, l, n)
+     {
+        if ((!wd->zoom) || ((n->idx % wd->zoom)==0)) continue;
+        if ((wd->route->x >= 0) && (wd->route->y >= 0))
+          {
+             elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
+             x += rx;
+             y += ry;
+	     if ((x >= px) && (x <= (px + ow)) &&
+	         (y >= py) && (y <= (py + oh)))
+               {
+                  x -= px;
+                  y -= py;
+
+                  path = eina_list_nth(wd->route->path, n->idx);
+                  evas_object_line_xy_set(path, wd->route->x, wd->route->y, x, y);
+                  evas_object_color_set(path, wd->route->color.r, wd->route->color.g, wd->route->color.b, wd->route->color.a);
+                  evas_object_raise(path);
+                  evas_object_show(path);
+                  wd->route->x = x;
+                  wd->route->y = y;
+               }
+             else
+               {
+                  wd->route->x = -1;
+                  wd->route->y = -1;
+               }
+          }
+        else
+          {
+             elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
+             x += rx;
+             y += ry;
+	     if ((x >= px) && (x <= (px + ow)) &&
+	         (y >= py) && (y <= (py + oh)))
+               {
+                  wd->route->x = x - px;
+                  wd->route->y = y - py;
+               }
+             else
+               {
+                  wd->route->x = -1;
+                  wd->route->y = -1;
+               }
+          }
+     }
+     wd->route->x = -1;
+     wd->route->y = -1;
+}
+
+static void
 rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1409,6 +1577,10 @@ _del_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *l;
    Event *ev;
+   Evas_Object *p;
+   Route_Node *n;
+   Route_Waypoint *w;
+   Ecore_Event_Handler *h;
 
    if (!wd) return;
 
@@ -1431,6 +1603,33 @@ _del_hook(Evas_Object *obj)
         destroy_event_object(obj, ev);
      }
 
+   if (wd->route)
+     {
+        EINA_LIST_FREE(wd->route->path, p)
+          {
+             evas_object_del(p);
+          }
+
+        EINA_LIST_FREE(wd->route->waypoint, w)
+          {
+             if (w->point) eina_stringshare_del(w->point);
+             free(w);
+          }
+
+        EINA_LIST_FREE(wd->route->nodes, n)
+          {
+             if (n->pos.address) eina_stringshare_del(n->pos.address);
+             free(n);
+          }
+
+        EINA_LIST_FREE(wd->route->handlers, h)
+          {
+             ecore_event_handler_del(h);
+          }
+
+        if (wd->route->con_url) ecore_con_url_free(wd->route->con_url);
+        if (wd->route->ud.data) free(wd->route->ud.data);
+     }
    if (wd->calc_job) ecore_job_del(wd->calc_job);
    if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
    if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
@@ -1653,6 +1852,7 @@ _pan_calculate(Evas_Object *obj)
         grid_load(sd->wd->obj, g);
         grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
         marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+        if (!sd->wd->zoom_animator) route_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
      }
 }
 
@@ -2080,6 +2280,159 @@ _event_hook(Evas_Object *obj, Evas_Object *src __U
    return EINA_TRUE;
 }
 
+static Eina_Bool
+_get_double(xmlXPathContext *xpath_ctx, char *xpath, double *value)
+{
+   xmlXPathObject *obj = NULL;
+
+   obj = xmlXPathEvalExpression (BAD_CAST (xpath), xpath_ctx);
+   if (obj && (!obj->nodesetval || xmlXPathNodeSetIsEmpty(obj->nodesetval)))
+     {
+        xmlXPathFreeObject (obj);
+        return EINA_FALSE;
+     }
+   *value = xmlXPathCastNodeSetToNumber(obj->nodesetval);
+   xmlXPathFreeObject (obj);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_get_string(xmlXPathContext *xpath_ctx, char *xpath, char **value)
+{
+   xmlXPathObject *obj = NULL;
+
+   obj = xmlXPathEvalExpression (BAD_CAST (xpath), xpath_ctx);
+   if (obj && (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval)))
+     {
+        xmlXPathFreeObject (obj);
+        return EINA_FALSE;
+     }
+   *value = xmlXPathCastNodeSetToString(obj->nodesetval);
+   xmlXPathFreeObject (obj);
+
+   return EINA_TRUE;
+}
+
+static void
+_parse_kml(void *data)
+{
+   ELM_CHECK_WIDTYPE(data, widtype);
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   xmlDocPtr doc;
+   xmlXPathContext *xpath_ctx;
+   unsigned int ele, idx;
+   char **str, *var;
+
+   doc = xmlParseDoc (BAD_CAST (wd->route->ud.data));
+   if (!doc) return;
+
+   xpath_ctx = xmlXPathNewContext(doc);
+   if (!xpath_ctx)
+     {
+        xmlFreeDoc (doc);
+        return;
+     }
+   xmlXPathRegisterNs (xpath_ctx, BAD_CAST ("prefix"), BAD_CAST("http://earth.google.com/kml/2.0";));
+   if (!_get_double(xpath_ctx, YOURS_DISTANCE_XPATH, &wd->route->info.dist))
+     {
+        WRN("distance is not found !");
+     }
+
+   if (_get_string(xpath_ctx, YOURS_DESCRIPTION_XPATH, &var))
+     {
+        str = eina_str_split_full(var, "\n", 0, &ele);
+        wd->route->info.waypoints = ele;
+        for (idx = 0 ; idx < ele ; idx++)
+          {
+             Route_Waypoint *wp = ELM_NEW(Route_Waypoint);
+             if (wp) wp->wd = wd;
+	     eina_stringshare_replace(&wp->point, str[idx]);
+	     INF("%s", str[idx]);
+             wd->route->waypoint = eina_list_append(wd->route->waypoint, wp);
+          }
+        if (str) free(str);
+     }
+   else WRN("description is not found !");
+
+   if (_get_string(xpath_ctx, YOURS_COORDINATES_XPATH, &var))
+     {
+        double lon, lat;
+	Evas_Object *path;
+        str = eina_str_split_full(var, "\n", 0, &ele);
+        wd->route->info.nodes = ele;
+        for (idx = 0 ; idx < ele ; idx++)
+          {
+             sscanf(str[idx], "%lf,%lf", &lon, &lat);
+             Route_Node *n = ELM_NEW(Route_Node);
+             if (n) n->wd = wd;
+	     n->pos.lon = lon;
+	     n->pos.lat = lat;
+	     n->idx = idx;
+	     INF("%lf:%lf", lon, lat);
+             wd->route->nodes = eina_list_append(wd->route->nodes, n);
+
+             path = evas_object_line_add(evas_object_evas_get(data));
+             evas_object_smart_member_add(path, wd->pan_smart);
+             wd->route->path = eina_list_append(wd->route->path, path);
+          }
+        if (str) free(str);
+     }
+   else WRN("coordinates is not found !");
+
+   xmlXPathFreeContext (xpath_ctx);
+   xmlFreeDoc (doc);
+}
+
+static Eina_Bool
+_common_data_cb(void *data, int ev_type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Url_Data *ev = event;
+   ELM_CHECK_WIDTYPE(data, widtype) EINA_TRUE;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd->route) return;
+
+   char *con_data = ecore_con_url_data_get(wd->route->con_url);
+   if (!con_data) return EINA_TRUE;
+
+   if ((!ev) || (!wd) || strcmp(con_data, "route")) return EINA_TRUE;
+
+   wd->route->ud.data = realloc(wd->route->ud.data, sizeof(char) * (wd->route->ud.size + ev->size));
+   memcpy(wd->route->ud.data + wd->route->ud.size, ev->data, ev->size);
+   wd->route->ud.size += ev->size;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_common_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Url_Complete *ev = event;
+   ELM_CHECK_WIDTYPE(data, widtype) EINA_TRUE;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd->route) return;
+
+   char *con_data = ecore_con_url_data_get(wd->route->con_url);
+   if (!con_data) return EINA_TRUE;
+
+   if ((!ev) || (!wd) || strcmp(con_data, "route")) return EINA_TRUE;
+   ecore_con_url_data_set(wd->route->con_url, NULL);
+   if (!wd->route->ud.data) return EINA_TRUE;
+   wd->route->ud.data[wd->route->ud.size] = '\0';
+
+   _parse_kml(data);
+
+   if (wd->grids)
+     {
+	Evas_Coord ox, oy, ow, oh;
+	evas_object_geometry_get(data, &ox, &oy, &ow, &oh);
+	route_place(data, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+     }
+
+   return EINA_TRUE;
+}
+
 static int idnum = 1;
 
 /**
@@ -2240,6 +2593,7 @@ elm_map_zoom_set(Evas_Object *obj, int zoom)
    Eina_List *l;
    Grid *g, *g_zoom = NULL;
    Evas_Coord rx, ry, rw, rh;
+   Evas_Object *p;
    int z;
    int zoom_changed = 0, started = 0;
 
@@ -2257,6 +2611,14 @@ elm_map_zoom_set(Evas_Object *obj, int zoom)
    elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
    elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
 
+   if (wd->route)
+     {
+        EINA_LIST_FOREACH(wd->route->path, l, p)
+          {
+             evas_object_hide(p);
+          }
+     }
+
    if (wd->mode == ELM_MAP_ZOOM_MODE_MANUAL)
      {
         wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
@@ -3480,10 +3842,25 @@ elm_map_source_set(Evas_Object *obj, Elm_Map_Sourc
 }
 
 /**
+ * Set the source of the route.
+ *
+ * @param clas the group class
+ * @param source the new source
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+}
+
+/**
  * Get the current source
  *
  * @param obj the map object
- * @return Returns the maximum zoom of the source
+ * @return Returns the source of the map
  *
  * @ingroup Map
  */
@@ -3497,6 +3874,23 @@ elm_map_source_get(const Evas_Object *obj)
 }
 
 /**
+ * Get the current route source
+ *
+ * @param obj the map object
+ * @return Returns the source of the route
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Route_Sources
+elm_map_route_source_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ROUTE_SOURCE_YOURS;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_MAP_ROUTE_SOURCE_YOURS;
+   return wd->route_source;
+}
+
+/**
  * Set the API of a custom source.
  *
  * A custom web service can be associated to the source ELM_MAP_SOURCE_CUSTOM_(1..7).
@@ -3510,7 +3904,7 @@ elm_map_source_get(const Evas_Object *obj)
  * @ingroup Map
  */
 EAPI void
-elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb)
+elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb, ElmMapRouteSourceURLFunc route_url_cb)
 {
    EINA_SAFETY_ON_NULL_RETURN(name);
    EINA_SAFETY_ON_NULL_RETURN(url_cb);
@@ -3518,6 +3912,7 @@ EAPI void
    map_sources_tab[source].zoom_min = zoom_min;
    map_sources_tab[source].zoom_max = zoom_max;
    map_sources_tab[source].url_cb = url_cb;
+   map_sources_tab[source].route_url_cb = route_url_cb;
 }
 
 /**
@@ -3602,7 +3997,132 @@ elm_map_user_agent_get(Evas_Object *obj)
    return wd->user_agent;
 }
 
+EAPI Elm_Map_Route*
+elm_map_route_add(Evas_Object *obj,
+                  Elm_Map_Route_Type type,
+                  int method,
+                  double flon,
+                  double flat,
+                  double tlon,
+                  double tlat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   if (wd->route)
+     {
+        elm_map_route_remove(wd->route);
+	free(wd->route);
+        wd->route = NULL;
+     }
 
+   Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
+   if (!route) return NULL;
+
+   wd->route = route;
+   route->wd = wd;
+   route->color.r = 255;
+   route->color.g = 0;
+   route->color.b = 0;
+   route->color.a = 255;
+   route->con_url = ecore_con_url_new(NULL);
+   route->handlers = eina_list_append
+     (route->handlers, (void*)ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _common_data_cb, obj));
+   route->handlers = eina_list_append
+     (route->handlers, (void*)ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _common_complete_cb, obj));
+
+   Eina_Bool ret = EINA_FALSE;
+   char *source;
+   char *type_name;
+
+   route->x = -1;
+   route->y = -1;
+   route->type = type;
+   route->method = method;
+   route->flon = flon;
+   route->flat = flat;
+   route->tlon = tlon;
+   route->tlat = tlat;
+
+   switch (type)
+     {
+      case ELM_MAP_ROUTE_MOTOCAR:
+        type_name = strdup(ROUTE_TYPE_MOTORCAR);
+        break;
+      case ELM_MAP_ROUTE_BICYCLE:
+        type_name = strdup(ROUTE_TYPE_BICYCLE);
+        break;
+      case ELM_MAP_ROUTE_FOOT:
+        type_name = strdup(ROUTE_TYPE_FOOT);
+        break;
+      default:
+        break;
+     }
+
+   source = map_sources_tab[wd->source].route_url_cb(obj, type_name, method, flon, flat, tlon, tlat);
+   INF("route url = %s", source);
+
+   ecore_con_url_url_set(route->con_url, source);
+   ecore_con_url_data_set(route->con_url, "route");
+
+   ret = ecore_con_url_get(route->con_url);
+   if (type_name) free(type_name);
+   if (source) free(source);
+   return route;
+}
+
+EAPI void
+elm_map_route_remove(Elm_Map_Route *route)
+{
+   EINA_SAFETY_ON_NULL_RETURN(route);
+
+   Route_Waypoint *w;
+   Route_Node *n;
+   Evas_Object *p;
+   Ecore_Event_Handler *h;
+
+   if (route->ud.data)
+     {
+        free(route->ud.data);
+        route->ud.data = NULL;
+	route->ud.size = 0;
+     }
+
+   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);
+     }
+}
+
+EAPI void
+elm_map_route_color_set(Evas_Object *obj, int r, int g , int b, int a)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   wd->route->color.r = r;
+   wd->route->color.g = g;
+   wd->route->color.b = b;
+   wd->route->color.a = a;
+}
+
 static char *
 _mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
@@ -3692,3 +4212,71 @@ _module_url_cb(Evas_Object *obj, int x, int y, int
    return buf;
 }
 
+static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+
+// TODO: fix monav api
+static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_MONAV_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+
+// TODO: fix ors api
+static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf),
+            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            ROUTE_ORS_URL, flat, flon, tlat, tlon, type_name, method);
+
+   return strdup(buf);
+}
+
+static char *_route_custom1_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_custom2_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_custom3_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_custom4_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_custom5_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_custom6_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   return strdup("");
+}
+
+static char *_route_module_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
+{
+   // TODO: make example route module
+   return strdup("");
+}
+
Index: elementary/src/bin/test_map.c
===================================================================
--- elementary/src/bin/test_map.c	(리비전 58309)
+++ elementary/src/bin/test_map.c	(작업 사본)
@@ -18,6 +18,7 @@ static Elm_Map_Group_Class *itc_group1, *itc_group
 static Evas_Object *rect;
 static int nb_elts;
 static Elm_Map_Marker *markers[MARKER_MAX];
+static Elm_Map_Marker *route_from, *route_to;
 
 Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
 Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
@@ -33,6 +34,9 @@ Marker_Data data11= {PACKAGE_DATA_DIR"/images/wood
 
 Marker_Data data_parking= {PACKAGE_DATA_DIR"/images/parking.png"};
 
+static Evas_Object * _marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data);
+static Evas_Object * _group_icon_get(Evas_Object *obj, void *data);
+
 static void
 my_map_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
@@ -52,9 +56,51 @@ my_map_longpressed(void *data __UNUSED__, Evas_Obj
 }
 
 static void
-my_map_clicked_double(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+my_map_clicked_double(void *data, Evas_Object *obj, void *event_info)
 {
-   printf("clicked,double\n");
+   double lon, lat;
+   double flon, flat, tlon, tlat;
+   Evas_Coord x, y, w, h;
+   int zoom;
+   Evas_Event_Mouse_Up *down = (Evas_Event_Mouse_Up *)event_info;
+   if (!down) return;
+
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   zoom = elm_map_zoom_get(data);
+   if (zoom<5) return;
+   elm_map_geo_region_get(obj, &lon, &lat);
+   elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, zoom)*256, &x, &y);
+   x += down->output.x-(w / 2);
+   y += down->output.y-(h / 2);
+   elm_map_utils_convert_coord_into_geo(obj, x, y, pow(2.0, zoom)*256, &lon, &lat);
+
+   itc1 = elm_map_marker_class_new(data);
+
+   elm_map_marker_class_del_cb_set(itc1, NULL);
+
+   itc_group1 = elm_map_group_class_new(data);
+   elm_map_group_class_icon_cb_set(itc_group1, _group_icon_get);
+   elm_map_group_class_data_set(itc_group1, (void *)PACKAGE_DATA_DIR"/images/bubble.png");
+   elm_map_group_class_style_set(itc_group1, "empty");
+   elm_map_group_class_zoom_displayed_set(itc_group1, 5);
+
+   if (route_from && route_to)
+     {
+        elm_map_marker_remove(route_from);
+	route_from = NULL;
+        elm_map_marker_remove(route_to);
+	route_to = NULL;
+     }
+
+   if (!route_from) route_from = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
+   else route_to = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
+
+   if (route_from && route_to)
+     {
+        elm_map_marker_region_get(route_from, &flon, &flat);
+        elm_map_marker_region_get(route_to, &tlon, &tlat);
+        elm_map_route_add(data, ELM_MAP_ROUTE_MOTOCAR, 1, flon, flat, tlon, tlat);
+     }
 }
 
 static void
@@ -133,7 +179,7 @@ my_bt_show_reg(void *data, Evas_Object *obj __UNUS
    Eina_Bool b = elm_map_paused_get(data);
    elm_map_paused_set(data, EINA_TRUE);
    elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
-   elm_map_geo_region_show(data, 2.352, 48.857);
+   elm_map_geo_region_show(data, 126.977969, 37.566535);
    elm_map_zoom_set(data, 18);
    elm_map_paused_set(data, b);
 }
@@ -141,7 +187,7 @@ my_bt_show_reg(void *data, Evas_Object *obj __UNUS
 static void
 my_bt_bring_reg(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   elm_map_geo_region_bring_in(data, 2.352, 48.857);
+   elm_map_geo_region_bring_in(data, 126.977969, 37.566535);
 }
 
 static void
@@ -254,7 +300,7 @@ my_bt_add(void *data, Evas_Object *obj __UNUSED__,
         if (!style) g_clas = itc_group1;
 	else g_clas = itc_group2;
 
-       markers[i] = elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d); 
+       markers[i] = elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d);
     }
     nb_elts += 1000;
     printf("nb elements: %d\n", nb_elts);
@@ -455,7 +501,7 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
         evas_object_smart_callback_add(map, "clicked", my_map_clicked, win);
         evas_object_smart_callback_add(map, "press", my_map_press, win);
         evas_object_smart_callback_add(map, "longpressed", my_map_longpressed, win);
-        evas_object_smart_callback_add(map, "clicked,double", my_map_clicked_double, win);
+        evas_object_smart_callback_add(map, "clicked,double", my_map_clicked_double, map);
         evas_object_smart_callback_add(map, "load,detail", my_map_load_detail, win);
         evas_object_smart_callback_add(map, "loaded,detail", my_map_loaded_detail, win);
         evas_object_smart_callback_add(map, "zoom,start", my_map_zoom_start, win);
@@ -515,7 +561,7 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
         //
 
         bt = elm_button_add(win);
-        elm_button_label_set(bt, "Show Paris");
+        elm_button_label_set(bt, "Show Seoul");
         evas_object_smart_callback_add(bt, "clicked", my_bt_show_reg, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(bt, 0.1, 0.5);
@@ -523,7 +569,7 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
         evas_object_show(bt);
 
         bt = elm_button_add(win);
-        elm_button_label_set(bt, "Bring Paris");
+        elm_button_label_set(bt, "Bring Seoul");
         evas_object_smart_callback_add(bt, "clicked", my_bt_bring_reg, map);
         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(bt, 0.9, 0.5);
------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to