summaryrefslogtreecommitdiffstats
path: root/friendfinder/map
diff options
context:
space:
mode:
authorPatrick Hornecker2009-12-21 16:07:36 +0100
committerPatrick Hornecker2009-12-21 16:07:36 +0100
commit3cefadd098bb72a087406ecc09c1c04f1dca0ab5 (patch)
treebbec3ea006ac2abc6bdf52f00ca2b970f27274d9 /friendfinder/map
parentfew changes (diff)
downloadfriendfinder-3cefadd098bb72a087406ecc09c1c04f1dca0ab5.tar.gz
friendfinder-3cefadd098bb72a087406ecc09c1c04f1dca0ab5.tar.xz
friendfinder-3cefadd098bb72a087406ecc09c1c04f1dca0ab5.zip
file locations reorderd, map in gui...build problems on local machine
Diffstat (limited to 'friendfinder/map')
-rw-r--r--friendfinder/map/.map_reader.c.swpbin0 -> 12288 bytes
-rw-r--r--friendfinder/map/controls.c146
-rw-r--r--friendfinder/map/e_smart_tile.h31
-rw-r--r--friendfinder/map/map_reader.c141
-rw-r--r--friendfinder/map/object.c176
-rw-r--r--friendfinder/map/overlay.c257
-rw-r--r--friendfinder/map/smart_map_priv.h166
7 files changed, 917 insertions, 0 deletions
diff --git a/friendfinder/map/.map_reader.c.swp b/friendfinder/map/.map_reader.c.swp
new file mode 100644
index 0000000..ae96628
--- /dev/null
+++ b/friendfinder/map/.map_reader.c.swp
Binary files differ
diff --git a/friendfinder/map/controls.c b/friendfinder/map/controls.c
new file mode 100644
index 0000000..89eee55
--- /dev/null
+++ b/friendfinder/map/controls.c
@@ -0,0 +1,146 @@
+#include <Elementary.h>
+#include "../vkbd/vkbd.h"
+
+#include "../map/smart_map_priv.h"
+
+static void
+cb_exit(void *data, Evas_Object *obj, void *event_info)
+{
+ elm_exit();
+}
+
+
+static void
+_cb_hide(void *data, Evas_Object *obj, void *event_info)
+{
+ struct smart_map *smart = (struct smart_map *)data;
+
+ overlay_hide(smart, "xxx");
+}
+
+
+static void
+_kbd_show(void *data, Evas_Object *o, void *event_info)
+{
+ struct controls *ctrl = data;
+ vkbd_show(ctrl->vkbd, 240, 320, NULL);
+}
+
+
+
+static void _cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ struct smart_map *smart = (struct smart_map *)data;
+ smart->moved = 0;
+ smart->drag = 1;
+}
+
+static void _cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ struct smart_map *smart = (struct smart_map *)data;
+ Evas_Event_Mouse_Up *ev = event;
+ double lat = 0, lon = 0;
+ int ox, oy;
+
+ smart->drag = 0;
+ if(smart->moved)
+ {
+ smart->moved = 0;
+ return;
+ }
+
+ ox = smart->ta.ox + ev->output.x;
+ oy = smart->ta.oy + ev->output.y;
+ map_to_latlon(smart->li, ox, oy, &lat, &lon);
+
+ char buffer[512];
+ snprintf(buffer, 512, "point: %lf * %lf", lat, lon);
+ edje_object_part_text_set(smart->theme, "position", buffer);
+
+}
+
+static void _cb_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ Evas_Event_Mouse_Move *ev = event;
+
+ struct smart_map *smart = (struct smart_map *)data;
+ Evas_Coord dx, dy;
+
+ if(!smart->drag)
+ return;
+
+ smart->moved = 1;
+ dx = ev->cur.canvas.x - ev->prev.canvas.x;
+ dy = ev->cur.canvas.y - ev->prev.canvas.y;
+
+ e_smart_map_move(smart->obj, -dx, -dy);
+}
+
+void init_clickarea(struct smart_map *smart)
+{
+ struct controls *ctrl = &smart->c;
+
+ ctrl->ctrl = evas_object_rectangle_add(smart->evas);
+ evas_object_smart_member_add(ctrl->ctrl, smart->obj);
+ evas_object_color_set(ctrl->ctrl, 0, 0, 0, 0);
+ evas_object_clip_set(ctrl->ctrl, smart->clip);
+ evas_object_repeat_events_set(ctrl->ctrl, 1);
+ evas_object_show(ctrl->ctrl);
+
+ evas_object_event_callback_add(ctrl->ctrl, EVAS_CALLBACK_MOUSE_DOWN,
+ _cb_mouse_down, smart);
+ evas_object_event_callback_add(ctrl->ctrl, EVAS_CALLBACK_MOUSE_UP,
+ _cb_mouse_up, smart);
+ evas_object_event_callback_add(ctrl->ctrl, EVAS_CALLBACK_MOUSE_MOVE,
+ _cb_mouse_move, smart);
+}
+
+int controls_init(struct smart_map *smart)
+{
+ struct controls *ctrl;
+
+ if(!smart || !smart->win)
+ return -1;
+
+ init_clickarea(smart);
+ ctrl = &smart->c;
+ /*
+ ctrl->bx = elm_box_add(smart->win);
+ evas_object_size_hint_weight_set(ctrl->bx, 1.0, 1.0);
+ elm_win_resize_object_add(smart->win, ctrl->bx);
+ evas_object_show(ctrl->bx);
+
+ ctrl->bt = elm_hoversel_add(smart->win);
+ elm_hoversel_hover_parent_set(ctrl->bt, smart->obj);
+ elm_hoversel_label_set(ctrl->bt, "Menu");
+ elm_hoversel_item_add(ctrl->bt, "Item 1", "apps",
+ ELM_ICON_STANDARD, NULL, NULL);
+ elm_hoversel_item_add(ctrl->bt, "Item 2", "arrow_down",
+ ELM_ICON_STANDARD, _cb_hide, smart);
+ elm_hoversel_item_add(ctrl->bt, "Item 3", "home",
+ ELM_ICON_STANDARD, _kbd_show, ctrl);
+ elm_hoversel_item_add(ctrl->bt, "Item 4", "close",
+ ELM_ICON_STANDARD, cb_exit, NULL);
+ evas_object_size_hint_weight_set(ctrl->bt, 1.0, 1.0);
+ evas_object_size_hint_align_set(ctrl->bt, 1.0, 1.0);
+ elm_box_pack_end(ctrl->bx, ctrl->bt);
+ evas_object_show(ctrl->bt);
+ */
+#if 0
+ Evas_Object *bt = elm_button_add(win);
+ elm_button_label_set(bt, "Button");
+ Evas_Object *bx = elm_box_add(win);
+ evas_object_size_hint_weight_set(bx, 1.0, 1.0);
+ elm_win_resize_object_add(win, bx);
+ elm_box_pack_end(bx, bt);
+
+ evas_object_show(bx);
+
+ evas_object_size_hint_align_set(bt, 1.0, -1.0);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+#endif
+ ctrl->vkbd = vkbd_add(smart->evas);
+ return 0;
+}
diff --git a/friendfinder/map/e_smart_tile.h b/friendfinder/map/e_smart_tile.h
new file mode 100644
index 0000000..1a35df3
--- /dev/null
+++ b/friendfinder/map/e_smart_tile.h
@@ -0,0 +1,31 @@
+#ifndef _E_SMART_TILE
+#define _E_SMART_TILE
+
+
+struct tile_array
+{
+ Evas_Object **tiles;
+ int tw, th;
+ int ox, oy;
+ int mode;
+ double lat, lon;
+ int w, h;
+};
+
+struct osm_data
+{
+ int x, y, z;
+};
+
+static inline char *osm_string(struct osm_data *osm)
+{
+ static char buf[64];
+ snprintf(buf, 64, "%i/%i/%i", osm->z, osm->x, osm->y);
+ return buf;
+}
+
+Evas_Object *e_smart_tile_add(Evas *e);
+struct osm_data *e_smart_tile_load(Evas_Object *tile, const char *path, int z, int x, int y);
+struct osm_data *e_smart_tile_unload(Evas_Object *tile);
+struct osm_data *e_smart_tile_needs_update(Evas_Object *tile, int z, int x, int y);
+#endif
diff --git a/friendfinder/map/map_reader.c b/friendfinder/map/map_reader.c
new file mode 100644
index 0000000..fb475fc
--- /dev/null
+++ b/friendfinder/map/map_reader.c
@@ -0,0 +1,141 @@
+#include <string.h>
+#include <Eet.h>
+
+#include "smart_map_priv.h"
+
+#define READ_KEY_INIT char key[512]
+#define LKEY(_le, _mk) snprintf(key, 512, "%i/%s", _le, _mk);
+
+static inline int _read_int_val(Eet_File *eet, char *key, int *intval)
+{
+ int size;
+ char *val;
+ val = eet_read(eet, key, &size);
+ if(val == NULL)
+ {
+ // _warn("reading %s failed\n", key);
+ return -1;
+ }
+ *intval = atoi(val);
+ free(val);
+ return 0;
+}
+
+static inline int _read_double_val(Eet_File *eet, char *key, double *dval)
+{
+ int size;
+ char *val;
+ val = eet_read(eet, key, &size);
+ if(val == NULL)
+ {
+ // _warn("reading %s failed\n", key);
+ return -1;
+ }
+
+ *dval = atof(val);
+ free(val);
+ return 0;
+}
+
+
+struct map_info *map_info_read(const char *path)
+{
+ Eet_File *eet;
+ int size, i;
+ char *val;
+ struct map_info *mi;
+
+ mi = (struct map_info *)calloc(1, sizeof(struct map_info));
+ if(mi == NULL)
+ return NULL;
+
+ eet = eet_open(path, EET_FILE_MODE_READ);
+ if(eet == NULL)
+ return NULL;
+
+ val = eet_read(eet, "min_level", &size);
+ if(val == NULL)
+ return NULL;
+ mi->min_level = atoi(val);
+ free(val);
+
+ val = eet_read(eet, "max_level", &size);
+ if(val == NULL)
+ return NULL;
+ mi->max_level = atoi(val);
+ free(val);
+ mi->level = (struct map_level_info *)
+ calloc(mi->max_level - mi->min_level + 1,
+ sizeof(struct map_level_info));
+ if(mi->level == NULL)
+ {
+ free(mi);
+ return NULL;
+ }
+ mi->tile_size = 256;
+ for(i = mi->min_level; i < mi->max_level + 1; i++)
+ {
+ READ_KEY_INIT;
+ struct map_level_info *li;
+
+ li = &mi->level[i - mi->min_level];
+
+ LKEY(i, "min_x");
+ if(_read_int_val(eet, key, &(li->min_x)))
+ goto failure;
+
+ LKEY(i, "max_x");
+ if(_read_int_val(eet, key, &(li->max_x)))
+ goto failure;
+
+ LKEY(i, "min_y");
+ if(_read_int_val(eet, key, &(li->min_y)))
+ goto failure;
+
+ LKEY(i, "max_y");
+ if(_read_int_val(eet, key, &(li->max_y)))
+ goto failure;
+
+ LKEY(i, "north");
+ if(_read_double_val(eet, key, &(li->north)))
+ goto failure;
+
+ LKEY(i, "west");
+ if(_read_double_val(eet, key, &(li->west)))
+ goto failure;
+
+ LKEY(i, "south");
+ if(_read_double_val(eet, key, &(li->south)))
+ goto failure;
+
+ LKEY(i, "east");
+ if(_read_double_val(eet, key, &(li->east)))
+ goto failure;
+
+ LKEY(i, "dx");
+ if(_read_double_val(eet, key, &(li->dx)))
+ goto failure;
+
+ LKEY(i, "dy");
+ if(_read_double_val(eet, key, &(li->dy)))
+ goto failure;
+
+ LKEY(i, "e0");
+ if(_read_double_val(eet, key, &(li->e0)))
+ goto failure;
+
+ LKEY(i, "n0");
+ if(_read_double_val(eet, key, &(li->n0)))
+ goto failure;
+ }
+ mi->path = strdup(path);
+ eet_close(eet);
+ return mi;
+failure:
+ free(mi->level);
+ free(mi);
+ return NULL;
+}
+
+
+
diff --git a/friendfinder/map/object.c b/friendfinder/map/object.c
new file mode 100644
index 0000000..f4f4c0b
--- /dev/null
+++ b/friendfinder/map/object.c
@@ -0,0 +1,176 @@
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Edje.h>
+
+#include "e_smart_tile.h"
+
+#include "smart_map_priv.h"
+
+static void tile_array_add(struct smart_map *smart, int index)
+{
+ smart->ta.tiles[index] = e_smart_tile_add(smart->evas);
+ evas_object_smart_member_add(smart->ta.tiles[index], smart->obj);
+ evas_object_clip_set(smart->ta.tiles[index], smart->clip);
+ evas_object_pass_events_set(smart->ta.tiles[index], 1);
+ evas_object_stack_below(smart->ta.tiles[index], smart->clip);
+}
+
+static int tile_array_resize(struct tile_array *ta, struct smart_map *smart, int tw, int th)
+{
+ int i;
+ if(ta->tiles == NULL)
+ {
+ ta->tiles = calloc(1, tw * th * sizeof(Evas_Object *));
+ if(ta->tiles == NULL)
+ return -1;
+ ta->tw = tw;
+ ta->th = th;
+ for(i = 0; i < tw*th; i++)
+ tile_array_add(smart, i);
+ return 0;
+ }
+
+ int oldsize = smart->ta.tw * smart->ta.th;
+ if(oldsize < tw*th)
+ {
+ ta->tiles = realloc(ta->tiles, tw * th * sizeof(Evas_Object *));
+ if(smart->ta.tiles == NULL)
+ return -1;
+
+ for(i = oldsize; i < tw*th; i++)
+ tile_array_add(smart, i);
+ }
+ else
+ {
+ for(i = tw*th; i < oldsize; i++)
+ {
+ evas_object_del(ta->tiles[i]);
+ evas_object_smart_member_del(ta->tiles[i]);
+ }
+
+ ta->tiles = realloc(ta->tiles,
+ tw * th * sizeof(Evas_Object *));
+ if(ta->tiles == NULL)
+ return -1;
+ }
+ ta->tw = tw;
+ ta->th = th;
+ return 0;
+}
+
+static inline int tile_array_update(struct tile_array *ta, struct map_level_info *li)
+{
+ if(ta->mode == POSITION_WORLD)
+ {
+ if(latlon_to_map(li, ta->lat, ta->lon, &ta->ox, &ta->oy) < 0)
+ return -1;
+ ta->ox -= ta->w/2;
+ ta->oy -= ta->h/2;
+ ta->mode = POSITION_PX;
+ }
+ else
+ {
+ if(map_to_latlon(li, ta->ox + ta->w/2, ta->oy + ta->h/2, &ta->lat, &ta->lon) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int fill_tiles(struct smart_map *smart)
+{
+ int tx, ty;
+ int xmin, ymin, xoffset, yoffset;
+ int tile_size = smart->mi->tile_size;
+ struct tile_array *ta = &smart->ta;
+ Eina_Array_Iterator iterator;
+ int i;
+ Evas_Object *path;
+
+ if(smart->li == NULL)
+ return -1;
+
+ tile_array_update(ta, smart->li);
+
+ EINA_ARRAY_ITER_NEXT(smart->paths, i, path, iterator)
+ {
+ evas_object_move(path, ta->ox, ta->oy);
+ evas_object_show(path);
+ }
+
+ xmin = ta->ox / tile_size + smart->li->min_x - 1;
+ ymin = ta->oy / tile_size + smart->li->min_y - 1;
+ xoffset = -ta->ox % tile_size;
+ yoffset = -ta->oy % tile_size;
+ for(ty = 0; ty < ta->th; ty++)
+ {
+ Evas_Coord y0;
+ y0 = (ty - 1) * tile_size;
+ for(tx = 0; tx < ta->tw; tx++)
+ {
+ Evas_Coord x0;
+ struct osm_data *osm;
+ Evas_Object *o;
+
+ x0 = (tx - 1) * tile_size;
+ o = ta->tiles[ty * ta->tw + tx];
+ if(o == NULL)
+ return -1;
+
+ if(xmin + tx < smart->li->min_x || xmin + tx > smart->li->max_x ||
+ ymin + ty < smart->li->min_y || ymin + ty > smart->li->max_y)
+ {
+ osm = e_smart_tile_unload(o);
+ overlay_unload(smart, osm);
+ }
+ else
+ {
+ osm = e_smart_tile_needs_update(o,
+ smart->current_level, xmin + tx, ymin + ty);
+ if(osm != NULL)
+ overlay_unload(smart, osm);
+
+ osm = e_smart_tile_load(o, smart->mi->path,
+ smart->current_level, xmin + tx, ymin + ty);
+ if(osm == NULL)
+ continue;
+ }
+ evas_object_move(o, smart->x + xoffset + x0, smart->y + yoffset + y0);
+ evas_object_resize(o, tile_size, tile_size);
+ evas_object_show(o);
+ overlay_update(smart, osm, smart->x + xoffset + x0, smart->y + yoffset + y0);
+ }
+ }
+ return 0;
+}
+
+int map_object_update(struct smart_map *smart)
+{
+ int tw, th;
+ int ret, ts = smart->mi->tile_size;
+ char buffer[512];
+
+ tw = 2 + (((double)smart->w + ts) / ts);
+ th = 2 + (((double)smart->h + ts) / ts);
+ if(tw != smart->ta.tw || th != smart->ta.th)
+ {
+ if(tile_array_resize(&smart->ta, smart, tw, th) < 0)
+ return -1;
+ }
+ ret = fill_tiles(smart);
+ if(ret < 0)
+ return -1;
+
+ if(smart->theme == NULL)
+ return 0;
+
+ snprintf(buffer, 512, "%lf * %lf", smart->ta.lat, smart->ta.lon);
+ smart->lat = smart->ta.lat;
+ smart->lon = smart->ta.lon;
+ edje_object_part_text_set(smart->theme, "position", buffer);
+ return 0;
+}
diff --git a/friendfinder/map/overlay.c b/friendfinder/map/overlay.c
new file mode 100644
index 0000000..1566040
--- /dev/null
+++ b/friendfinder/map/overlay.c
@@ -0,0 +1,257 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Edje.h>
+#include <Elementary.h>
+#include <Eina.h>
+
+#include "e_smart_tile.h"
+
+#include "smart_map_priv.h"
+
+struct map_overlay *overlay_find_by_name(struct smart_map *smart, char *name)
+{
+ int i;
+ struct map_overlay *ov = NULL;
+ Eina_Array_Iterator iterator;
+
+ EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
+ {
+ if(strcmp(ov->name, name) == 0)
+ return ov;
+ }
+ return NULL;
+}
+
+struct map_overlay *overlay_create(struct smart_map *smart, char *name)
+{
+ int i;
+ struct map_overlay *ov = malloc(sizeof(struct map_overlay));
+ if(ov == NULL)
+ return NULL;
+
+ eina_array_init();
+ ov->name = strdup(name);
+ ov->parent = smart;
+ ov->state = OVERLAY_VISIBLE;
+
+ ov->hash = eina_hash_string_superfast_new(NULL);
+ for(i = 0; i < OSM_LEVEL_COUNT; i++)
+ ov->pois[i] = NULL;
+
+ ov->current_level = -1;
+ return ov;
+}
+
+void overlay_add(struct smart_map *smart, struct map_overlay *ov, struct overlay_item *poi)
+{
+ int i;
+ if(ov == NULL)
+ return;
+
+ for(i = 1; i < OSM_LEVEL_COUNT; i++)
+ {
+ unsigned int mask = 1<<i;
+ if(!(poi->level_mask & mask))
+ continue;
+
+ if(ov->pois[i] == NULL)
+ ov->pois[i] = eina_array_new(4);
+
+ eina_array_push(ov->pois[i], poi);
+ }
+}
+
+static void _hash_item(struct smart_map *smart, struct map_overlay *ov, struct overlay_item *poi, int level)
+{
+ int x, y, tx, ty;
+ char buf[64];
+ Eina_Array *items;
+ struct map_level_info *li;
+ li = map_info_get_level(smart->mi, &level);
+
+ if(latlon_to_map(li, poi->lat, poi->lon, &x, &y) < 0)
+ return;
+
+ tx = x / smart->mi->tile_size + li->min_x;
+ ty = y / smart->mi->tile_size + li->min_y;
+ poi->level_data.ox = x % smart->mi->tile_size;
+ poi->level_data.oy = y % smart->mi->tile_size;
+ poi->level_data.visible = 1;
+
+ snprintf(buf, 64, "%i/%i/%i", level, tx, ty);
+ items = eina_hash_find(ov->hash, (const void *)buf);
+ if(items == NULL)
+ {
+ items = eina_array_new(4);
+ eina_array_push(items, poi);
+ eina_hash_add(ov->hash, buf, items);
+ }
+ else
+ {
+ eina_array_push(items, poi);
+ }
+}
+
+static void _overlay_hide(struct smart_map *smart, struct map_overlay *ov, int newstate)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct overlay_item *poi;
+
+ if(ov->state == OVERLAY_HIDDEN)
+ return;
+
+ if(ov->current_level <= 0)
+ return;
+
+ if(ov->pois[ov->current_level] == NULL)
+ return;
+ ov->state = newstate;
+
+ EINA_ARRAY_ITER_NEXT(ov->pois[ov->current_level], i, poi, iterator)
+ {
+ evas_object_hide(poi->obj->obj);
+ }
+}
+
+void overlay_hide(struct smart_map *smart, char *name)
+{
+ struct map_overlay *ov = overlay_find_by_name(smart, name);
+ if(ov == NULL)
+ return;
+
+ _overlay_hide(smart, ov, OVERLAY_HIDDEN);
+}
+
+void overlay_hide_all(struct smart_map *smart)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct map_overlay *ov;
+
+
+ EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
+ {
+ _overlay_hide(smart, ov, OVERLAY_HIDDEN);
+ }
+}
+
+static void _overlay_change_level(struct smart_map *smart, struct map_overlay *ov, int level)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct overlay_item *poi;
+
+ if(level >= OSM_LEVEL_COUNT)
+ {
+ printf("overlay_change_level: level %i not supported\n", level);
+ return;
+ }
+
+ if(ov->current_level > 0 && ov->current_level < OSM_LEVEL_COUNT)
+ _overlay_hide(smart, ov, ov->state);
+
+ eina_hash_free(ov->hash); //XXX
+ ov->hash = eina_hash_string_superfast_new(NULL);
+ ov->current_level = level;
+
+ if(ov->pois[level] == NULL)
+ return;
+
+ EINA_ARRAY_ITER_NEXT(ov->pois[level], i, poi, iterator)
+ {
+ _hash_item(smart, ov, poi, level);
+ }
+}
+
+void overlay_change_level(struct smart_map *smart, int level)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct map_overlay *ov;
+
+ EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
+ {
+ _overlay_change_level(smart, ov, level);
+ }
+}
+
+static inline void
+_overlay_unload(struct smart_map *smart, struct map_overlay *ov, struct osm_data *osm)
+{
+ char buf[64];
+ struct map_level_info *li;
+ Eina_Array *items;
+ Eina_Array_Iterator iterator;
+ unsigned int i;
+ struct overlay_item *oi;
+
+ snprintf(buf, 64, "%i/%i/%i", osm->z, osm->x, osm->y);
+ items = eina_hash_find(ov->hash, (const void *)buf);
+ if(items == NULL)
+ {
+ return;
+ }
+
+ EINA_ARRAY_ITER_NEXT(items, i, oi, iterator)
+ {
+ evas_object_hide(oi->obj->obj);
+ }
+}
+
+void overlay_unload(struct smart_map *smart, struct osm_data *osm)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct map_overlay *ov;
+
+ EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
+ {
+ _overlay_unload(smart, ov, osm);
+ }
+}
+
+static void inline
+_overlay_update(struct smart_map *smart, struct map_overlay *ov, struct osm_data *osm, int xoff, int yoff)
+{
+ char buf[64];
+ Eina_Array *items;
+ Eina_Array_Iterator iterator;
+ unsigned int i;
+ struct overlay_item *oi;
+
+ snprintf(buf, 64, "%i/%i/%i", osm->z, osm->x, osm->y);
+ items = eina_hash_find(ov->hash, (const void *)buf);
+ if(items == NULL)
+ {
+ return;
+ }
+
+ EINA_ARRAY_ITER_NEXT(items, i, oi, iterator)
+ {
+ struct overlay_object *obj = oi->obj;
+ evas_object_move(obj->obj,
+ xoff + oi->level_data.ox + obj->ox,
+ yoff + oi->level_data.oy + obj->oy);
+ evas_object_resize(oi->obj->obj, obj->sw, obj->sh);
+ // if(oi->level_data.visible)
+ evas_object_show(oi->obj->obj);
+ }
+}
+
+void overlay_update(struct smart_map *smart, struct osm_data *osm, int xoff, int yoff)
+{
+ Eina_Array_Iterator iterator;
+ int i;
+ struct map_overlay *ov;
+
+ EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
+ {
+ if(ov->state != OVERLAY_VISIBLE)
+ continue;
+ _overlay_update(smart, ov, osm, xoff, yoff);
+ }
+}
diff --git a/friendfinder/map/smart_map_priv.h b/friendfinder/map/smart_map_priv.h
new file mode 100644
index 0000000..d40e847
--- /dev/null
+++ b/friendfinder/map/smart_map_priv.h
@@ -0,0 +1,166 @@
+#ifndef _SMART_MAP_PRIV_H_
+#define _SMART_MAP_PRIV_H_
+
+struct map_level_info
+{
+ int min_x;
+ int max_x;
+ int min_y;
+ int max_y;
+
+ double north, south, west, east;
+ double dx, dy, e0, n0;
+};
+
+struct map_info
+{
+ char *path;
+ struct map_level_info *level;
+ int min_level;
+ int max_level;
+ int tile_size;
+};
+
+#include <Evas.h>
+
+struct smart_map;
+struct controls
+{
+ Evas_Object *bt;
+ Evas_Object *bx;
+ Evas_Object *vkbd;
+ Evas_Object *ctrl;
+};
+
+struct overlay_level_data
+{
+ int ox, oy;
+ int visible:1;
+};
+
+struct overlay_object
+{
+ Evas_Object *obj;
+ int ox;
+ int oy;
+ int sw, sh;
+};
+
+struct overlay_item
+{
+ struct overlay_object *obj;
+ double lat, lon;
+ unsigned int level_mask;
+ struct overlay_level_data level_data;
+};
+
+#define OSM_LEVEL_COUNT 19
+
+#include "e_smart_tile.h"
+struct smart_map
+{
+ Evas_Object *obj;
+ Evas_Object *clip;
+ Evas_Object *theme;
+ Evas_Coord x, y, w, h;
+
+ Evas *evas;
+ Evas_Object *win;
+ struct controls c;
+ Eina_Array *overlays;
+ Eina_Array *paths;
+
+ struct map_info *mi;
+ struct map_level_info *li;
+ int current_level;
+
+ struct tile_array ta;
+ double lat;
+ double lon;
+
+ int moved;
+ int drag;
+};
+
+enum {
+ OVERLAY_HIDDEN,
+ OVERLAY_VISIBLE
+};
+
+struct map_overlay
+{
+ struct smart_map *parent;
+ char *name;
+ Eina_Hash *hash;
+ Eina_Array *pois[OSM_LEVEL_COUNT];
+ int current_level;
+ int state;
+};
+
+enum {
+ POSITION_WORLD,
+ POSITION_PX,
+ NUM_POSITION,
+};
+
+struct map_info *map_info_read(const char *path);
+int map_object_update(struct smart_map *smart);
+int controls_init(struct smart_map *smart);
+
+struct map_overlay *overlay_create(struct smart_map *smart, char *name);
+void overlay_update(struct smart_map *smart, struct osm_data *, int xoff, int yoff);
+void overlay_unload(struct smart_map *smart, struct osm_data *osm);
+void overlay_change_level(struct smart_map *smart, int level);
+void overlay_add(struct smart_map *smart, struct map_overlay *ov, struct overlay_item *poi);
+struct map_overlay *overlay_find_by_name(struct smart_map *smart, char *name);
+void overlay_hide(struct smart_map *smart, char *name);
+void overlay_hide_all(struct smart_map *smart);
+
+static inline struct map_level_info *
+map_info_get_level(struct map_info *map, int* z)
+{
+ if(*z < map->min_level || *z > map->max_level)
+ *z = (map->min_level + map->max_level) / 2 ;
+
+ return &map->level[*z - map->min_level];
+}
+
+#include <limits.h>
+#include "../util/projection.h"
+static inline int
+latlon_to_map(struct map_level_info *level, double lat, double lon, int *x, int *y)
+{
+ if(level == NULL)
+ return -1;
+
+ int e = INT_MAX, n = INT_MAX;
+ double e0 = level->e0;
+ double n0 = level->n0;
+ double dx = level->dx;
+ double dy = level->dy;
+
+ project_latlon(lat, lon, &e, &n, PROJECTION_MERC);
+ *x = (e - e0) / dx;
+ *y = (n0 - n) / dy;
+ return 0;
+}
+
+static inline int
+map_to_latlon(struct map_level_info *level, int x, int y, double *lat, double *lon)
+{
+ int e, n;
+
+ if(level == NULL)
+ return -1;
+
+ double e0 = level->e0;
+ double n0 = level->n0;
+ double dx = level->dx;
+ double dy = level->dy;
+
+ e = e0 + x * dx;
+ n = -(y * dy - n0);
+ project_latlon_inv(e, n, lat, lon, PROJECTION_MERC);
+ return 0;
+}
+#endif