From 5c0bfbe028fd3f9999bf10376c6a60c861bc7c3c Mon Sep 17 00:00:00 2001 From: steffen Date: Mon, 13 May 2013 22:27:35 +0000 Subject: [PATCH] some fixes on splitting areas.. --- draw/draw.c | 14 +-- mapsys/map_area.c | 4 +- mapsys/map_osmload.c | 250 +++++++++++++++++++++++-------------------- 3 files changed, 141 insertions(+), 127 deletions(-) diff --git a/draw/draw.c b/draw/draw.c index 020278a..12c8570 100644 --- a/draw/draw.c +++ b/draw/draw.c @@ -485,13 +485,13 @@ void draw_map () { || ((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]); + 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); diff --git a/mapsys/map_area.c b/mapsys/map_area.c index 66a865d..60d7695 100644 --- a/mapsys/map_area.c +++ b/mapsys/map_area.c @@ -92,8 +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); + 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); diff --git a/mapsys/map_osmload.c b/mapsys/map_osmload.c index c51a57d..e2417dd 100644 --- a/mapsys/map_osmload.c +++ b/mapsys/map_osmload.c @@ -1177,79 +1177,83 @@ struct s_osmareapnt { int pnr; fPoint km; float angle; + float sel_dist; + float sel_angle; }; -#define MAX_SUBID 100 +#define MAX_SUBID 40 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 == 4470478) _debug = 1; -// else return 1; -// d_printf ("marea: %lld cnt:%d", marea->marea->id, marea->marea->p_cnt); + struct s_osmareapnt *pt = ml_malloc (sizeof (struct s_osmareapnt) * marea->marea->p_cnt); + int i, st, pt_c, c; + int _debug = 0; + float angle_sum; + + if (marea->marea->id == 18763935) _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); + 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 && a->subid < MAX_SUBID) { - /* 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; + for (pt_c = 0, i = 0; i < marea->marea->p_cnt; i++) { + if (i == 0) st = marea->marea->p_cnt-1; + else st = i-1; + + if (marea->marea->p[i].lon == marea->marea->p[st].lon + && marea->marea->p[i].lat == marea->marea->p[st].lat) continue; + + pt[pt_c].pnr = i; + pt[pt_c].angle = -1.0; + pt[pt_c].km.x = map_lon2km (marea->marea->p[i].lon, marea->marea->p[i].lat); + pt[pt_c].km.y = map_lat2km (marea->marea->p[i].lat); + if (_debug) d_printf ("pt[%-3d].pnr:%d km.x:%f km.y:%f", pt_c, pt[pt_c].pnr, pt[pt_c].km.x, pt[pt_c].km.y); + pt_c++; + } + + while (pt[0].pnr >= 0 && pt_c > 2 && a->subid < MAX_SUBID) { + /* st - will keep first pt to start checking polygon + * c - count how many angles are above 180° */ + d_printf ("**************** subid:%d pt_c:%d", a->subid, pt_c); + for (angle_sum = 0.0, st = -1, c = 0, i = 0; i < pt_c; i++) { + if (i == pt_c-1) pt[i].angle = point_angle (pt[i-1].km, pt[i].km, pt[0].km); + else if (i == 0) pt[i].angle = point_angle (pt[pt_c-1].km, pt[i].km, pt[i+1].km); + else pt[i].angle = point_angle (pt[i-1].km, pt[i].km, pt[i+1].km); + if (pt[i].angle > M_PI) { /* only select first pt */ + if (st == -1 ||st+1 == i) st = i; c++; } - else smaller = 1; -// if (_debug) d_printf ("i:%-2d pnr:%-2d angle:%f",i, pall[i].pnr, pall[i].angle); + angle_sum += pt[i].angle; + if (_debug) d_printf ("i:%-2d pnr:%-2d angle:%f",i, pt[i].pnr, pt[i].angle); } -// if (_debug) d_printf ("c:%d pall_cnt:%d j:%d",c, pall_cnt, j); + angle_sum /= (float)pt_c; + if (_debug) d_printf ("c:%d pt_c:%d st:%d angle_sum:%f",c, pt_c, st, angle_sum); - /* if all angles are abover 180° turn rotation around */ - if (smaller == 0) { - struct s_osmareapnt *pall_ = ml_malloc (sizeof (struct s_osmareapnt) * pall_cnt); + /* make sure we going counterclock direction, only first area */ + if (angle_sum > M_PI && a->subid == marea->marea->subid) { + struct s_osmareapnt *pt_ = ml_malloc (sizeof (struct s_osmareapnt) * pt_c); -// 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 (_debug) d_printf ("change rotation ..."); + for (i = 0; i < pt_c; i++) pt_[pt_c - i - 1] = pt[i]; + ml_free (pt); + pt = pt_; } /* 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 = 0; + for (i = 0; i < pt_c; i++) { + if (_debug) d_printf ("0: added %d pnr:%d", a->p_cnt, pt[i].pnr); + a->p[a->p_cnt++] = marea->marea->p[pt[i].pnr]; + pt[i].pnr = -1; } - a->p_cnt = pall_cnt; map_area_add (a, MHLOAD_RELOAD); a->subid++; } @@ -1257,106 +1261,116 @@ int osm_area_split_add (struct s_osmmarea *marea) { /* 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; + for (a->p_cnt = 0, i = st; a->p_cnt < pt_c;) { + if (_debug) d_printf ("1: added %d pnr:%d", a->p_cnt, pt[i].pnr); + a->p[a->p_cnt++] = marea->marea->p[pt[i].pnr]; + pt[i].pnr = -1; - if (i < pall_cnt-1) i++; + if (i < pt_c-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 { + int j, sel, s, i_old, c; + float dist; 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); + /* check if selected start is working for us */ + sel = st; + i_old = -1; + do { + /* fill up all sel_angles and sel_dists */ + if (sel < pt_c-1) s = sel + 1; + else s = 0; + if (_debug) d_printf ("select %d [pnr:%d] second:%d", sel, pt[sel].pnr, s); + for (i = 0; i < pt_c; i++) { + if (i != sel) { + pt[i].sel_angle = point_angle (pt[i].km, pt[st].km, pt[s].km); + pt[i].sel_dist = vec_len (vec_sub (pt[i].km, pt[st].km)); + } + else { + pt[i].sel_angle = -2.0; + pt[i].sel_dist = -2.0; + } + if (_debug) d_printf (" %-2d pnr:%-2d angle:%f dist:%f", i, pt[i].pnr, pt[i].sel_angle, pt[i].sel_dist); + } - /* 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); - } + a->p_cnt = 0; + a->p[a->p_cnt++] = marea->marea->p[pt[sel].pnr]; + angle = 0.0; + if (_debug) d_printf (" check for possible loop: i:%d s:%d st:%d sel:%d angle:%f pt[i].sel_angle:%f", i, s, st, sel, angle, pt[i].sel_angle); + for (i_old = -1, i = s, angle = 0.0; i != sel && angle <= pt[i].sel_angle;) { + if (_debug) d_printf (" i:%d sel:%d angle:%f pt[i].sel_angle:%f", i, st, angle, pt[i].sel_angle); + for (j = i; j != sel;) { + if (_debug) d_printf (" j:%d (pnr:%d, angle:%f, dist:%f) i:%d (pnr:%d, angle:%f, dist:%f) ", j, pt[j].pnr, pt[j].sel_angle, pt[j].sel_dist, i, pt[i].pnr, pt[i].sel_angle, pt[i].sel_dist); + if (pt[i].sel_angle > pt[j].sel_angle && pt[i].sel_dist > pt[j].sel_dist) { + if (_debug) d_printf (" break 1"); + break; + } + j++; if (j >= pt_c) j = 0; + } + if (j != sel) { + /* something is in the way */ + if (_debug) d_printf (" break 2"); + break; + } + else { + /* found something */ + if (i_old >= 0) pt[i_old].pnr = -1; /* already second pass */ + a->p[a->p_cnt++] = marea->marea->p[pt[i].pnr]; + if (_debug) d_printf ("add nr:%d pnr:%d", a->p_cnt-1, pt[i].pnr); + angle = pt[i].sel_angle; + } + + i_old = i; + i++; if (i >= pt_c) i = 0; + } + + if (a->p_cnt < 3) { + /* found nothing try next one */ + i = sel + 1; if (i >= pt_c) i = 0; + do { + sel = i; + i++; if (i >= pt_c) i = 0; + } while (sel > st && (pt[i].angle > M_PI || pt[sel].angle < M_PI)); + } -// 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); + } while (sel > st && a->p_cnt < 3); /* add element */ - a->p_cnt = k; - map_area_add (a, MHLOAD_RELOAD); - a->subid++; + if (a->p_cnt >= 3) { + 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; + for (c = 0, i = 0; i < pt_c; i++) if (pt[i].pnr != -1) pt[c++] = pt[i]; + if (pt_c == c) { + d_printf ("%s:%d pt_c == c : nothing deleted.. something went wrong.", __FILE__, __LINE__); + break; + } + pt_c = c; } if (a->subid >= MAX_SUBID) { d_printf ("%s:%d max subid reached. area id:%lld", __FILE__, __LINE__, a->id); } -// if (_debug) d_printf ("j:%d c:%d", j, c); - if (pall[0].pnr >= 0 && pall_cnt > 0) { + if (pt[0].pnr >= 0 && pt_c > 0) { d_printf ("%s:%d osm_area_split_add: something went very wrong", __FILE__, __LINE__); d_printf (" marea->id: %lld:%d", a->id, a->subid); - d_printf (" pall[0].pnr:%d pall_cnt: %d", pall[0].pnr, pall_cnt); + d_printf (" pt[0].pnr:%d pall_cnt: %d", pt[0].pnr, pt_c); } /* free unneeded memory and return to caller */ ml_free (a); - ml_free (pall); + ml_free (pt); return a->subid; };