Hi,
In my point of view, elm_map did not consider zooming & rotation by
using Evas_Map initially.
There are no problems if you use only elm_map_zoom_set(). But if you
use pinch gesture or wheel to do subtle zooming & rotating, the
calculations of coordinates are not correct currently.
I have fixed these problem and also made some utility APIs for user convenience.
I made following 3 APIs.
1. elm_map_utils_size_get()
Currently users can only get integer zoom level by using elm_map_zoom_get().
So if user want to calculate full map size, user should calculate
pow(2.0, zoom level) * tile size. Furthermore, user assumes tile size
as 256. (tile size can be changed!!)
Also it's not correct sometimes because Evas_map is used for subtle
zooming between zoom levels.
Above APIs return correct full map size.
2. elm_map_utils_region_get()
It can used for getting left top coordinates, center coordinates and
width, height of currently shown map area.
3. elm_map_utils_convert_canvas_into_geo()
Currently it is hard to converting x, y coordinates to geographical
longitude, latitude because of subtle zooming & rotating.
If use wants to get it, user uses combination of above functions and
more. It is harsh job.
This function is used for getting longitude, latitude from x, y
coordinates of current viewport.
Test application can be brief by using above functions .
Please review this patch.
--
BRs,
Kim.
Index: src/lib/elm_map.c
===================================================================
--- src/lib/elm_map.c (리비전 66738)
+++ src/lib/elm_map.c (작업 사본)
@@ -3357,17 +3357,16 @@ elm_map_geo_region_get(const Evas_Object
#ifdef HAVE_ELEMENTARY_ECORE_CON
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
- Evas_Coord sx, sy, sw, sh;
-
- if (!wd) return;
- elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
- elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
- if (wd->size.w < sw) sw = wd->size.w;
- if (wd->size.h < sh) sh = wd->size.h;
- sx += sw / 2;
- sy += sh / 2;
-
- elm_map_utils_convert_coord_into_geo(obj, sx, sy, wd->size.w, lon, lat);
+ Evas_Coord cx, cy;
+ int rw;
+ double tlon, tlat;
+ EINA_SAFETY_ON_NULL_RETURN(wd);
+
+ elm_map_utils_region_get(obj, NULL, NULL, &cx, &cy, NULL, NULL);
+ elm_map_utils_size_get(obj, &rw, NULL);
+ elm_map_utils_convert_coord_into_geo(obj, cx, cy, rw, &tlon, &tlat);
+ if (lon) *lon = tlon;
+ if (lat) *lat = tlat;
#else
(void) obj;
(void) lon;
@@ -3569,10 +3568,48 @@ elm_map_utils_convert_name_into_coord(co
}
EAPI void
-elm_map_utils_rotate_coord(const Evas_Object *obj __UNUSED__, 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)
+elm_map_utils_convert_canvas_into_geo(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, double *lon, double *lat)
{
#ifdef HAVE_ELEMENTARY_ECORE_CON
- if ((!xx) || (!yy)) return;
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ EINA_SAFETY_ON_NULL_RETURN(lon);
+ EINA_SAFETY_ON_NULL_RETURN(lat);
+
+ Evas_Coord xx, yy, w, h, mw, tx, ty, cx, cy;
+ double d;
+
+ elm_map_utils_region_get(obj, &xx, &yy, &cx, &cy, &w, &h);
+ elm_map_utils_size_get(obj, &mw, NULL);
+ if (w < mw)
+ {
+ xx += x;
+ yy += y;
+ }
+ else
+ {
+ xx = x - xx;
+ yy = y - yy;
+ }
+
+ elm_map_rotate_get(obj, &d, NULL, NULL);
+ elm_map_utils_rotate_coord(obj, xx, yy, cx, cy, -d, &tx, &ty);
+ elm_map_utils_convert_coord_into_geo(obj, tx, ty, mw, lon, lat);
+#else
+ (void) obj;
+ (void) x;
+ (void) y;
+ (void) lon;
+ (void) lat;
+#endif
+}
+
+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
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ EINA_SAFETY_ON_NULL_RETURN(xx);
+ EINA_SAFETY_ON_NULL_RETURN(yy);
double r = (degree * M_PI) / 180.0;
double tx, ty, ttx, tty;
@@ -3598,6 +3635,81 @@ elm_map_utils_rotate_coord(const Evas_Ob
#endif
}
+EAPI void
+elm_map_utils_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *w, Evas_Coord *h)
+{
+#ifdef HAVE_ELEMENTARY_ECORE_CON
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord sx, sy, tx, ty, tcx, tcy, sw, sh, tw, th, rw, rh;
+ EINA_SAFETY_ON_NULL_RETURN(wd);
+
+ elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
+ elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
+ rw = wd->size.w * wd->pinch.level;
+ rh = wd->size.h * wd->pinch.level;
+
+ if (wd->size.w < sw)
+ {
+ tw = rw;
+ tcx = sx + tw/2;
+ tx = sx + (sw - tw)/2;
+ }
+ else
+ {
+ tw = sw;
+ tcx = (sx + tw/2) * wd->pinch.level;
+ tx = tcx - tw/2;
+
+ }
+ if (wd->size.h < sh)
+ {
+ th = rh;
+ ty = sy + (sh - th)/2;
+ tcy = sy + th/2;
+ }
+ else
+ {
+ th = sw;
+ tcy = (sy + th/2) * wd->pinch.level;
+ ty = tcy - th/2;
+ }
+
+ if (x) *x = tx;
+ if (y) *y = ty;
+ if (cx) *cx= tcx;
+ if (cy) *cy = tcy;
+ if (w) *w = tw;
+ if (h) *h = th;
+#else
+ (void) obj;
+ (void) x;
+ (void) y;
+ (void) cx;
+ (void) cy;
+ (void) w;
+ (void) h;
+#endif
+}
+
+EAPI void
+elm_map_utils_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *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);
+
+ if (w) *w = wd->size.w * wd->pinch.level;
+ if (h) *h = wd->size.h * wd->pinch.level;
+#else
+ (void) obj;
+ (void) w;
+ (void) h;
+#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 *clas_group, void *data)
{
Index: src/lib/elm_map.h
===================================================================
--- src/lib/elm_map.h (리비전 66738)
+++ src/lib/elm_map.h (작업 사본)
@@ -266,7 +266,7 @@ EAPI void elm_map_zoom_
EAPI Elm_Map_Zoom_Mode elm_map_zoom_mode_get(const Evas_Object *obj);
/**
- * Get the current coordinates of the map.
+ * Get the current geographic coordinates of the map.
*
* @param obj The map object.
* @param lon Pointer where to store longitude.
@@ -494,6 +494,34 @@ EAPI Elm_Map_Name *elm_map_utils
EAPI Elm_Map_Name *elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address);
/**
+ * Convert canvas coordinates into a geographic coordinate
+ * (longitude, latitude).
+ *
+ * @param obj The map object.
+ * @param x horizontal coordinate of the point to convert.
+ * @param y vertical coordinate of the point to convert.
+ * @param lon A poniter to the longitude.
+ * @param lat A pointer to the latitude.
+ *
+ * This gets longitude and latitude from canvas x, y coordinates. The canvas
+ * coordinates mean x, y coordinate from current viewport.
+ * This function uses elm_map_utils_region_get(), elm_map_utils_size_get(),
+ * elm_map_rotate_get(), elm_map_utils_rotate_coord(),
+ * elm_map_utils_convert_coord_into_geo() internally to get the geographic
+ * location.
+ *
+ * see elm_map_utils_region_get()
+ * see elm_map_utils_size_get()
+ * see elm_map_rotate_get()
+ * see elm_map_utils_rotate_coord()
+ * see elm_map_utils_convert_coord_into_geo()
+ *
+ * @ingroup Map
+ */
+EAPI void elm_map_utils_convert_canvas_into_geo(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, double *lon, double *lat);
+
+
+/**
* Convert a pixel coordinate into a rotated pixel coordinate.
*
* @param obj The map object.
@@ -510,6 +538,42 @@ EAPI Elm_Map_Name *elm_map_utils
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);
/**
+ * Get the pixel area of the currenlty shown map.
+ *
+ * @param obj The map object.
+ * @param x A pointer to the X-coordinate of region.
+ * @param y A pointer to the Y-coordinate of region.
+ * @param cx A pointer to the center X-coordinate of region.
+ * @param cy A pointer to the center Y-coordinate of region.
+ * @param w A pointer to the width.
+ * @param h A pointer to the height.
+ *
+ * This gets the area of the map that is currently shown. The area is not
+ * rotated area. If you want to get the rotated area, you should use
+ * elm_map_rotate_get() and elm_map_utils_rotate_coord() if you want to
+ * convert these coordinates to exactly rotated coordinates.
+ *
+ * @see elm_map_rotate_get()
+ * @see elm_map_utils_rotate_coord()
+ *
+ * @ingroup Map
+ */
+EAPI void elm_map_utils_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *w, Evas_Coord *h);
+
+/**
+ * Get the entire pixel size of the map.
+ *
+ * @param obj The map object.
+ * @param w A pointer to the width.
+ * @param h A pointer to the height.
+ *
+ * This gets the entire pixel size of the map that is currently shown as well as that is not shown.
+ *
+ * @ingroup Map
+ */
+EAPI void elm_map_utils_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+
+/**
* Add a new marker to the map object.
*
* @param obj The map object.
Index: src/bin/test_map.c
===================================================================
--- src/bin/test_map.c (리비전 66738)
+++ src/bin/test_map.c (작업 사본)
@@ -86,59 +86,36 @@ my_map_press(void *data __UNUSED__, Evas
}
static void
-my_map_longpressed(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+my_map_longpressed(void *data __UNUSED__, Evas_Object *obj, void *event_info)
{
printf("longpressed\n");
double lon, lat;
- Evas_Coord ox, oy, x, y, w, h;
- int zoom;
Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
if (!down) return;
+ if (elm_map_zoom_get(obj) < 5) 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->canvas.x - (w / 2) - ox;
- y += down->canvas.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);
+ elm_map_utils_convert_canvas_into_geo(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);
+ name = elm_map_utils_convert_coord_into_name(obj, lon, lat);
}
static void
-my_map_clicked_double(void *data, Evas_Object *obj, void *event_info)
+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_Coord ox, oy, x, y, w, h, rx, ry, tx, ty;
- double d;
- int zoom;
- Evas_Coord size;
Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
if (!down) return;
+ if (elm_map_zoom_get(obj) < 5) return;
- evas_object_geometry_get(data, &ox, &oy, &w, &h);
- zoom = elm_map_zoom_get(data);
- if (zoom < 5) return;
- size = pow(2.0, zoom) * 256;
- elm_map_geo_region_get(obj, &lon, &lat);
- elm_map_utils_convert_geo_into_coord(obj, lon, lat, size, &x, &y);
-
- rx = x;
- ry = y;
- x += down->canvas.x - ((float)w * 0.5) - ox;
- y += down->canvas.y - ((float)h * 0.5) - oy;
- elm_map_rotate_get(data, &d, NULL, NULL);
- elm_map_utils_rotate_coord(data, x, y, rx, ry, -d, &tx, &ty);
- elm_map_utils_convert_coord_into_geo(obj, tx, ty, size, &lon, &lat);
-
- itc1 = elm_map_marker_class_new(data);
+ elm_map_utils_convert_canvas_into_geo(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);
+ itc1 = elm_map_marker_class_new(obj);
elm_map_marker_class_del_cb_set(itc1, NULL);
- itc_group1 = elm_map_group_class_new(data);
+ itc_group1 = elm_map_group_class_new(obj);
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");
@@ -153,14 +130,14 @@ my_map_clicked_double(void *data, Evas_O
elm_map_route_remove(route);
}
- if (!route_from) route_from = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
- else route_to = elm_map_marker_add(data, lon, lat, itc1, itc_group1, NULL);
+ if (!route_from) route_from = elm_map_marker_add(obj, lon, lat, itc1, itc_group1, NULL);
+ else route_to = elm_map_marker_add(obj, lon, lat, itc1, itc_group1, NULL);
if (route_from && route_to)
{
elm_map_marker_region_get(route_from, &flon, &flat);
elm_map_marker_region_get(route_to, &tlon, &tlat);
- route = elm_map_route_add(data, ELM_MAP_ROUTE_TYPE_MOTOCAR, ELM_MAP_ROUTE_METHOD_FASTEST, flon, flat, tlon, tlat);
+ route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR, ELM_MAP_ROUTE_METHOD_FASTEST, flon, flat, tlon, tlat);
elm_map_route_color_set(route, 255, 0, 0, 255);
}
}
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel