|
|
|
|
@ -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);
|
|
|
|
|
/* 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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (angle_old > angle) {
|
|
|
|
|
pall[i_old].pnr = pnr_old;
|
|
|
|
|
j++; if (j >= pt_c) j = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (angle > M_PI) {
|
|
|
|
|
pall[i_old].pnr = pnr_old;
|
|
|
|
|
if (j != sel) {
|
|
|
|
|
/* something is in the way */
|
|
|
|
|
if (_debug) d_printf (" break 2");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (i == j) {
|
|
|
|
|
d_printf ("%s:%d i(%d) == j(%d) finished?", __FILE__, __LINE__, i, j);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} while (sel > st && a->p_cnt < 3);
|
|
|
|
|
|
|
|
|
|
/* add element */
|
|
|
|
|
a->p_cnt = k;
|
|
|
|
|
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);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
pall_cnt = k;
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|