Dear all,

This is a patch for elm_map name(address) feature.
I added some APIs for name to elm_map.c and added some test code to
test_map.c

I used nominatim OSM service. (http://http://nominatim.openstreetmap.org/)
as i felt, it's response time was very good to use.

added APIs are:
   EAPI Elm_Map_Name *elm_map_utils_convert_coord_into_name(const
Evas_Object *obj, double lon, double lat);
   EAPI Elm_Map_Name *elm_map_utils_convert_name_into_coord(const
Evas_Object *obj, char *address);

   EAPI const char *elm_map_name_address_get(Elm_Map_Name *name);
   EAPI void elm_map_name_region_get(Elm_Map_Name *name, double *lon, double
*lat);
   EAPI void elm_map_name_remove(Elm_Map_Name *name);

you can get the address from coordinate and also get coordinate from
freeform address;

please review this patch.
Index: elementary/src/lib/Elementary.h.in
===================================================================
--- elementary/src/lib/Elementary.h.in	(리비전 58611)
+++ elementary/src/lib/Elementary.h.in	(작업 사본)
@@ -2201,6 +2201,19 @@ extern "C" {
         ELM_MAP_ROUTE_SOURCE_LAST
      } Elm_Map_Route_Sources;
 
+   typedef enum _Elm_Map_Name_Sources
+     {
+        ELM_MAP_NAME_SOURCE_NOMINATIM,
+        ELM_MAP_NAME_SOURCE_CUSTOM_1,
+        ELM_MAP_NAME_SOURCE_CUSTOM_2,
+        ELM_MAP_NAME_SOURCE_CUSTOM_3,
+        ELM_MAP_NAME_SOURCE_CUSTOM_4,
+        ELM_MAP_NAME_SOURCE_CUSTOM_5,
+        ELM_MAP_NAME_SOURCE_CUSTOM_6,
+        ELM_MAP_NAME_SOURCE_MODULE,
+        ELM_MAP_NAME_SOURCE_LAST
+     } Elm_Map_Name_Sources;
+
    typedef enum _Elm_Map_Route_Type
      {
         ELM_MAP_ROUTE_TYPE_MOTOCAR,
@@ -2216,16 +2229,25 @@ extern "C" {
         ELM_MAP_ROUTE_METHOD_LAST
      } Elm_Map_Route_Method;
 
+   typedef enum _Elm_Map_Name_Method
+     {
+        ELM_MAP_NAME_METHOD_SEARCH,
+        ELM_MAP_NAME_METHOD_REVERSE,
+        ELM_MAP_NAME_METHOD_LAST
+     } Elm_Map_Name_Method;
+
    typedef struct _Elm_Map_Marker          Elm_Map_Marker;
    typedef struct _Elm_Map_Marker_Class    Elm_Map_Marker_Class;
    typedef struct _Elm_Map_Group_Class     Elm_Map_Group_Class;
    typedef struct _Elm_Map_Route           Elm_Map_Route;
+   typedef struct _Elm_Map_Name            Elm_Map_Name;
    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);
+   typedef char        *(*ElmMapNameSourceURLFunc) (Evas_Object *obj, int method, char *name, double lon, double lat);
 
    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);
@@ -2240,8 +2262,10 @@ extern "C" {
    EAPI void                  elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused) EINA_ARG_NONNULL(1);
    EAPI Eina_Bool             elm_map_paused_markers_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num) EINA_ARG_NONNULL(1, 2, 3);
-   EAPI void                  elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat);
-   EAPI void                  elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y);
+   EAPI void                  elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat) EINA_ARG_NONNULL(1, 5, 6);
+   EAPI void                  elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y) EINA_ARG_NONNULL(1, 5, 6);
+   EAPI Elm_Map_Name         *elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat) EINA_ARG_NONNULL(1);
+   EAPI Elm_Map_Name         *elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address) EINA_ARG_NONNULL(1, 2);
    EAPI Elm_Map_Marker       *elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *clas_group, void *data) EINA_ARG_NONNULL(1, 4, 5);
    EAPI void                  elm_map_max_marker_per_group_set(Evas_Object *obj, int max) EINA_ARG_NONNULL(1);
    EAPI void                  elm_map_marker_remove(Elm_Map_Marker *marker) EINA_ARG_NONNULL(1);
@@ -2268,7 +2292,7 @@ extern "C" {
    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 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 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, ElmMapNameSourceURLFunc name_url_cb) EINA_ARG_NONNULL(2, 5, 6, 7);
    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);
@@ -2281,6 +2305,9 @@ extern "C" {
    EAPI double                elm_map_route_distance_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
    EAPI const char           *elm_map_route_node_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
    EAPI const char           *elm_map_route_waypoint_get(Elm_Map_Route *route) EINA_ARG_NONNULL(1);
+   EAPI const char           *elm_map_name_address_get(Elm_Map_Name *name) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_name_region_get(Elm_Map_Name *name, double *lon, double *lat) EINA_ARG_NONNULL(1);
+   EAPI void                  elm_map_name_remove(Elm_Map_Name *name) EINA_ARG_NONNULL(1);
 
    /* smart callbacks called:
     * "clicked" - when image clicked
Index: elementary/src/lib/elm_map.c
===================================================================
--- elementary/src/lib/elm_map.c	(리비전 58611)
+++ elementary/src/lib/elm_map.c	(작업 사본)
@@ -31,6 +31,8 @@
  * "downloaded" - This is called when map images are downloaded
  * "route,load" - This is called when route request begins
  * "route,loaded" - This is called when route request ends
+ * "name,load" - This is called when name request begins
+ * "name,loaded- This is called when name request ends
  *
  * TODO : doxygen
  */
@@ -47,11 +49,13 @@ typedef struct _Route_Node Route_Node;
 typedef struct _Route_Waypoint Route_Waypoint;
 typedef struct _Url_Data Url_Data;
 typedef struct _Route_Dump Route_Dump;
+typedef struct _Name_Dump Name_Dump;
 
 #define DEST_DIR_ZOOM_PATH "/tmp/elm_map/%d/%d/"
 #define DEST_DIR_PATH DEST_DIR_ZOOM_PATH"%d/"
 #define DEST_FILE_PATH "%s%d.png"
-#define DEST_XML_FILE "/tmp/elm_map-XXXXXX"
+#define DEST_ROUTE_XML_FILE "/tmp/elm_map-route-XXXXXX"
+#define DEST_NAME_XML_FILE "/tmp/elm_map-name-XXXXXX"
 
 #define ROUTE_YOURS_URL "http://www.yournavigation.org/api/dev/route.php";
 #define ROUTE_TYPE_MOTORCAR "motocar"
@@ -65,6 +69,12 @@ typedef struct _Route_Dump Route_Dump;
 #define ROUTE_MONAV_URL "http://";
 #define ROUTE_ORS_URL "http:///";
 
+#define NAME_NOMINATIM_URL "http://nominatim.openstreetmap.org";
+#define NOMINATIM_RESULT "result"
+#define NOMINATIM_PLACE "place"
+#define NOMINATIM_ATTR_LON "lon"
+#define NOMINATIM_ATTR_LAT "lat"
+
 // 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
@@ -77,6 +87,7 @@ typedef struct _Map_Sources_Tab
    ElmMapSourceURLFunc url_cb;
    Elm_Map_Route_Sources route_source;
    ElmMapRouteSourceURLFunc route_url_cb;
+   ElmMapNameSourceURLFunc name_url_cb;
 } Map_Sources_Tab;
 
 #define ZOOM_MAX 18
@@ -109,19 +120,27 @@ static char *_route_custom6_url_cb(Evas_Object *ob
 static char *_route_module_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
  */
 
+static char *_nominatim_url_cb(Evas_Object *obj, int method, char *name, double lon, double lat);
+static char *_name_custom1_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+static char *_name_custom2_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+static char *_name_custom3_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+static char *_name_custom4_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+static char *_name_custom5_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+static char *_name_custom6_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__);
+
 static Map_Sources_Tab map_sources_tab[] =
 {
-     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
-     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
-     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
-     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_1, _route_custom1_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, _custom2_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_2, _route_custom2_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, _custom3_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_3, _route_custom3_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, _custom4_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_4, _route_custom4_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, _custom5_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_5, _route_custom5_url_cb},
-     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, _custom6_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_6, _route_custom6_url_cb},
-     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb}
+     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb},
+     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb},
+     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb},
+     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, _custom1_url_cb, ELM_MAP_ROUTE_SOURCE_CUSTOM_1, _route_custom1_url_cb, _name_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, _name_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, _name_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, _name_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, _name_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, _name_custom6_url_cb},
+     {ELM_MAP_SOURCE_MODULE, "Module", 0, 18, _module_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb}
 };
 
 struct _Url_Data
@@ -262,6 +281,18 @@ struct _Route_Waypoint
    const char *point;
 };
 
+struct _Elm_Map_Name
+{
+   Widget_Data *wd;
+
+   Ecore_Con_Url *con_url;
+   int method;
+   char *address;
+   double lon, lat;
+   Url_Data ud;
+   Ecore_Event_Handler *handler;
+};
+
 struct _Grid_Item
 {
    Widget_Data *wd;
@@ -300,7 +331,6 @@ struct _Widget_Data
    Evas_Coord pan_x, pan_y, minw, minh;
 
    int id;
-   int fid;
    int zoom;
    Elm_Map_Zoom_Mode mode;
 
@@ -325,7 +355,6 @@ struct _Widget_Data
    int preload_num;
    Eina_List *grids;
    Eina_Bool resized : 1;
-   Eina_Bool longpressed : 1;
    Eina_Bool on_hold : 1;
    Eina_Bool paused : 1;
    Eina_Bool paused_markers : 1;
@@ -357,6 +386,8 @@ struct _Widget_Data
    Eina_Hash *ua;
    const char *user_agent;
    Eina_List *route;
+   Evas_Event_Mouse_Down ev;
+   Eina_List *names;
 };
 
 struct _Mod_Api
@@ -407,6 +438,23 @@ enum _Route_Xml_Attribute
    ROUTE_XML_LAST
 } Route_Xml_Attibute;
 
+struct _Name_Dump
+{
+   int id;
+   char *address;
+   double lon;
+   double lat;
+};
+
+enum _Name_Xml_Attribute
+{
+   NAME_XML_NONE,
+   NAME_XML_NAME,
+   NAME_XML_LON,
+   NAME_XML_LAT,
+   NAME_XML_LAST
+} Name_Xml_Attibute;
+
 static int dis_old = 0;
 static const char *widtype = NULL;
 
@@ -426,6 +474,8 @@ static const char SIG_ZOOM_STOP[] = "zoom,stop";
 static const char SIG_DOWNLOADED[] = "downloaded";
 static const char SIG_ROUTE_LOAD[] = "route,load";
 static const char SIG_ROUTE_LOADED[] = "route,loaded";
+static const char SIG_NAME_LOAD[] = "name,load";
+static const char SIG_NAME_LOADED[] = "name,loaded";
 static const Evas_Smart_Cb_Description _signals[] = {
        {SIG_CHANGED, ""},
        {SIG_CLICKED, ""},
@@ -443,6 +493,8 @@ static const Evas_Smart_Cb_Description _signals[]
        {SIG_DOWNLOADED, ""},
        {SIG_ROUTE_LOAD, ""},
        {SIG_ROUTE_LOADED, ""},
+       {SIG_NAME_LOAD, ""},
+       {SIG_NAME_LOADED, ""},
        {NULL, NULL}
 };
 
@@ -1359,8 +1411,7 @@ _long_press(void *data)
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return ECORE_CALLBACK_CANCEL;
    wd->long_timer = NULL;
-   wd->longpressed = EINA_TRUE;
-   evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
+   evas_object_smart_callback_call(data, SIG_LONGPRESSED, &wd->ev);
    return ECORE_CALLBACK_CANCEL;
 }
 
@@ -1388,8 +1439,9 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Eva
      evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, ev);
    else
      evas_object_smart_callback_call(data, SIG_PRESS, ev);
-   wd->longpressed = EINA_FALSE;
    if (wd->long_timer) ecore_timer_del(wd->long_timer);
+   wd->ev.output.x = ev->output.x;
+   wd->ev.output.y = ev->output.y;
    wd->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
 }
 
@@ -1593,6 +1645,7 @@ _del_hook(Evas_Object *obj)
    Route_Waypoint *w;
    Ecore_Event_Handler *h;
    Elm_Map_Route *r;
+   Elm_Map_Name *na;
 
    if (!wd) return;
 
@@ -1643,6 +1696,19 @@ _del_hook(Evas_Object *obj)
         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;
