Dear all,
I just implement map rotate feature.
it's the start of turn-by-turn navigation. :)
because of some added APIs, I need your reviews.
you can find demo youtube.
http://www.youtube.com/watch?v=juxKrrHVU4U
pls review this patch.
Thanks.
BR
Index: elementary/src/lib/Elementary.h.in
===================================================================
--- elementary/src/lib/Elementary.h.in (리비전 58720)
+++ elementary/src/lib/Elementary.h.in (작업 사본)
@@ -2270,6 +2270,7 @@ extern "C" {
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 void elm_map_util_3d_rotate(Evas_Object *obj, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz, Evas_Coord *ox, Evas_Coord *oy, Evas_Coord *oz) EINA_ARG_NONNULL(1, 8, 9, 10);
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);
@@ -2312,6 +2313,8 @@ extern "C" {
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);
+ EAPI void elm_map_rotate_set(Evas_Object *obj, double rotate_angle) EINA_ARG_NONNULL(1);
+ EAPI double elm_map_rotate_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
/* smart callbacks called:
* "clicked" - when image clicked
Index: elementary/src/lib/elm_map.c
===================================================================
--- elementary/src/lib/elm_map.c (리비전 58720)
+++ elementary/src/lib/elm_map.c (작업 사본)
@@ -75,6 +75,8 @@ typedef struct _Name_Dump Name_Dump;
#define NOMINATIM_ATTR_LON "lon"
#define NOMINATIM_ATTR_LAT "lat"
+#define _TRANSIT_FOCAL 2000
+
// 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
@@ -388,6 +390,7 @@ struct _Widget_Data
Eina_List *route;
Evas_Event_Mouse_Down ev;
Eina_List *names;
+ double rotate_angle;
};
struct _Mod_Api
@@ -629,6 +632,29 @@ ok:
}
static void
+obj_rotate(void *data, Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(data, widtype);
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ Evas_Coord x, y, w, h;
+ float half_w, half_h;
+ Evas_Map *map = evas_map_new(4);
+ if (!map) return;
+
+ evas_map_util_points_populate_from_object_full(map, obj, 0);
+ evas_object_geometry_get(data, &x, &y, &w, &h);
+ half_w = (float)w * 0.5;
+ half_h = (float)h * 0.5;
+ evas_map_util_3d_rotate(map, 0.0, 0.0, wd->rotate_angle, x + half_w, y + half_h, 0);
+ evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, _TRANSIT_FOCAL);
+ evas_object_map_enable_set(obj, EINA_TRUE);
+ evas_object_map_set(obj, map);
+ evas_map_free(map);
+}
+
+static void
route_place(Evas_Object *obj, Grid *g __UNUSED__, Evas_Coord px, Evas_Coord py, Evas_Coord ox __UNUSED__, Evas_Coord oy __UNUSED__, Evas_Coord ow, Evas_Coord oh)
{
ELM_CHECK_WIDTYPE(obj, widtype);
@@ -641,6 +667,7 @@ route_place(Evas_Object *obj, Grid *g __UNUSED__,
Elm_Map_Route *r;
int nodes;
int x, y, rx, ry;
+
Evas_Coord size = pow(2.0, wd->zoom)*wd->tsize;
EINA_LIST_FOREACH(wd->route, lr, r)
@@ -670,6 +697,7 @@ route_place(Evas_Object *obj, Grid *g __UNUSED__,
evas_object_line_xy_set(p, r->x, r->y, x, y);
evas_object_color_set(p, r->color.r, r->color.g, r->color.b, r->color.a);
evas_object_raise(p);
+ obj_rotate(obj, p);
evas_object_show(p);
r->x = x;
r->y = y;
@@ -849,11 +877,13 @@ marker_place(Evas_Object *obj, Grid *g, Evas_Coord
{
group->update_resize = EINA_FALSE;
evas_object_resize(group->obj, ww, hh);
+ obj_rotate(obj, group->obj);
}
if (group->update_raise)
{
group->update_raise = EINA_FALSE;
evas_object_raise(group->obj);
+ obj_rotate(obj, group->obj);
evas_object_show(group->obj);
}
if (group->bubble) _group_bubble_place(group);
@@ -911,7 +941,7 @@ grid_place(Evas_Object *obj, Grid *g, Evas_Coord p
yy - py + ay + oy);
evas_object_resize(gi->img, ww, hh);
-
+ obj_rotate(obj, gi->img);
/*evas_object_move(gi->txt,
xx - px + ax + ox,
yy - py + ay + oy);
@@ -984,6 +1014,7 @@ _tile_update(Grid_Item *gi)
if (evas_object_image_load_error_get(gi->img) != EVAS_LOAD_ERROR_NONE)
ecore_file_remove(gi->file);
+ obj_rotate(gi->wd->obj, gi->img);
evas_object_show(gi->img);
//evas_object_text_text_set(gi->txt, gi->file);
@@ -1246,7 +1277,10 @@ grid_load(Evas_Object *obj, Grid *g)
if (source) free(source);
}
else if (gi->have)
- evas_object_show(gi->img);
+ {
+ obj_rotate(obj, gi->img);
+ evas_object_show(gi->img);
+ }
}
}
}
@@ -2243,10 +2277,12 @@ _group_bubble_place(Marker_Group *group)
evas_object_move(group->bubble, xx, yy);
evas_object_resize(group->bubble, ww, hh);
+ obj_rotate(group->wd, group->bubble);
evas_object_show(group->bubble);
evas_object_move(group->rect, xx, yy);
evas_object_resize(group->rect, ww, hh);
+ obj_rotate(group->wd, group->rect);
evas_object_show(group->rect);
}
@@ -2753,6 +2789,7 @@ elm_map_add(Evas_Object *parent)
wd->markers_max_num = 30;
wd->source = ELM_MAP_SOURCE_MAPNIK;
+ wd->rotate_angle = 0.0;
evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
@@ -3441,6 +3478,66 @@ elm_map_utils_convert_name_into_coord(const Evas_O
}
/**
+ * Convert a pixel coordinate into a roated pixcel coordinate.
+ *
+ * @param obj The map object
+ * @param dx amount of degrees from 0.0 to 360.0 to rotate arount X axis.
+ * @param dy amount of degrees from 0.0 to 360.0 to rotate arount Y axis.
+ * @param dz amount of degrees from 0.0 to 360.0 to rotate arount Z axis.
+ * @param cx rotation's center horizontal position.
+ * @param cy rotation's center vertical position.
+ * @param cz rotation's center vertical position.
+ * @param ox x to change.
+ * @param oy y to change.
+ * @param oz z to change.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_util_3d_rotate(Evas_Object *obj, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz, Evas_Coord *ox, Evas_Coord *oy, Evas_Coord *oz)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ if ((!ox) || (!oy) || (!oz)) return;
+
+ double rz = (dz * M_PI) / 180.0;
+ double rx = (dx * M_PI) / 180.0;
+ double ry = (dy * M_PI) / 180.0;
+ double x, y, z, xx, yy, zz;
+
+ x = *ox - cx;
+ y = *oy - cy;
+ z = *oz - cz;
+
+ if (rz != 0.0)
+ {
+ xx = x * cos(rz);
+ yy = x * sin(rz);
+ x = xx + (y * cos(rz + M_PI_2));
+ y = yy + (y * sin(rz + M_PI_2));
+ }
+
+ if (ry != 0.0)
+ {
+ xx = x * cos(ry);
+ zz = x * sin(ry);
+ x = xx + (z * cos(ry + M_PI_2));
+ z = zz + (z * sin(ry + M_PI_2));
+ }
+
+ if (rx != 0.0)
+ {
+ zz = z * cos(rx);
+ yy = z * sin(rx);
+ z = zz + (y * cos(rx + M_PI_2));
+ y = yy + (y * sin(rx + M_PI_2));
+ }
+
+ *ox = x + cx;
+ *oy = y + cy;
+ *oz = z + cz;
+}
+
+/**
* Add a marker on the map
*
* @param obj The map object
@@ -4548,7 +4645,14 @@ elm_map_route_waypoint_get(Elm_Map_Route *route)
return route->info.waypoints;
}
-
+/**
+ * Get the information of address
+ *
+ * @param name the name object
+ * @return Returns the address of name
+ *
+ * @ingroup Map
+ */
EAPI const char *
elm_map_name_address_get(Elm_Map_Name *name)
{
@@ -4556,6 +4660,17 @@ elm_map_name_address_get(Elm_Map_Name *name)
return name->address;
}
+/**
+ * Get the current coordinates of the name.
+ *
+ * This gets the current coordinates of the name object.
+ *
+ * @param obj The name object
+ * @param lat The latitude.
+ * @param lon The longitude.
+ *
+ * @ingroup Map
+ */
EAPI void
elm_map_name_region_get(Elm_Map_Name *name, double *lon, double *lat)
{
@@ -4564,6 +4679,13 @@ elm_map_name_region_get(Elm_Map_Name *name, double
if (*lat) *lat = name->lat;
}
+/**
+ * Remove a name from the map
+ *
+ * @param name The name to remove
+ *
+ * @ingroup Map
+ */
EAPI void
elm_map_name_remove(Elm_Map_Name *name)
{
@@ -4586,7 +4708,27 @@ elm_map_name_remove(Elm_Map_Name *name)
}
}
+EAPI void
+elm_map_rotate_set(Evas_Object *obj, double rotate_angle)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->rotate_angle = rotate_angle;
+ wd->calc_job = ecore_job_add(_calc_job, wd);
+}
+
+EAPI double
+elm_map_rotate_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return 0.0;
+
+ return wd->rotate_angle;
+}
+
static char *
_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
{
Index: elementary/src/bin/test_map.c
===================================================================
--- elementary/src/bin/test_map.c (리비전 58720)
+++ elementary/src/bin/test_map.c (작업 사본)
@@ -90,22 +90,29 @@ my_map_clicked_double(void *data, Evas_Object *obj
{
double lon, lat;
double flon, flat, tlon, tlat;
- Evas_Coord ox, oy, x, y, w, h;
+ Evas_Coord ox, oy, x, y, z, w, h, rx, ry;
int zoom;
+ double angle;
+ Evas_Coord size;
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);
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, 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);
+ elm_map_utils_convert_geo_into_coord(obj, lon, lat, size, &x, &y);
+ rx = x;
+ ry = y;
+ x += down->output.x - ((float)w * 0.5) - ox;
+ y += down->output.y - ((float)h * 0.5) - oy;
+ angle = elm_map_rotate_get(data);
+ elm_map_util_3d_rotate(data, 0.0, 0.0, -angle, rx, ry, 0, &x, &y, &z);
+ elm_map_utils_convert_coord_into_geo(obj, x, y, size, &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);
@@ -117,9 +124,9 @@ my_map_clicked_double(void *data, Evas_Object *obj
if (route_from && route_to)
{
elm_map_marker_remove(route_from);
- route_from = NULL;
+ route_from = NULL;
elm_map_marker_remove(route_to);
- route_to = NULL;
+ route_to = NULL;
elm_map_route_remove(route);
}
@@ -284,6 +291,24 @@ my_bt_zoom_in(void *data, Evas_Object *obj __UNUSE
}
static void
+my_bt_rotate_cw(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ double r = elm_map_rotate_get(data);
+ double rt = r + 15.0;
+ printf("rotate %lf to %lf\n", r, rt);
+ elm_map_rotate_set(data, rt);
+}
+
+static void
+my_bt_rotate_ccw(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ double r = elm_map_rotate_get(data);
+ double rt = r - 15.0;
+ printf("rotate %lf to %lf\n", r, rt);
+ elm_map_rotate_set(data, rt);
+}
+
+static void
my_bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
double zoom;
@@ -380,7 +405,7 @@ my_bt_add(void *data, Evas_Object *obj __UNUSED__,
style = rand() % 2;
if (!style) g_clas = itc_group1;
- else g_clas = itc_group2;
+ else g_clas = itc_group2;
markers[i] = elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d);
}
@@ -712,6 +737,22 @@ test_map(void *data __UNUSED__, Evas_Object *obj _
evas_object_size_hint_align_set(bt, 0.1, 0.9);
evas_object_show(bt);
elm_box_pack_end(bx, bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "R +");
+ evas_object_smart_callback_add(bt, "clicked", my_bt_rotate_cw, map);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, 0.1, 0.9);
+ evas_object_show(bt);
+ elm_box_pack_end(bx, bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "R -");
+ evas_object_smart_callback_add(bt, "clicked", my_bt_rotate_ccw, map);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, 0.1, 0.9);
+ evas_object_show(bt);
+ elm_box_pack_end(bx, bt);
//
//
------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve
application availability and disaster protection. Learn more about boosting
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel