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

Reply via email to