+          }
+     }
+
    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);
@@ -2294,16 +2360,23 @@ _event_hook(Evas_Object *obj, Evas_Object *src __U
 }
 
 static Eina_Bool
-cb_dump_attrs(void *data __UNUSED__, const char *key __UNUSED__, const char *value __UNUSED__)
+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_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
+cb_route_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
 {
-   Route_Dump *dump = data;
+   Route_Dump *dump = (Route_Dump*)data;
+   if (!dump) return EINA_FALSE;
 
    switch (type)
      {
@@ -2320,12 +2393,7 @@ static Eina_Bool
                 else if (!strncmp(value, YOURS_COORDINATES, length)) dump->id = ROUTE_XML_COORDINATES;
                 else dump->id = ROUTE_XML_NONE;
              }
-           else
-             {
-                eina_simple_xml_attributes_parse
-                  (attrs, length - (attrs - value), cb_dump_attrs, dump);
-             }
-        }
+         }
         break;
       case EINA_SIMPLE_XML_DATA:
         {
@@ -2345,6 +2413,45 @@ static Eina_Bool
    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 = (Name_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, 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)
 {
@@ -2376,7 +2483,7 @@ _parse_kml(void *data)
                {
                   if (fread(buf, 1, sz, f))
                     {
-                       eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_dump, &dump);
+                       eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_route_dump, &dump);
                        free(buf);
                     }
                }
@@ -2441,8 +2548,52 @@ _parse_kml(void *data)
      }
 }
 
+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;
+     }
+}
+
 static Eina_Bool
-_common_complete_cb(void *data, int ev_type __UNUSED__, void *event)
+_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;
@@ -2468,6 +2619,85 @@ static Eina_Bool
    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)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   char buf[PATH_MAX];
+   char *source;
+   int fd;
+   Elm_Map_Name *name = ELM_NEW(Elm_Map_Name);
+   if (!name) return NULL;
+
+   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 = map_sources_tab[wd->source].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);
+
+   return name;
+
+}
+
 static int idnum = 1;
 
 /**
@@ -2578,7 +2808,6 @@ elm_map_add(Evas_Object *parent)
 
    wd->zoom = -1;
    wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
-   wd->fid = 0;
    wd->id = ((int)getpid() << 16) | idnum;
    idnum++;
 
@@ -3174,7 +3403,40 @@ elm_map_utils_convert_geo_into_coord(const Evas_Ob
      *y = floor((1.0 - log( tan(lat * ELM_PI/180.0) + 1.0 / cos(lat * ELM_PI/180.0)) / ELM_PI) / 2.0 * size);
 }
 
+/**
+ * Convert a geographic coordinate (longitude, latitude) into a name (address).
+ *
+ * @param obj The map object
+ * @param lon the longitude
+ * @param lat the latitude
+ * @param name the adress 
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Name *
+elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_REVERSE, NULL, lon, lat);
+}
 
+/**
+ * Convert a name (address) into a geographic coordinate (longitude, latitude).
+ *
+ * @param obj The map object
+ * @param name the adress 
+ * @param lon the longitude correspond to x
+ * @param lat the latitude correspond to y
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Name *
+elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address)
+{
+   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);
+}
 
 /**
  * Add a marker on the map
@@ -3889,9 +4151,12 @@ elm_map_source_set(Evas_Object *obj, Elm_Map_Sourc
  * @ingroup Map
  */
 EAPI void
-elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source __UNUSED__)
+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);
+   if (!wd) return;
+   wd->source = source;
 }
 
 /**
@@ -3942,7 +4207,7 @@ elm_map_route_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, ElmMapRouteSourceURLFunc route_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, ElmMapNameSourceURLFunc name_url_cb)
 {
    EINA_SAFETY_ON_NULL_RETURN(name);
    EINA_SAFETY_ON_NULL_RETURN(url_cb);
@@ -3951,6 +4216,7 @@ EAPI void
    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;
+   map_sources_tab[source].name_url_cb = name_url_cb;
 }
 
 /**
@@ -4069,7 +4335,7 @@ elm_map_route_add(Evas_Object *obj,
    Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
    if (!route) return NULL;
 
-   snprintf(buf, sizeof(buf), DEST_XML_FILE);
+   snprintf(buf, sizeof(buf), DEST_ROUTE_XML_FILE);
    fd = mkstemp(buf);
    if (fd < 0)
      {
@@ -4081,7 +4347,6 @@ elm_map_route_add(Evas_Object *obj,
    route->ud.fname = strdup(buf);
    INF("xml file : %s", route->ud.fname);
 
-   wd->fid++;
    route->ud.fd = fdopen(fd, "w+");
    if ((!route->con_url) || (!route->ud.fd))
      {
@@ -4097,7 +4362,7 @@ elm_map_route_add(Evas_Object *obj,
    route->color.a = 255;
    route->handlers = eina_list_append
      (route->handlers, (void *)ecore_event_handler_add
-         (ECORE_CON_EVENT_URL_COMPLETE, _common_complete_cb, route));
+         (ECORE_CON_EVENT_URL_COMPLETE, _route_complete_cb, route));
 
    route->inbound = EINA_FALSE;
    route->type = type;
@@ -4279,6 +4544,45 @@ elm_map_route_waypoint_get(Elm_Map_Route *route)
    return route->info.waypoints;
 }
 
+
+EAPI const char *
+elm_map_name_address_get(Elm_Map_Name *name)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
+   return name->address;
+}
+
+EAPI void
+elm_map_name_region_get(Elm_Map_Name *name, double *lon, double *lat)
+{
+   EINA_SAFETY_ON_NULL_RETURN(name);
+   if (*lon) *lon = name->lon;
+   if (*lat) *lat = name->lat;
+}
+
+EAPI void
+elm_map_name_remove(Elm_Map_Name *name)
+{
+   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;
+     }
+}
+
+
 static char *
 _mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
 {
@@ -4372,7 +4676,7 @@ static char *_yours_url_cb(Evas_Object *obj __UNUS
 {
    char buf[PATH_MAX];
    snprintf(buf, sizeof(buf),
-            "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
+            "%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);
 
    return strdup(buf);
@@ -4440,3 +4744,67 @@ static char *_route_module_url_cb(Evas_Object *obj
    return strdup("");
 }
 */
+
+static char *
+_nominatim_url_cb(Evas_Object *obj, int method, char *name, double lon, double lat)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return strdup("");
+   char **str;
+   unsigned int ele, idx;
+
+   char search_url[PATH_MAX];
+   char buf[PATH_MAX];
+   if (method == ELM_MAP_NAME_METHOD_SEARCH)
+     {
+        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);
+     }
+   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, wd->zoom);
+   else strcpy(buf, "");
+
+   return strdup(buf);
+}
+
+static char *
+_name_custom1_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *
+_name_custom2_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *
+_name_custom3_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *
+_name_custom4_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *
+_name_custom5_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
+static char *
+_name_custom6_url_cb(Evas_Object *obj __UNUSED__, int method __UNUSED__, char *name __UNUSED__, double lon __UNUSED__, double lat __UNUSED__)
+{
+   return strdup("");
+}
+
Index: elementary/src/bin/test_map.c
===================================================================
--- elementary/src/bin/test_map.c	(리비전 58611)
+++ elementary/src/bin/test_map.c	(작업 사본)
@@ -5,6 +5,7 @@
 #ifndef ELM_LIB_QUICKLAUNCH
 
 #define MARKER_MAX 1000
+#define NAME_ENTRY_TEXT "Enter freeform address"
 
 typedef struct Marker_Data
 {
@@ -20,6 +21,8 @@ static int nb_elts;
 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 Eina_List *names;
 
 Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
 Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
@@ -51,9 +54,36 @@ my_map_press(void *data __UNUSED__, Evas_Object *o
 }
 
 static void
-my_map_longpressed(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+my_map_longpressed(void *data, Evas_Object *obj __UNUSED__, void *event_info)
 {
-   printf("longpressed\n");
+   double lon, lat;
+   double flon, flat, tlon, tlat;
+   Evas_Coord ox, oy, x, y, w, h;
+   int zoom;
+   Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
+   if (!down) return;
+
+   evas_object_geometry_get(data, &ox, &oy, &w, &h);
+   zoom = elm_map_zoom_get(data);
+   elm_map_geo_region_get(obj, &lon, &lat);
+   elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, zoom)*256, &x, &y);
+   x += down->output.x - (w / 2) - ox;
+   y += down->output.y - (h / 2) - oy;
+   elm_map_utils_convert_coord_into_geo(obj, x, y, pow(2.0, zoom)*256, &lon, &lat);
+
+   name = elm_map_utils_convert_coord_into_name(data, 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);
+
+   names = eina_list_append(names, elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL));
 }
 
 static void
