From 6eb422d36800898ac65b0e6780160ec39e32df63 Mon Sep 17 00:00:00 2001 From: steffen Date: Fri, 3 May 2013 22:52:57 +0000 Subject: [PATCH] displaying issues on opengles --- ChangeLog | 11 +++ base/vector.c | 21 +++++ base/vector.h | 2 + doc/TechDoc.odt | Bin 26873 -> 26967 bytes draw/draw.c | 15 ++- mapsys/map.h | 3 +- mapsys/map_area.c | 12 ++- mapsys/map_loadsave.c | 13 +-- mapsys/map_osmload.c | 212 ++++++++++++++++++++++++++++++++++++++++-- 9 files changed, 269 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f40215..63a497a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ Version 0.0.2: name changed to spOSMroute, since on there had been another OSMroute already. ============================================================================= +(2013-05-02): +- fixed: areas haven't been updated right. + +- added: areas have subid now. + +- changed: saving subid within the id by shifting bits to the left. + saving 2 bytes each way. + +- fixed: areas get split into different parts on each inside angle above 180° + should fix displaying issues on opengl and opengles devices. + (2013-03-11): - rewrote most parts of the gui handling. diff --git a/base/vector.c b/base/vector.c index 75510cd..a59c1bc 100644 --- a/base/vector.c +++ b/base/vector.c @@ -21,6 +21,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "osmroute.h" #include "vector.h" @@ -108,3 +109,23 @@ fPoint vec_mul (fPoint v, float f) { a.y = f * v.y; return a; }; + + +/* calc angle of three points assuming v2 is the center.. */ +float point_angle (fPoint v1, fPoint v2, fPoint v3) { + float a1; + float a3; + float delta; + + v1 = vec_sub (v1, v2); + v3 = vec_sub (v3, v2); + a1 = atan2f (v1.y, v1.x); + a3 = atan2f (v3.y, v3.x); + + if (a1 < 0.0) a1 += 2.0*M_PI; + if (a3 < 0.0) a3 += 2.0*M_PI; + if ((delta = a1-a3) < 0.0) delta += 2.0*M_PI; + + return delta; +}; + diff --git a/base/vector.h b/base/vector.h index 45c423e..0c5e357 100644 --- a/base/vector.h +++ b/base/vector.h @@ -35,4 +35,6 @@ extern fPoint vec_mirror (fPoint veca); extern float vec_len (fPoint veca); extern fPoint vec_mul (fPoint v, float f); +extern float point_angle (fPoint v1, fPoint v2, fPoint v3); + #endif diff --git a/doc/TechDoc.odt b/doc/TechDoc.odt index 6d6f97f43274191f44703647671bf39ce2a6d8ff..a07eacf80d2e0a30dbd3d8121db1ceee8bc24e7c 100644 GIT binary patch delta 19542 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 O00mt!5Xm-{1pN<6;fr7Z delta 19456 zcmZ7e1z1&G)GiE*lynG^(v7rqcXxMpceA9sOS+{5q#Gn9q(Qp7yX#v%p8x#kefPz@ zbnms-nq$s6^1cVmPD0#IKp-nfLqcJ^dGqeg8|dsf!FXgzw7>rX(Ae{BpWeLrJFpXJ zOz`3ZNr6v+k|KgC9+}5ko(`&_54R|hP-LhnP;qon^MWRDH8e~_HPko*VQ-bf*4`pB zM;55ba=!fdZaAIhBn(|d^JO?{;-?5|oG${ZV7Lw3V+?8l85son_^tA-=f2fg^DSxu zzBAnO^X8vsU$4{CeZTCJ;#S(%i(!Tof5A5@^oLN0*ifvA@^qAdg52Ht%j2nji%WQD zsdDkc5~a-7vk~@Hd>)T8dcp{7Lp{9}${Zi1daD_60?)0zi2{AUd(&38V+Z?{Hct
42=YAL#h{tBL+ppA^4l5}sSrk4$-fq^I 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 diff --git a/draw/draw.c b/draw/draw.c index 9c43a65..1d479fc 100644 --- a/draw/draw.c +++ b/draw/draw.c @@ -479,12 +479,19 @@ void draw_map () { carea = mh->areas; while (carea) { if (draw_type[carea->type + MWAY_MAX]) { - draw_polygonstart (); + draw_polygonstart (); for (n = 0; n < carea->p_cnt; n++) if (n == 0 || n == carea->p_cnt-1 || view_scale < 0.01 || ((view_scale < 0.1 && (n % 2) == 0) || carea->p_cnt < 5) || ((view_scale < 0.1 && (n % 4) == 0) || carea->p_cnt < 10)) { p1 = draw_geo2screen (view_lon, view_lat, carea->p[n].lon, carea->p[n].lat); + // if (n == 0) { + // draw_line (img_map, p1.x + center.x - 5, p1.y + center.y - 5, p1.x + center.x + 5, p1.y + center.y + 5, tmplinestyle); + // draw_line (img_map, p1.x + center.x + 5, p1.y + center.y - 5, p1.x + center.x - 5, p1.y + center.y + 5, tmplinestyle); + // } + // if (n == 0) sprintf (text, "%d:%d", n, carea->subid); + // else sprintf (text, "%d", n); + // gfx_draw_text (img_map, p1.x + center.x - 20, p1.y + center.y - 10, text, &color[COLOR_white][3]); draw_polygonadd (p1.x + center.x, p1.y + center.y); } draw_polygonfinish (img_map, tmplinestyle, &color_polygon[carea->type], 0); @@ -494,12 +501,11 @@ void draw_map () { } } - /* * draw ways */ /* draw outside */ - for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++) + for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++) for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) { /* * draw the hash.. @@ -573,7 +579,7 @@ void draw_map () { } /* ways inside */ - for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++) + for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++) for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) { /* * draw the hash.. @@ -679,7 +685,6 @@ void draw_map () { } } - /* * draw places, pois just on top layers */ diff --git a/mapsys/map.h b/mapsys/map.h index 6f1007c..5a15783 100644 --- a/mapsys/map.h +++ b/mapsys/map.h @@ -44,7 +44,7 @@ #define MAP_LSSTAT_MAX 128 #endif #define MAP_LSSIZE_HASH 28 -#define MAP_LSSIZE_WAY 16 +#define MAP_LSSIZE_WAY 14 #define MAP_LSSIZE_WAYNODE 23 #define MAP_LSSIZE_POS 8 #define MAP_LSSIZE_AREA 12 @@ -176,6 +176,7 @@ struct map_way { struct map_area { char status; unsigned long long int id; + unsigned short int subid; unsigned char type; unsigned char flags; diff --git a/mapsys/map_area.c b/mapsys/map_area.c index 15409bd..66a865d 100644 --- a/mapsys/map_area.c +++ b/mapsys/map_area.c @@ -39,11 +39,18 @@ int map_area_add_to_hash (struct map_hash *mh, struct map_area *ma) { int size; struct map_area *a; + /* check if the first element is already the one we want to update */ + if (mh->areas && mh->areas->id == ma->id && mh->areas->subid == ma->subid) { + mh->areas = mh->areas->next; + mh->areascnt--; + } + + /* find possible update and go to the end */ if (mh->areas) { /* find last way */ a = mh->areas; while (a && a->next) { - if (a->next->id == ma->id) { + if (a->next->id == ma->id && a->next->subid == a->subid) { /* found old way.. just delete .. */ a->next = a->next->next; mh->areascnt--; @@ -85,6 +92,8 @@ int map_area_add (struct map_area *area, int loadflags) { int size; if (area->p == NULL || area->p_cnt == 0) return 0; +// area->type = area->subid % MAREA_campsite + 1; +// d_printf ("subid:%d type:%d cnt:%d", area->subid, area->type, area->p_cnt); size = map_area_getsize (area); mh = map_hash_get (area->p[0].lon, area->p[0].lat, loadflags); @@ -110,6 +119,7 @@ void map_area_copy (struct map_area *dest, struct map_area *src) { int i; dest->id = src->id; + dest->subid = src->subid; dest->type = src->type; dest->p_cnt = src->p_cnt; dest->p = (struct map_pos*) (dest->data); diff --git a/mapsys/map_loadsave.c b/mapsys/map_loadsave.c index 52cdeab..f55ea5c 100644 --- a/mapsys/map_loadsave.c +++ b/mapsys/map_loadsave.c @@ -38,6 +38,8 @@ #include "memoryleak.h" #include "osmroute.h" +#define MAP_BITS_SUBID 5 + char *lsrw_data = NULL; int lsrw_data_size = 0; char *lshash_data = NULL; @@ -576,9 +578,8 @@ char *map_ls_hash2data (struct map_hash *mh, int *size) { /* save the basic data */ ui64 = mw->id; /* id */ + ui64 = (ui64 << MAP_BITS_SUBID) | mw->subid; woutpos = mempush (woutpos, &ui64, 8); - ui16 = mw->subid; /* subid */ - woutpos = mempush (woutpos, &ui16, 2); ui8 = mw->type; /* type */ woutpos = mempush (woutpos, &ui8, 1); ui8 = mw->flags; /* flags */ @@ -644,7 +645,7 @@ char *map_ls_hash2data (struct map_hash *mh, int *size) { map_ls_hashdatacheckpos (*size, &woutpos); /* save the basic data */ - ui64 = ma->id; /* id */ + ui64 = (ma->id << MAP_BITS_SUBID) | ma->subid; /* id */ woutpos = mempush (woutpos, &ui64, 8); ui8 = ma->type; /* type */ woutpos = mempush (woutpos, &ui8, 1); @@ -839,9 +840,8 @@ struct map_hash *map_ls_data2hash (char *data, int size) { for (cnt = 0; cnt < lsh.ways; cnt++) { /* load basic data */ inpos = mempop (inpos, &ui64, 8); - way->id = ui64; - inpos = mempop (inpos, &ui16, 2); - way->subid = ui16; + way->subid = ui64 % (1<id = (ui64 >> MAP_BITS_SUBID); inpos = mempop (inpos, &ui8, 1); way->type = ui8; inpos = mempop (inpos, &ui8, 1); @@ -914,6 +914,7 @@ struct map_hash *map_ls_data2hash (char *data, int size) { area->next = NULL; inpos = mempop (inpos, &ui64, 8); + area->subid = ui64 % (1<id = ui64; inpos = mempop (inpos, &ui8, 1); area->type = ui8; diff --git a/mapsys/map_osmload.c b/mapsys/map_osmload.c index 1c28f56..7c1f97c 100644 --- a/mapsys/map_osmload.c +++ b/mapsys/map_osmload.c @@ -34,6 +34,7 @@ #include "map.h" #include "system.h" #include "memoryleak.h" +#include "vector.h" #include #include @@ -190,6 +191,7 @@ void osm_waynodes_checknode (struct s_osm_hashnodes *nhash, struct osm_node *nod void osm_marea_new (struct s_osmmarea *a, int max); void osm_area_save (struct osm_way *oway, struct s_osmmarea *marea); +int osm_area_split_add (struct s_osmmarea *marea); void osm_nodedetail_save (struct osm_nodedetail *onoded, struct osm_node *node); @@ -696,7 +698,8 @@ void osm_waynode_add (struct osm_node *node, long long int nodepos, unsigned lon do { lseek (hnodes->nodes_fd, wpos, SEEK_SET); if (read (hnodes->nodes_fd, &wn, sizeof (struct osm_waynode)) < sizeof (struct osm_waynode)) { - d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, hnodes->fnnodes, hash.pos); + d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, + hnodes->fnnodes, hash.pos); errorexit (-1); } wpos = wn.next; @@ -707,7 +710,8 @@ void osm_waynode_add (struct osm_node *node, long long int nodepos, unsigned lon pos = 0 - (long long int)sizeof (struct osm_waynode); lseek (hnodes->nodes_fd, pos, SEEK_CUR); if (write (hnodes->nodes_fd, &wn, sizeof (struct osm_waynode)) < sizeof (struct osm_waynode)) { - d_printf ("%s:%d could not write data to file:%s pos:%d", __FILE__, __LINE__, hnodes->fnnodes, hash.pos); + d_printf ("%s:%d could not write data to file:%s pos:%d", __FILE__, __LINE__, + hnodes->fnnodes, hash.pos); errorexit (-1); } } @@ -719,7 +723,6 @@ void osm_waynode_add (struct osm_node *node, long long int nodepos, unsigned lon d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, hnodes->fnnodes, hash.pos); errorexit (-1); } - return; }; @@ -741,7 +744,8 @@ void osm_waynodes_check () { /* read node */ lseek (ohash->nodes_fd, ohash->hash[i].pos, SEEK_SET); if (read (ohash->nodes_fd, &node, sizeof (struct osm_node)) < sizeof (struct osm_node)) { - d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, ohash->fnnodes, ohash->hash[i].pos); + d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, + ohash->fnnodes, ohash->hash[i].pos); errorexit (-1); } osm_waynodes_checknode (ohash, &node); @@ -777,7 +781,8 @@ void osm_waynodes_checknode (struct s_osm_hashnodes *ohash, struct osm_node *nod do { /* read waynode */ if (read (ohash->nodes_fd, &osm_wnode[wncnt], sizeof (struct osm_waynode)) < sizeof (struct osm_waynode)) { - d_printf ("%s:%d could not read data from file:%s pos:%d", __FILE__, __LINE__, ohash->fnnodes, osm_wnode[wncnt].next); + d_printf ("%s:%d could not read data from file:%s pos:%d", + __FILE__, __LINE__, ohash->fnnodes, osm_wnode[wncnt].next); errorexit (-1); } lseek (ohash->nodes_fd, osm_wnode[wncnt].next, SEEK_SET); @@ -1036,6 +1041,7 @@ void osm_area_save (struct osm_way *oway, struct s_osmmarea *area ) { static int nodestat_alloc = 0; // size of the struct struct map_pos pos, p1; // current hash, pos struct osm_node curnode, node; // current node, node + int sid = 0; /* check if we just need to free all data */ if (oway == NULL) { @@ -1105,6 +1111,7 @@ void osm_area_save (struct osm_way *oway, struct s_osmmarea *area ) { /* save first node */ area->marea->id = oway->wid; + area->marea->subid = sid; area->marea->type = oway->type; area->marea->p_cnt = 1; area->marea->p = (struct map_pos *) area->marea->data; @@ -1120,7 +1127,8 @@ void osm_area_save (struct osm_way *oway, struct s_osmmarea *area ) { if (++nd >= oway->ncnt) nd = 0; /* count +1, check for overrun */ while (nd != ndfirst) { if (osm_node_load (&node, oway->nid[nd]) == -1) { - d_printf ("%s:%d osm_area_save count not find node number: %lld", __FILE__, __LINE__, oway->nid[nd]); + d_printf ("%s:%d osm_area_save count not find node number: %lld", + __FILE__, __LINE__, oway->nid[nd]); return; } pos.lon = node.lon; @@ -1150,7 +1158,7 @@ void osm_area_save (struct osm_way *oway, struct s_osmmarea *area ) { } if (++nd >= oway->ncnt) nd = 0; /* count +1, check for overrun */ } - map_area_add (area->marea, MHLOAD_RELOAD); + osm_area_split_add (area); } } while (ndfirst < oway->ncnt); @@ -1158,6 +1166,196 @@ void osm_area_save (struct osm_way *oway, struct s_osmmarea *area ) { }; +/* + * convert area into a polygon without angles above 180° + * it saves time late in drawing on slow devices. + * only needed because of GL_TRIANGLE_STRIP and return + * last subid saved. + */ +struct s_osmareapnt { + int pnr; + fPoint km; + float angle; +}; + + +int osm_area_split_add (struct s_osmmarea *marea) { + /* allocate enought memory */ + struct map_area *a = NULL; + struct s_osmareapnt *pall = ml_malloc (sizeof (struct s_osmareapnt) * marea->marea->p_cnt); + int pall_cnt = marea->marea->p_cnt; + int i, j, c, k, smaller; + int _debug = 0; + +// if (marea->marea->id == 29225778) _debug = 1; +// else return 1; +// d_printf ("marea: %lld cnt:%d", marea->marea->id, marea->marea->p_cnt); +// map_area_add (marea->marea, MHLOAD_RELOAD); +// return 1; + +// if (_debug) d_printf ("area:%lld:%d", marea->marea->id, marea->marea->subid); + a = ml_malloc (map_area_getsize (marea->marea)); + map_area_copy (a, marea->marea); + + /* calculate all klon, klat and prepare start struct, also + * ignore double entrys */ + for (c = 0, i = 0; i < marea->marea->p_cnt; i++) { + if (i == 0) j = marea->marea->p_cnt-1; + else j = i-1; + + if (marea->marea->p[i].lon == marea->marea->p[j].lon + && marea->marea->p[i].lat == marea->marea->p[j].lat) continue; + + pall[c].pnr = i; + pall[c].km.x = map_lon2km (marea->marea->p[i].lon, marea->marea->p[i].lat); + pall[c].km.y = map_lat2km (marea->marea->p[i].lat); + c++; + } + pall_cnt = c; + + while (pall[0].pnr >= 0 && pall_cnt > 2) { + /* j - will keep first ptr to start checking polygon + * c - counter how many angles > 180° */ +// d_printf ("**************** subid:%d pallcnt:%d", a->subid, pall_cnt); + for (smaller = 0, j = -1, c = 0, i = 0; i < pall_cnt; i++) { + if (i == pall_cnt-1) pall[i].angle = point_angle (pall[i-1].km, pall[i].km, pall[0].km); + else if (i == 0) pall[i].angle = point_angle (pall[pall_cnt-1].km, pall[i].km, pall[i+1].km); + else pall[i].angle = point_angle (pall[i-1].km, pall[i].km, pall[i+1].km); + if (pall[i].angle > M_PI) { + if (j == -1 ||j+1 == i) j = i; + c++; + } + else smaller = 1; +// if (_debug) d_printf ("i:%-2d pnr:%-2d angle:%f",i, pall[i].pnr, pall[i].angle); + } +// if (_debug) d_printf ("c:%d pall_cnt:%d j:%d",c, pall_cnt, j); + + /* if all angles are abover 180° turn rotation around */ + if (smaller == 0) { + struct s_osmareapnt *pall_ = ml_malloc (sizeof (struct s_osmareapnt) * pall_cnt); + +// if (_debug) d_printf ("change rotation ..."); + for (i = 0; i < pall_cnt; i++) pall_[pall_cnt - i - 1] = pall[i]; + ml_free (pall); + pall = pall_; + } + + /* if c==0 save last areapart */ + else if (c == 0) { + for (i = 0; i < pall_cnt; i++) { +// if (_debug) d_printf ("0: added %d pnr:%d", k, pall[i].pnr); + a->p[i] = marea->marea->p[pall[i].pnr]; + pall[i].pnr = -1; + } + a->p_cnt = pall_cnt; + map_area_add (a, MHLOAD_RELOAD); + a->subid++; + } + + /* if c==1 select j as 0 then quit, if GL_TRIANGLE_STRIP gets kicked out of + * openGL we need to change this */ + else if (c == 1) { + for (k = 0, i = j; k < pall_cnt;) { +// if (_debug) d_printf ("1: added %d pnr:%d", k, pall[i].pnr); + a->p[k++] = marea->marea->p[pall[i].pnr]; + pall[i].pnr = -1; + + if (i < pall_cnt-1) i++; + else i = 0; + } + a->p_cnt = pall_cnt; + map_area_add (a, MHLOAD_RELOAD); + a->subid++; + } + + /* check again for the part to split the area. */ + else { + float angle; + int s; /* second point */ + float angle_old; /* old value */ + int i_old; + int pnr_old; + + k = 0; + i = j; + +// if (_debug) d_printf ("added %d pnr:%d", k, pall[i].pnr); + a->p[k++] = marea->marea->p[pall[i].pnr]; /* copy first point */ + if (i < pall_cnt-1) i++; /* increase */ + else i = 0; + + i_old = s = i; + angle_old = angle = 0.0; + if (_debug) d_printf ("pall_cnt:%d c:%d s:%d j:%d", pall_cnt, c, s, j); + + /* loop as long as angle is increasing and below 180° */ + for (; i != j && angle_old <= angle && angle <= M_PI;) { + angle_old = angle; /* save old values */ + i_old = i; + pnr_old = pall[i].pnr; +// if (_debug) d_printf ("added %d pnr:%d", k, pall[i].pnr); + a->p[k++] = marea->marea->p[pall[i].pnr]; /* copy point */ + pall[i].pnr = -1; + + if (i < pall_cnt-1) i++; /* increase */ + else i = 0; + angle = point_angle (pall[i].km, pall[j].km, pall[s].km); +// if (_debug) d_printf ("k:%d next angle:%f angle_old:%f pall[%d].angle:%f nr:%d", k, angle, angle_old, i, pall[i].angle, pall[i].pnr); + } + +// if (_debug) d_printf ("j:%d i:%d s:%d k:%d angle:%f angle_old:%f pall[i].angle:%f", +// j, i, s, k, angle, angle_old, pall[i].angle); + +// /* last visible point */ +// if (pall[i].angle > M_PI) { +// if (_debug) d_printf ("added %d pnr:%d", k, pall[i].pnr); +// a->p[k++] = marea->marea->p[pall[i].pnr]; /* copy point */ +// } +// else + if (angle_old > angle) { + pall[i_old].pnr = pnr_old; + } + else if (angle > M_PI) { + pall[i_old].pnr = pnr_old; + } + else if (i == j) { + d_printf ("%s:%d i(%d) == j(%d) finished?", __FILE__, __LINE__, i, j); + } + +// if (_debug) d_printf ("j:%d i:%d s:%d k:%d angle:%f angle_old:%f pall[i].angle:%f", +// j, i, s, k, angle, angle_old, pall[i].angle); + + /* add element */ + a->p_cnt = k; + map_area_add (a, MHLOAD_RELOAD); + a->subid++; + } + + /* recreate pall list, delete unneeded elements (pnr == -1) */ + for (k = 0, i = 0; i < pall_cnt; i++) + if (pall[i].pnr != -1) { + pall[k++] = pall[i]; +// if (_debug) d_printf (" old:%-2d new:%-2d pnr:%d", i, k, pall[i].pnr); + } + pall_cnt = k; + } + +// if (_debug) d_printf ("j:%d c:%d", j, c); + if (pall[0].pnr >= 0 && pall_cnt > 0) { + d_printf ("%s:%d osm_area_split_add: something went very wrong", __FILE__, __LINE__); + d_printf (" marea->id: %lld:%d", marea->marea->id, marea->marea->subid); + d_printf (" pall[0].pnr:%d pall_cnt: %d", pall[0].pnr, pall_cnt); + + } + + /* free unneeded memory and return to caller */ + ml_free (a); + ml_free (pall); + + return a->subid; +}; + + /******************************************************************** * save detail information of the node. This will also create the