#include #include #include #include #include #include #include #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<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); } }