some fixes on splitting areas..

master
steffen 13 years ago
parent 08d75cf3b5
commit 5c0bfbe028

@ -485,13 +485,13 @@ void draw_map () {
|| ((view_scale < 0.1 && (n % 2) == 0) || carea->p_cnt < 5) || ((view_scale < 0.1 && (n % 2) == 0) || carea->p_cnt < 5)
|| ((view_scale < 0.1 && (n % 4) == 0) || carea->p_cnt < 10)) { || ((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); p1 = draw_geo2screen (view_lon, view_lat, carea->p[n].lon, carea->p[n].lat);
// if (n == 0) { 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);
// 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); if (n == 0) sprintf (text, "%d:%d", n, carea->subid);
// else sprintf (text, "%d", n); 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]); 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_polygonadd (p1.x + center.x, p1.y + center.y);
} }
draw_polygonfinish (img_map, tmplinestyle, &color_polygon[carea->type], 0); draw_polygonfinish (img_map, tmplinestyle, &color_polygon[carea->type], 0);

@ -92,8 +92,8 @@ int map_area_add (struct map_area *area, int loadflags) {
int size; int size;
if (area->p == NULL || area->p_cnt == 0) return 0; if (area->p == NULL || area->p_cnt == 0) return 0;
// area->type = area->subid % MAREA_campsite + 1; area->type = area->subid % MAREA_campsite + 1;
// d_printf ("subid:%d type:%d cnt:%d", area->subid, area->type, area->p_cnt); d_printf ("subid:%d type:%d cnt:%d", area->subid, area->type, area->p_cnt);
size = map_area_getsize (area); size = map_area_getsize (area);
mh = map_hash_get (area->p[0].lon, area->p[0].lat, loadflags); mh = map_hash_get (area->p[0].lon, area->p[0].lat, loadflags);

@ -1177,79 +1177,83 @@ struct s_osmareapnt {
int pnr; int pnr;
fPoint km; fPoint km;
float angle; 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) { int osm_area_split_add (struct s_osmmarea *marea) {
/* allocate enought memory */ /* allocate enought memory */
struct map_area *a = NULL; struct map_area *a = NULL;
struct s_osmareapnt *pall = ml_malloc (sizeof (struct s_osmareapnt) * marea->marea->p_cnt); struct s_osmareapnt *pt = ml_malloc (sizeof (struct s_osmareapnt) * marea->marea->p_cnt);
int pall_cnt = marea->marea->p_cnt; int i, st, pt_c, c;
int i, j, c, k, smaller; int _debug = 0;
// int _debug = 0; float angle_sum;
// if (marea->marea->id == 4470478) _debug = 1; if (marea->marea->id == 18763935) _debug = 1;
// else return 1; else return 1;
// d_printf ("marea: %lld cnt:%d", marea->marea->id, marea->marea->p_cnt); d_printf ("marea: %lld cnt:%d", marea->marea->id, marea->marea->p_cnt);
// map_area_add (marea->marea, MHLOAD_RELOAD); // map_area_add (marea->marea, MHLOAD_RELOAD);
// return 1; // 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)); a = ml_malloc (map_area_getsize (marea->marea));
map_area_copy (a, marea->marea); map_area_copy (a, marea->marea);
/* calculate all klon, klat and prepare start struct, also /* calculate all klon, klat and prepare start struct, also
* ignore double entrys */ * ignore double entrys */
for (c = 0, i = 0; i < marea->marea->p_cnt; i++) { for (pt_c = 0, i = 0; i < marea->marea->p_cnt; i++) {
if (i == 0) j = marea->marea->p_cnt-1; if (i == 0) st = marea->marea->p_cnt-1;
else j = i-1; else st = i-1;
if (marea->marea->p[i].lon == marea->marea->p[j].lon if (marea->marea->p[i].lon == marea->marea->p[st].lon
&& marea->marea->p[i].lat == marea->marea->p[j].lat) continue; && marea->marea->p[i].lat == marea->marea->p[st].lat) continue;
pall[c].pnr = i; pt[pt_c].pnr = i;
pall[c].km.x = map_lon2km (marea->marea->p[i].lon, marea->marea->p[i].lat); pt[pt_c].angle = -1.0;
pall[c].km.y = map_lat2km (marea->marea->p[i].lat); pt[pt_c].km.x = map_lon2km (marea->marea->p[i].lon, marea->marea->p[i].lat);
c++; 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);
pall_cnt = c; pt_c++;
}
while (pall[0].pnr >= 0 && pall_cnt > 2 && a->subid < MAX_SUBID) {
/* j - will keep first ptr to start checking polygon while (pt[0].pnr >= 0 && pt_c > 2 && a->subid < MAX_SUBID) {
* c - counter how many angles > 180° */ /* st - will keep first pt to start checking polygon
// d_printf ("**************** subid:%d pallcnt:%d", a->subid, pall_cnt); * c - count how many angles are above 180° */
for (smaller = 0, j = -1, c = 0, i = 0; i < pall_cnt; i++) { d_printf ("**************** subid:%d pt_c:%d", a->subid, pt_c);
if (i == pall_cnt-1) pall[i].angle = point_angle (pall[i-1].km, pall[i].km, pall[0].km); for (angle_sum = 0.0, st = -1, c = 0, i = 0; i < pt_c; i++) {
else if (i == 0) pall[i].angle = point_angle (pall[pall_cnt-1].km, pall[i].km, pall[i+1].km); if (i == pt_c-1) pt[i].angle = point_angle (pt[i-1].km, pt[i].km, pt[0].km);
else pall[i].angle = point_angle (pall[i-1].km, pall[i].km, pall[i+1].km); else if (i == 0) pt[i].angle = point_angle (pt[pt_c-1].km, pt[i].km, pt[i+1].km);
if (pall[i].angle > M_PI) { else pt[i].angle = point_angle (pt[i-1].km, pt[i].km, pt[i+1].km);
if (j == -1 ||j+1 == i) j = i; if (pt[i].angle > M_PI) { /* only select first pt */
if (st == -1 ||st+1 == i) st = i;
c++; c++;
} }
else smaller = 1; angle_sum += pt[i].angle;
// if (_debug) d_printf ("i:%-2d pnr:%-2d angle:%f",i, pall[i].pnr, pall[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 */ /* make sure we going counterclock direction, only first area */
if (smaller == 0) { if (angle_sum > M_PI && a->subid == marea->marea->subid) {
struct s_osmareapnt *pall_ = ml_malloc (sizeof (struct s_osmareapnt) * pall_cnt); struct s_osmareapnt *pt_ = ml_malloc (sizeof (struct s_osmareapnt) * pt_c);
// if (_debug) d_printf ("change rotation ..."); if (_debug) d_printf ("change rotation ...");
for (i = 0; i < pall_cnt; i++) pall_[pall_cnt - i - 1] = pall[i]; for (i = 0; i < pt_c; i++) pt_[pt_c - i - 1] = pt[i];
ml_free (pall); ml_free (pt);
pall = pall_; pt = pt_;
} }
/* if c==0 save last areapart */ /* if c==0 save last areapart */
else if (c == 0) { else if (c == 0) {
for (i = 0; i < pall_cnt; i++) { a->p_cnt = 0;
// if (_debug) d_printf ("0: added %d pnr:%d", k, pall[i].pnr); for (i = 0; i < pt_c; i++) {
a->p[i] = marea->marea->p[pall[i].pnr]; if (_debug) d_printf ("0: added %d pnr:%d", a->p_cnt, pt[i].pnr);
pall[i].pnr = -1; 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); map_area_add (a, MHLOAD_RELOAD);
a->subid++; 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 /* if c==1 select j as 0 then quit, if GL_TRIANGLE_STRIP gets kicked out of
* openGL we need to change this */ * openGL we need to change this */
else if (c == 1) { else if (c == 1) {
for (k = 0, i = j; k < pall_cnt;) { for (a->p_cnt = 0, i = st; a->p_cnt < pt_c;) {
// if (_debug) d_printf ("1: added %d pnr:%d", k, pall[i].pnr); if (_debug) d_printf ("1: added %d pnr:%d", a->p_cnt, pt[i].pnr);
a->p[k++] = marea->marea->p[pall[i].pnr]; a->p[a->p_cnt++] = marea->marea->p[pt[i].pnr];
pall[i].pnr = -1; pt[i].pnr = -1;
if (i < pall_cnt-1) i++; if (i < pt_c-1) i++;
else i = 0; else i = 0;
} }
a->p_cnt = pall_cnt;
map_area_add (a, MHLOAD_RELOAD); map_area_add (a, MHLOAD_RELOAD);
a->subid++; a->subid++;
} }
/* check again for the part to split the area. */ /* check again for the part to split the area. */
else { else {
int j, sel, s, i_old, c;
float dist;
float angle; 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", /* check if selected start is working for us */
// j, i, s, k, angle, angle_old, pall[i].angle); 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 */ a->p_cnt = 0;
if (pall[i].angle > M_PI) { a->p[a->p_cnt++] = marea->marea->p[pt[sel].pnr];
// if (_debug) d_printf ("added %d pnr:%d", k, pall[i].pnr); angle = 0.0;
a->p[k++] = marea->marea->p[pall[i].pnr]; /* copy point */ 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;) {
else if (_debug) d_printf (" i:%d sel:%d angle:%f pt[i].sel_angle:%f", i, st, angle, pt[i].sel_angle);
if (angle_old > angle) { for (j = i; j != sel;) {
pall[i_old].pnr = pnr_old; 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) {
else if (angle > M_PI) { if (_debug) d_printf (" break 1");
pall[i_old].pnr = pnr_old; break;
} }
else if (i == j) { j++; if (j >= pt_c) j = 0;
d_printf ("%s:%d i(%d) == j(%d) finished?", __FILE__, __LINE__, i, j); }
} 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", } while (sel > st && a->p_cnt < 3);
// j, i, s, k, angle, angle_old, pall[i].angle);
/* add element */ /* add element */
a->p_cnt = k; if (a->p_cnt >= 3) {
map_area_add (a, MHLOAD_RELOAD); map_area_add (a, MHLOAD_RELOAD);
a->subid++; a->subid++;
}
} }
/* recreate pall list, delete unneeded elements (pnr == -1) */ /* recreate pall list, delete unneeded elements (pnr == -1) */
for (k = 0, i = 0; i < pall_cnt; i++) for (c = 0, i = 0; i < pt_c; i++) if (pt[i].pnr != -1) pt[c++] = pt[i];
if (pall[i].pnr != -1) { if (pt_c == c) {
pall[k++] = pall[i]; d_printf ("%s:%d pt_c == c : nothing deleted.. something went wrong.", __FILE__, __LINE__);
// if (_debug) d_printf (" old:%-2d new:%-2d pnr:%d", i, k, pall[i].pnr); break;
} }
pall_cnt = k; pt_c = c;
} }
if (a->subid >= MAX_SUBID) { if (a->subid >= MAX_SUBID) {
d_printf ("%s:%d max subid reached. area id:%lld", __FILE__, __LINE__, a->id); 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 (pt[0].pnr >= 0 && pt_c > 0) {
if (pall[0].pnr >= 0 && pall_cnt > 0) {
d_printf ("%s:%d osm_area_split_add: something went very wrong", __FILE__, __LINE__); 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 (" 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 */ /* free unneeded memory and return to caller */
ml_free (a); ml_free (a);
ml_free (pall); ml_free (pt);
return a->subid; return a->subid;
}; };

Loading…
Cancel
Save