From 969d27f72d4fe008d1feef06fac7935148e891d7 Mon Sep 17 00:00:00 2001 From: martin-s Date: Thu, 20 Dec 2007 20:39:48 +0000 Subject: [PATCH] Made viewport more flexible git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@656 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/src/graphics.c | 59 +++--- navit/src/gui/sdl/gui_sdl_window.cpp | 11 +- navit/src/map.c | 97 +++++----- navit/src/map.h | 115 +++++++++++- navit/src/navit.c | 17 +- navit/src/route.c | 23 +-- navit/src/transform.c | 336 +++++++++++++---------------------- navit/src/transform.h | 19 +- 8 files changed, 340 insertions(+), 337 deletions(-) diff --git a/navit/src/graphics.c b/navit/src/graphics.c index 5904c4e..cd3f8e0 100644 --- a/navit/src/graphics.c +++ b/navit/src/graphics.c @@ -457,50 +457,41 @@ xdisplay_draw(GHashTable *display_list, struct graphics *gra, GList *layouts, in extern void *route_selection; static void -do_draw_map(struct displaylist *displaylist, struct transformation *t, struct map *m, struct map_selection *sel) +do_draw_map(struct displaylist *displaylist, struct transformation *t, struct map *m, int order) { enum projection pro; struct map_rect *mr; struct item *item; - struct coord c; - int i, conv,count,max=16384; + int conv,count,max=16384; struct point pnt[max]; struct coord ca[max]; struct attr attr; - struct coord_rect r; + struct map_selection *sel; pro=map_projection(m); conv=map_requires_conversion(m); - transform_rect(t, pro, &sel->u.c_rect); + sel=transform_get_selection(t, pro, order); if (route_selection) mr=map_rect_new(m, route_selection); else mr=map_rect_new(m, sel); while ((item=map_rect_get_item(mr))) { - if (item->type < type_line) { - item_coord_get(item, &c, 1); - if (!transform(t, pro, &c, &pnt[0])) { - dbg(1,"not visible\n"); - continue; - } - count=1; - } else { - count = item_coord_get(item, ca, max); - if (count < 2) - continue; - r.lu=ca[0]; - r.rl=ca[0]; - for (i=1; i < count; i++) { - coord_rect_extend(&r, &ca[i]); - } - if (!transform_contains(t, pro, &r)) { - dbg(1,"poly not visible\n"); - continue; - } - count = transform_array(t, pro, ca, pnt, count, 1); - if (count < 2) - continue; - g_assert(count < max); + count=item_coord_get(item, ca, item->type < type_line ? 1: max); + if (item->type >= type_line && count < 2) { + dbg(1,"poly from map has only %d points\n", count); + continue; + } + count=transform(t, pro, ca, pnt, count, + item->type < type_line ? 1 : (item->type < type_area ? 5 : 7)); + if (!count) { + dbg(1,"not visible\n"); + continue; + } + if (count == max) + dbg(0,"point count overflow\n", count); + if (item->type >= type_line && count < 2) { + dbg(1,"poly from transform has only %d points\n", count); + continue; } if (!item_attr_get(item, attr_label, &attr)) attr.u.str=NULL; @@ -512,32 +503,28 @@ do_draw_map(struct displaylist *displaylist, struct transformation *t, struct ma display_add(displaylist, item, count, pnt, attr.u.str); } map_rect_destroy(mr); + map_selection_destroy(sel); } static void do_draw(struct displaylist *displaylist, struct transformation *t, GList *mapsets, int order, struct route *route) { - struct map_selection sel; struct mapset *ms; struct map *m; struct mapset_handle *h; if (! mapsets) return; - sel.next=NULL; - sel.order[layer_town]=1*order; - sel.order[layer_street]=order; - sel.order[layer_poly]=1*order; ms=mapsets->data; h=mapset_open(ms); while ((m=mapset_next(h, 1))) { - do_draw_map(displaylist, t, m, &sel); + do_draw_map(displaylist, t, m, order); } mapset_close(h); if (route) { m = route_get_map(route); if (m) - do_draw_map(displaylist, t, m, &sel); + do_draw_map(displaylist, t, m, order); } } diff --git a/navit/src/gui/sdl/gui_sdl_window.cpp b/navit/src/gui/sdl/gui_sdl_window.cpp index 19f82a9..7d08df1 100644 --- a/navit/src/gui/sdl/gui_sdl_window.cpp +++ b/navit/src/gui/sdl/gui_sdl_window.cpp @@ -21,6 +21,7 @@ #include "attr.h" #include "track.h" #include "menu.h" +#include "map.h" #include "CEGUI.h" @@ -179,11 +180,13 @@ static int gui_run_main_loop(struct gui_priv *this_) int frames=0; char fps [12]; - struct transformation *t; + struct map_selection sel; - - t=navit_get_trans(this_->nav); - transform_set_size(t, 800, 600); + memset(&sel, 0, sizeof(sel)); + sel.u.c_rect.rl.x=800; + sel.u.c_rect.rl.y=600; + + transform_set_screen_selection(navit_get_trans(this_->nav), &sel); navit_draw(this_->nav); bool enable_timer=0; diff --git a/navit/src/map.c b/navit/src/map.c index bd3c6a9..f7a872d 100644 --- a/navit/src/map.c +++ b/navit/src/map.c @@ -41,39 +41,39 @@ map_new(const char *type, struct attr **attrs) } char * -map_get_filename(struct map *this) +map_get_filename(struct map *this_) { - return this->filename; + return this_->filename; } char * -map_get_type(struct map *this) +map_get_type(struct map *this_) { - return this->type; + return this_->type; } int -map_get_active(struct map *this) +map_get_active(struct map *this_) { - return this->active; + return this_->active; } void -map_set_active(struct map *this, int active) +map_set_active(struct map *this_, int active) { - this->active=active; + this_->active=active; } int -map_requires_conversion(struct map *this) +map_requires_conversion(struct map *this_) { - return (this->meth.charset != NULL); + return (this_->meth.charset != NULL); } char * -map_convert_string(struct map *this, char *str) +map_convert_string(struct map *this_, char *str) { - return g_convert(str, -1,"utf-8",this->meth.charset,NULL,NULL,NULL); + return g_convert(str, -1,"utf-8",this_->meth.charset,NULL,NULL,NULL); } void @@ -83,9 +83,9 @@ map_convert_free(char *str) } enum projection -map_projection(struct map *this) +map_projection(struct map *this_) { - return this->meth.pro; + return this_->meth.pro; } void @@ -152,64 +152,79 @@ struct map_search { struct map_search * map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial) { - struct map_search *this; + struct map_search *this_; dbg(1,"enter(%p,%p,%p,%d)\n", m, item, search_attr, partial); dbg(1,"0x%x 0x%x 0x%x\n", attr_country_all, search_attr->type, attr_country_name); - this=g_new0(struct map_search,1); - this->m=m; - this->search_attr=*search_attr; + this_=g_new0(struct map_search,1); + this_->m=m; + this_->search_attr=*search_attr; if (search_attr->type >= attr_country_all && search_attr->type <= attr_country_name) - this->priv=country_search_new(&this->search_attr, partial); + this_->priv=country_search_new(&this_->search_attr, partial); else { if (m->meth.map_search_new) { if (m->meth.charset) - this->search_attr.u.str=g_convert(this->search_attr.u.str, -1,m->meth.charset,"utf-8",NULL,NULL,NULL); - this->priv=m->meth.map_search_new(m->priv, item, &this->search_attr, partial); + this_->search_attr.u.str=g_convert(this_->search_attr.u.str, -1,m->meth.charset,"utf-8",NULL,NULL,NULL); + this_->priv=m->meth.map_search_new(m->priv, item, &this_->search_attr, partial); } else { - g_free(this); - this=NULL; + g_free(this_); + this_=NULL; } } - return this; + return this_; } struct item * -map_search_get_item(struct map_search *this) +map_search_get_item(struct map_search *this_) { struct item *ret; - if (! this) + if (! this_) return NULL; - if (this->search_attr.type >= attr_country_all && this->search_attr.type <= attr_country_name) - return country_search_get_item(this->priv); - ret=this->m->meth.map_search_get_item(this->priv); + if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name) + return country_search_get_item(this_->priv); + ret=this_->m->meth.map_search_get_item(this_->priv); if (ret) - ret->map=this->m; + ret->map=this_->m; return ret; } void -map_search_destroy(struct map_search *this) +map_search_destroy(struct map_search *this_) { - if (! this) + if (! this_) return; - if (this->search_attr.type >= attr_country_all && this->search_attr.type <= attr_country_name) - country_search_destroy(this->priv); + if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name) + country_search_destroy(this_->priv); else { - if (this->m->meth.charset) - g_free(this->search_attr.u.str); - this->m->meth.map_search_destroy(this->priv); + if (this_->m->meth.charset) + g_free(this_->search_attr.u.str); + this_->m->meth.map_search_destroy(this_->priv); } - g_free(this); + g_free(this_); +} + +struct map_selection * +map_selection_dup(struct map_selection *sel) +{ + struct map_selection *next,**last; + struct map_selection *ret=NULL; + last=&ret; + while (sel) { + next = g_new(struct map_selection, 1); + *next=*sel; + *last=next; + sel = sel->next; + } + return ret; } void map_selection_destroy(struct map_selection *sel) { - struct map_selection *ms; + struct map_selection *next; while (sel) { - ms = sel->next; + next = sel->next; g_free(sel); - sel = ms; + sel = next; } } diff --git a/navit/src/map.h b/navit/src/map.h index 7d1f31a..891d602 100644 --- a/navit/src/map.h +++ b/navit/src/map.h @@ -37,6 +37,102 @@ struct map { int active; }; +static inline int +map_selection_contains_point(struct map_selection *sel, struct coord *c) +{ + struct map_selection *curr=sel; + while (curr) { + struct coord_rect *r=&curr->u.c_rect; + if (c->x >= r->lu.x && c->x <= r->rl.x && + c->y >= r->lu.y && c->y <= r->rl.y) + return 1; + curr=curr->next; + } + return sel ? 0:1; +} + +static inline int +map_selection_contains_polyline(struct map_selection *sel, struct coord *c, int count) +{ + int i,x_mi,x_ma,y_mi,y_ma; + struct map_selection *curr; + + if (! sel) + return 1; + for (i = 0 ; i < count-1 ; i++) { + x_mi=c[i].x; + if (c[i+1].x < x_mi) + x_mi=c[i+1].x; + x_ma=c[i].x; + if (c[i+1].x > x_ma) + x_ma=c[i+1].x; + y_mi=c[i].y; + if (c[i+1].y < y_mi) + y_mi=c[i+1].y; + y_ma=c[i].y; + if (c[i+1].y > y_ma) + y_ma=c[i+1].y; + curr=sel; + while (curr) { + struct coord_rect *sr=&curr->u.c_rect; + if (x_mi <= sr->rl.x && x_ma >= sr->lu.x && + y_ma >= sr->rl.y && y_mi <= sr->lu.y) + return 1; + curr=curr->next; + } + } + return 0; +} + +static inline int +map_selection_contains_rect(struct map_selection *sel, struct coord_rect *r) +{ + struct map_selection *curr; + + g_assert(r->lu.x <= r->rl.x); + g_assert(r->lu.y >= r->rl.y); + + if (! sel) + return 1; + curr=sel; + while (curr) { + struct coord_rect *sr=&curr->u.c_rect; + g_assert(sr->lu.x <= sr->rl.x); + g_assert(sr->lu.y >= sr->rl.y); + if (r->lu.x <= sr->rl.x && r->rl.x >= sr->lu.x && + r->lu.y >= sr->rl.y && r->rl.y <= sr->lu.y) + return 1; + curr=curr->next; + } + return 0; +} + +static inline int +map_selection_contains_polygon(struct map_selection *sel, struct coord *c, int count) +{ + struct coord_rect r; + int i; + + if (! sel) + return 1; + if (! count) + return 0; + r.lu=c[0]; + r.rl=c[0]; + for (i = 1 ; i < count-1 ; i++) { + if (c[i].x < r.lu.x) + r.lu.x=c[i].x; + if (c[i].x > r.rl.x) + r.rl.x=c[i].x; + if (c[i].y < r.rl.y) + r.rl.y=c[i].y; + if (c[i].y > r.lu.y) + r.lu.y=c[i].y; + } + return map_selection_contains_rect(sel, &r); +} + + /* prototypes */ enum projection; struct attr; @@ -46,22 +142,23 @@ struct map_rect; struct map_search; struct map_selection; struct map *map_new(const char *type, struct attr **attrs); -char *map_get_filename(struct map *this); -char *map_get_type(struct map *this); -int map_get_active(struct map *this); -void map_set_active(struct map *this, int active); -int map_requires_conversion(struct map *this); -char *map_convert_string(struct map *this, char *str); +char *map_get_filename(struct map *this_); +char *map_get_type(struct map *this_); +int map_get_active(struct map *this_); +void map_set_active(struct map *this_, int active); +int map_requires_conversion(struct map *this_); +char *map_convert_string(struct map *this_, char *str); void map_convert_free(char *str); -enum projection map_projection(struct map *this); +enum projection map_projection(struct map *this_); void map_destroy(struct map *m); struct map_rect *map_rect_new(struct map *m, struct map_selection *sel); struct item *map_rect_get_item(struct map_rect *mr); struct item *map_rect_get_item_byid(struct map_rect *mr, int id_hi, int id_lo); void map_rect_destroy(struct map_rect *mr); struct map_search *map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial); -struct item *map_search_get_item(struct map_search *this); -void map_search_destroy(struct map_search *this); +struct item *map_search_get_item(struct map_search *this_); +void map_search_destroy(struct map_search *this_); +struct map_selection *map_selection_dup(struct map_selection *sel); void map_selection_destroy(struct map_selection *sel); /* end of prototypes */ diff --git a/navit/src/navit.c b/navit/src/navit.c index ddb6521..f6adb28 100644 --- a/navit/src/navit.c +++ b/navit/src/navit.c @@ -155,7 +155,13 @@ static void navit_resize(void *data, int w, int h) { struct navit *this_=data; - transform_set_size(this_->trans, w, h); + struct map_selection sel; + memset(&sel, 0, sizeof(sel)); + sel.u.p_rect.lu.x=w/4; + sel.u.p_rect.lu.y=h/4; + sel.u.p_rect.rl.x=w*3/4; + sel.u.p_rect.rl.y=h*3/4; + transform_set_screen_selection(this_->trans, &sel); navit_draw(this_); } @@ -207,7 +213,9 @@ navit_button(void *data, int pressed, int button, struct point *p) } if (this_->moved) { struct point p; +#if 0 transform_get_size(this_->trans, &p.x, &p.y); +#endif p.x/=2; p.y/=2; p.x-=this_->last.x-this_->pressed.x; @@ -1050,6 +1058,7 @@ navit_set_center(struct navit *this_, struct coord *center) static void navit_set_center_cursor(struct navit *this_, struct coord *cursor, int dir, int xpercent, int ypercent) { +#if 0 struct coord *c=transform_center(this_->trans); int width, height; struct point p; @@ -1064,6 +1073,7 @@ navit_set_center_cursor(struct navit *this_, struct coord *cursor, int dir, int *c=cnew; if (this_->ready) navit_draw(this_); +#endif } @@ -1122,7 +1132,7 @@ navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point * pnt2=*pnt; else { pro=transform_get_projection(this_->trans); - transform(this_->trans, pro, &nv->coord, &pnt2); + transform(this_->trans, pro, &nv->coord, &pnt2, 1, 0); } #if 1 cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL); @@ -1167,7 +1177,8 @@ navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv) } } - if ((!transform(this_->trans, pro, &nv->coord, &cursor_pnt) || !transform_within_border(this_->trans, &cursor_pnt, border))) { + if ((!transform(this_->trans, pro, &nv->coord, &cursor_pnt, 1, 1) || + !transform_within_border(this_->trans, &cursor_pnt, border))) { if (!this_->cursor_flag) return; if (nv->follow_curr != 1) { diff --git a/navit/src/route.c b/navit/src/route.c index 83d13a7..9eedf34 100644 --- a/navit/src/route.c +++ b/navit/src/route.c @@ -1414,10 +1414,11 @@ static int route_draw_route_info(struct route_info *pos, struct route_info *dst, struct transformation *t, struct displaylist *dsp) { struct route_info_handle *h; - struct coord *c; - struct coord_rect r; + struct coord *cp; struct item item; - struct point pnt[100]; + int max=100; + struct coord c[max]; + struct point pnt[max]; int count=0; struct street_data *street; enum projection pro = projection_mg; @@ -1438,17 +1439,11 @@ route_draw_route_info(struct route_info *pos, struct route_info *dst, struct tra pro = map_projection(street->item.map); if (pos) dbg(1, "pos=%p pos->dir=%d pos->pos=%d\n", pos, pos->dir, pos->pos); - c=route_info_get(h); - r.lu=*c; - r.rl=*c; - while (c && count < 100) { - dbg(1,"c=%p (0x%x,0x%x)\n", c, c->x, c->y); - transform(t, pro, c, &pnt[count++]); - coord_rect_extend(&r, c); - c=route_info_get(h); - - } - if (count && transform_contains(t, pro, &r)) + while ((cp=route_info_get(h)) && count < max) + c[count++]=*cp; + if (count) + count=transform(t, pro, c, pnt, count, 1); + if (count) display_add(dsp, &item, count, pnt, "Route"); route_info_close(h); dbg(1, "return 1\n"); diff --git a/navit/src/transform.c b/navit/src/transform.c index d3d9ca7..2d11a7b 100644 --- a/navit/src/transform.c +++ b/navit/src/transform.c @@ -6,19 +6,20 @@ #include "config.h" #include "coord.h" #include "debug.h" +#include "map.h" #include "transform.h" #include "projection.h" #include "point.h" struct transformation { - int width; /* Height of destination rectangle */ - int height; /* Width of destination rectangle */ long scale; /* Scale factor */ int angle; /* Rotation angle */ double cos_val,sin_val; /* cos and sin of rotation angle */ enum projection pro; - struct coord_rect r; /* Source rectangle */ - struct coord center; /* Center of source rectangle */ + struct map_selection *map_sel; + struct map_selection *screen_sel; + struct point screen_center; + struct coord map_center; /* Center of source rectangle */ }; struct transformation * @@ -69,73 +70,7 @@ transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *c) } int -transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p) -{ - struct coord c1; -#ifdef AVOID_FLOAT - int xc,yc; -#else - double xc,yc; -#endif - int ret; - if (pro != t->pro) { - struct coord_geo g; - transform_to_geo(pro, c, &g); - transform_from_geo(t->pro, &g, &c1); - c=&c1; - } - xc=c->x; - yc=c->y; - dbg(2,"0x%x, 0x%x - 0x%x,0x%x contains 0x%x,0x%x\n", t->r.lu.x, t->r.lu.y, t->r.rl.x, t->r.rl.y, c->x, c->y); - ret=coord_rect_contains(&t->r, c); - xc-=t->center.x; - yc-=t->center.y; - yc=-yc; - if (t->angle) { - int xcn, ycn; - xcn=xc*t->cos_val+yc*t->sin_val; - ycn=-xc*t->sin_val+yc*t->cos_val; - xc=xcn; - yc=ycn; - } -#ifndef AVOID_FLOAT - xc=xc*16.0/(double)(t->scale); - yc=yc*16.0/(double)(t->scale); -#else - xc=xc*16/t->scale; - yc=yc*16/t->scale; -#endif -#if 0 - { - double zc=yc; - if (zc < 10 && zc > 10) - zc=10; - return 0; - yc=300; - xc/=(-zc+1000.0)/1000.0; - yc/=(-zc+1000.0)/1000.0; - xc+=t->width/2; - } -#else - yc+=t->height/2; - xc+=t->width/2; -#endif - if (xc < -0x8000) - xc=-0x8000; - if (xc > 0x7fff) { - xc=0x7fff; - } - if (yc < -0x8000) - yc=-0x8000; - if (yc > 0x7fff) - yc=0x7fff; - p->x=xc; - p->y=yc; - return ret; -} - -int -transform_array(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int uniq) +transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int flags) { struct coord c1; int xcn, ycn; @@ -146,6 +81,20 @@ transform_array(struct transformation *t, enum projection pro, struct coord *c, double xc,yc; #endif int i,j = 0; + if (flags & 1) { + if (count == 1) { + if (!map_selection_contains_point(t->map_sel, &c[0])) + return 0; + } else { + if (flags & 2) { + if (!map_selection_contains_polygon(t->map_sel, c, count)) + return 0; + } else { + if (!map_selection_contains_polyline(t->map_sel, c, count)) + return 0; + } + } + } for (i=0; i < count; i++) { if (pro == t->pro) { xc=c[i].x; @@ -158,8 +107,8 @@ transform_array(struct transformation *t, enum projection pro, struct coord *c, } // dbg(2,"0x%x, 0x%x - 0x%x,0x%x contains 0x%x,0x%x\n", t->r.lu.x, t->r.lu.y, t->r.rl.x, t->r.rl.y, c->x, c->y); // ret=coord_rect_contains(&t->r, c); - xc-=t->center.x; - yc-=t->center.y; + xc-=t->map_center.x; + yc-=t->map_center.y; yc=-yc; if (t->angle) { xcn=xc*t->cos_val+yc*t->sin_val; @@ -180,8 +129,8 @@ transform_array(struct transformation *t, enum projection pro, struct coord *c, yc=yc/t->scale; } #endif - yc+=t->height>>1; - xc+=t->width>>1; + xc+=t->screen_center.x; + yc+=t->screen_center.y; if (xc < -0x8000) xc=-0x8000; if (xc > 0x7fff) { @@ -191,27 +140,13 @@ transform_array(struct transformation *t, enum projection pro, struct coord *c, yc=-0x8000; if (yc > 0x7fff) yc=0x7fff; - if (uniq) { - if (i) { - if (p[j].x != xc || p[j].y != yc) { - j++; - p[j].x=xc; - p[j].y=yc; - } - } else { - p[j].x=xc; - p[j].y=yc; - } - } else { - p[i].x=xc; - p[i].y=yc; + if (j == 0 || !(flags & 4) || p[j-1].x != xc || p[j-1].y != yc) { + p[j].x=xc; + p[j].y=yc; + j++; } } - - if (uniq) - return 1+j; - - return count; + return j; } void @@ -220,8 +155,8 @@ transform_reverse(struct transformation *t, struct point *p, struct coord *c) int xc,yc; xc=p->x; yc=p->y; - xc-=t->width/2; - yc-=t->height/2; + xc-=t->screen_center.x; + yc-=t->screen_center.y; xc=xc*t->scale/16; yc=-yc*t->scale/16; if (t->angle) { @@ -231,8 +166,8 @@ transform_reverse(struct transformation *t, struct point *p, struct coord *c) xc=xcn; yc=ycn; } - c->x=t->center.x+xc; - c->y=t->center.y+yc; + c->x=t->map_center.x+xc; + c->y=t->map_center.y+yc; } enum projection @@ -273,43 +208,39 @@ max4(int v1,int v2, int v3, int v4) return res; } -void -transform_rect(struct transformation *this_, enum projection pro, struct coord_rect *r) +struct map_selection * +transform_get_selection(struct transformation *this_, enum projection pro, int order) { + + struct map_selection *ret,*curri,*curro; struct coord_geo g; - if (0 && this_->pro == pro) { - *r=this_->r; - } else { - transform_to_geo(this_->pro, &this_->r.lu, &g); - transform_from_geo(pro, &g, &r->lu); - dbg(1,"%f,%f", g.lat, g.lng); - transform_to_geo(this_->pro, &this_->r.rl, &g); - dbg(1,": - %f,%f\n", g.lat, g.lng); - transform_from_geo(pro, &g, &r->rl); + int i; + + ret=map_selection_dup(this_->map_sel); + curri=this_->map_sel; + curro=ret; + while (curri) { + if (this_->pro != pro) { + transform_to_geo(this_->pro, &curri->u.c_rect.lu, &g); + transform_from_geo(pro, &g, &curro->u.c_rect.lu); + dbg(1,"%f,%f", g.lat, g.lng); + transform_to_geo(this_->pro, &curri->u.c_rect.rl, &g); + transform_from_geo(pro, &g, &curro->u.c_rect.rl); + dbg(1,": - %f,%f\n", g.lat, g.lng); + } + dbg(1,"transform rect for %d is %d,%d - %d,%d\n", pro, curro->u.c_rect.lu.x, curro->u.c_rect.lu.y, curro->u.c_rect.rl.x, curro->u.c_rect.rl.y); + for (i = 0 ; i < layer_end ; i++) + curro->order[i]+=order; + curri=curri->next; + curro=curro->next; } - dbg(1,"transform rect for %d is %d,%d - %d,%d\n", pro, r->lu.x, r->lu.y, r->rl.x, r->rl.y); + return ret; } struct coord * transform_center(struct transformation *this_) { - return &this_->center; -} - -int -transform_contains(struct transformation *this_, enum projection pro, struct coord_rect *r) -{ - struct coord_geo g; - struct coord_rect r1; - if (this_->pro != pro) { - transform_to_geo(pro, &r->lu, &g); - transform_from_geo(this_->pro, &g, &r1.lu); - transform_to_geo(pro, &r->rl, &g); - transform_from_geo(this_->pro, &g, &r1.rl); - r=&r1; - } - return coord_rect_overlap(&this_->r, r); - + return &this_->map_center; } void @@ -327,29 +258,46 @@ transform_get_angle(struct transformation *this_,int angle) } void +transform_set_screen_selection(struct transformation *t, struct map_selection *sel) +{ + map_selection_destroy(t->screen_sel); + t->screen_sel=map_selection_dup(sel); + if (sel) { + t->screen_center.x=(sel->u.p_rect.rl.x-sel->u.p_rect.lu.x)/2; + t->screen_center.y=(sel->u.p_rect.rl.y-sel->u.p_rect.lu.y)/2; + } +} + +#if 0 +void transform_set_size(struct transformation *t, int width, int height) { t->width=width; t->height=height; } +#endif +#if 0 void transform_get_size(struct transformation *t, int *width, int *height) { *width=t->width; *height=t->height; } +#endif void transform_setup(struct transformation *t, struct pcoord *c, int scale, int angle) { t->pro=c->pro; - t->center.x=c->x; - t->center.y=c->y; + t->map_center.x=c->x; + t->map_center.y=c->y; t->scale=scale; transform_set_angle(t, angle); } +#if 0 + void transform_setup_source_rect_limit(struct transformation *t, struct coord *center, int limit) { @@ -361,6 +309,7 @@ transform_setup_source_rect_limit(struct transformation *t, struct coord *center t->r.rl.y=center->y-limit; t->r.lu.y=center->y+limit; } +#endif void transform_setup_source_rect(struct transformation *t) @@ -368,22 +317,39 @@ transform_setup_source_rect(struct transformation *t) int i; struct coord screen[4]; struct point screen_pnt[4]; - - screen_pnt[0].x=0; - screen_pnt[0].y=0; - screen_pnt[1].x=t->width; - screen_pnt[1].y=0; - screen_pnt[2].x=0; - screen_pnt[2].y=t->height; - screen_pnt[3].x=t->width; - screen_pnt[3].y=t->height; - for (i = 0 ; i < 4 ; i++) { - transform_reverse(t, &screen_pnt[i], &screen[i]); + struct point_rect *pr; + struct map_selection *ms,*msm,*next,**msm_last; + ms=t->map_sel; + while (ms) { + next=ms->next; + g_free(ms); + ms=next; + } + t->map_sel=NULL; + msm_last=&t->map_sel; + ms=t->screen_sel; + while (ms) { + msm=g_new0(struct map_selection, 1); + pr=&ms->u.p_rect; + screen_pnt[0].x=pr->lu.x; + screen_pnt[0].y=pr->lu.y; + screen_pnt[1].x=pr->rl.x; + screen_pnt[1].y=pr->lu.y; + screen_pnt[2].x=pr->lu.x; + screen_pnt[2].y=pr->rl.y; + screen_pnt[3].x=pr->rl.x; + screen_pnt[3].y=pr->rl.y; + for (i = 0 ; i < 4 ; i++) { + transform_reverse(t, &screen_pnt[i], &screen[i]); + } + msm->u.c_rect.lu.x=min4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); + msm->u.c_rect.rl.x=max4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); + msm->u.c_rect.rl.y=min4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); + msm->u.c_rect.lu.y=max4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); + *msm_last=msm; + msm_last=&msm->next; + ms=ms->next; } - t->r.lu.x=min4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); - t->r.rl.x=max4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); - t->r.rl.y=min4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); - t->r.lu.y=max4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); } long @@ -619,76 +585,6 @@ transform_print_deg(double deg) printf("%2.0f:%2.0f:%2.4f", floor(deg), fmod(deg*60,60), fmod(deg*3600,60)); } -int -is_visible(struct transformation *t, struct coord *c) -{ - struct coord_rect *r=&t->r; - - assert(c[0].x <= c[1].x); - assert(c[0].y >= c[1].y); - assert(r->lu.x <= r->rl.x); - assert(r->lu.y >= r->rl.y); - if (c[0].x > r->rl.x) - return 0; - if (c[1].x < r->lu.x) - return 0; - if (c[0].y < r->rl.y) - return 0; - if (c[1].y > r->lu.y) - return 0; - return 1; -} - -int -is_line_visible(struct transformation *t, struct coord *c) -{ - struct coord_rect *r=&t->r; - - assert(r->lu.x <= r->rl.x); - assert(r->lu.y >= r->rl.y); - if (MIN(c[0].x,c[1].x) > r->rl.x) - return 0; - if (MAX(c[0].x,c[1].x) < r->lu.x) - return 0; - if (MAX(c[0].y,c[1].y) < r->rl.y) - return 0; - if (MIN(c[0].y,c[1].y) > r->lu.y) - return 0; - return 1; -} - -int -is_point_visible(struct transformation *t, struct coord *c) -{ - struct coord_rect *r=&t->r; - - assert(r->lu.x <= r->rl.x); - assert(r->lu.y >= r->rl.y); - if (c->x > r->rl.x) - return 0; - if (c->x < r->lu.x) - return 0; - if (c->y < r->rl.y) - return 0; - if (c->y > r->lu.y) - return 0; - return 1; -} - - -int -is_too_small(struct transformation *t, struct coord *c, int limit) -{ - return 0; - if ((c[1].x-c[0].x) < limit*t->scale/16) { - return 1; - } - if ((c[0].y-c[1].y) < limit*t->scale/16) { - return 1; - } - return 0; -} - #ifdef AVOID_FLOAT static int tab_atan[]={0,262,524,787,1051,1317,1584,1853,2126,2401,2679,2962,3249,3541,3839,4142,4452,4770,5095,5430,5774,6128,6494,6873,7265,7673,8098,8541,9004,9490,10000,10538}; @@ -765,9 +661,15 @@ transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir) int transform_within_border(struct transformation *this_, struct point *p, int border) { - if (p->x < border || p->x > this_->width-border || p->y < border || p->y > this_->height-border) - return 0; - return 1; + struct map_selection *ms=this_->screen_sel; + while (ms) { + struct point_rect *r=&ms->u.p_rect; + if (p->x >= r->lu.x+border && p->x <= r->rl.x-border && + p->y >= r->lu.y+border && p->y <= r->rl.y-border) + return 1; + ms=ms->next; + } + return 0; } /* diff --git a/navit/src/transform.h b/navit/src/transform.h index d2a4004..b49485e 100644 --- a/navit/src/transform.h +++ b/navit/src/transform.h @@ -7,28 +7,21 @@ extern "C" { /* prototypes */ enum projection; struct coord; -struct pcoord; struct coord_geo; -struct coord_rect; +struct map_selection; struct point; struct transformation; struct transformation *transform_new(void); void transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g); void transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *c); -int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p); -int transform_array(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int uniq); +int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int flags); void transform_reverse(struct transformation *t, struct point *p, struct coord *c); enum projection transform_get_projection(struct transformation *this_); void transform_set_projection(struct transformation *this_, enum projection pro); -void transform_rect(struct transformation *this_, enum projection pro, struct coord_rect *r); struct coord *transform_center(struct transformation *this_); -int transform_contains(struct transformation *this_, enum projection pro, struct coord_rect *r); void transform_set_angle(struct transformation *t, int angle); int transform_get_angle(struct transformation *this_, int angle); -void transform_set_size(struct transformation *t, int width, int height); -void transform_get_size(struct transformation *t, int *width, int *height); -void transform_setup(struct transformation *t, struct pcoord *c, int scale, int angle); -void transform_setup_source_rect_limit(struct transformation *t, struct coord *center, int limit); +void transform_set_screen_selection(struct transformation *t, struct map_selection *sel); void transform_setup_source_rect(struct transformation *t); long transform_get_scale(struct transformation *t); void transform_set_scale(struct transformation *t, long scale); @@ -40,9 +33,9 @@ int transform_distance_sq(struct coord *c1, struct coord *c2); int transform_distance_line_sq(struct coord *l0, struct coord *l1, struct coord *ref, struct coord *lpnt); int transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos); void transform_print_deg(double deg); -int is_visible(struct transformation *t, struct coord *c); -int is_line_visible(struct transformation *t, struct coord *c); -int is_point_visible(struct transformation *t, struct coord *c); +int transform_contains_polygon(struct transformation *t, struct coord *c, int count); +int transform_contains_polyline(struct transformation *t, struct coord *c, int count); +int transform_contains_point(struct transformation *t, struct coord *c); int is_too_small(struct transformation *t, struct coord *c, int limit); int transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir); int transform_within_border(struct transformation *this_, struct point *p, int border); -- 2.7.4