@@ -63,7 +93,7 @@ my_map_clicked_double(void *data, Evas_Object *obj
    double flon, flat, tlon, tlat;
    Evas_Coord ox, oy, x, y, w, h;
    int zoom;
-   Evas_Event_Mouse_Up *down = (Evas_Event_Mouse_Up *)event_info;
+   Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
    if (!down) return;
 
    evas_object_geometry_get(data, &ox, &oy, &w, &h);
@@ -198,6 +228,35 @@ my_map_route_loaded(void *data __UNUSED__, Evas_Ob
 }
 
 static void
+my_map_name_load(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   printf("name_load\n");
+ }
+
+static void
+my_map_name_loaded(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   if (!name) return;
+   double lon, lat;
+   const char *addr = elm_map_name_address_get(name);
+   elm_map_name_region_get(name, &lon, &lat);
+   if (addr)
+     {
+        printf("name of [lon = %lf, lat = %lf] is %s\n", lon, lat, addr);
+        if ((lon != 0.0) && (lat !=0.0))
+          {
+             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, lon, lat);
+             elm_map_zoom_set(data, 18);
+             elm_map_paused_set(data, b);
+          }
+     }
+   elm_map_name_remove(name);
+}
+
+static void
 my_bt_show_reg(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Eina_Bool b = elm_map_paused_get(data);
@@ -345,6 +404,23 @@ my_bt_remove(void *data __UNUSED__, Evas_Object *o
      }
 }
 
+static void
+my_map_entry_focused(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   const char *s = elm_scrolled_entry_entry_get(obj);
+   if (!strcmp(s, NAME_ENTRY_TEXT)) elm_scrolled_entry_entry_set(obj, "");
+}
+
+static void
+my_map_entry_activated(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   double lon, lat;
+   const char *s = elm_scrolled_entry_entry_get(obj);
+   char *addr = strdup(s);
+   name = elm_map_utils_convert_name_into_coord(data, addr);
+   if (addr) free (addr);
+}
+
 static Evas_Object *
 _marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
 {
@@ -439,7 +515,7 @@ _map_move_resize_cb(void *data, Evas *e __UNUSED__
 void
 test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-   Evas_Object *win, *bg, *map, *tb2, *bt, *bx;
+   Evas_Object *win, *bg, *map, *tb2, *bt, *bx, *en;
 
    win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
    elm_win_title_set(win, "Map");
@@ -524,7 +600,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, "longpressed", my_map_longpressed, map);
         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);
@@ -539,6 +615,8 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
         evas_object_smart_callback_add(map, "downloaded", my_map_downloaded, map);
         evas_object_smart_callback_add(map, "route,load", my_map_route_load, map);
         evas_object_smart_callback_add(map, "route,loaded", my_map_route_loaded, map);
+        evas_object_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_show(map);
 
@@ -569,6 +647,18 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
         elm_table_pack(tb2, bx, 1, 0, 1, 1);
 
         //
+        en = elm_scrolled_entry_add(win);
+        evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+        elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+        elm_scrolled_entry_entry_set(en, NAME_ENTRY_TEXT);
+        elm_scrolled_entry_single_line_set(en, 1);
+        elm_box_pack_end(bx, en);
+        evas_object_smart_callback_add(en, "focused", my_map_entry_focused, win);
+        evas_object_smart_callback_add(en, "activated", my_map_entry_activated, map);
+        evas_object_show(en);
+
+        //
         bt = elm_button_add(win);
         elm_button_label_set(bt, "Add 1000 markers");
         evas_object_smart_callback_add(bt, "clicked", my_bt_add, map);
------------------------------------------------------------------------------
Forrester Wave Report - Recovery time is now measured in hours and minutes
not days. Key insights are discussed in the 2010 Forrester Wave Report as
part of an in-depth evaluation of disaster recovery service providers.
Forrester found the best-in-class provider in terms of services and vision.
Read this report now!  http://p.sf.net/sfu/ibm-webcastpromo
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to