/* * draw_route.c * Copyright (C) Steffen Pohle 2011 * * main.c is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * main.c is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include #include #include "osmroute.h" #include "draw.h" #include "map.h" #include "routing.h" #include "gps.h" #include "system.h" void draw_routelist (struct rtwaylist *rtlist, struct line_style linestyle, int cnt); /**************************************************************************** * drawing routing information on the screen */ void draw_gui_route () { struct map_hash *mh; struct map_way *mw; struct line_style tmplinestyle; iPoint p1, p2, center = {gfx_screensize.x/2, gfx_screensize.y/2}; fPoint nd; float angle, f; int j, n, i; char text[256]; struct rtwaylist *rtlist = NULL; if (route == NULL) return; /* * draw the destination route thick */ mh = map_hash_get (route->dest.lon, route->dest.lat, MHLOAD_RELOAD); mw = map_way_find (mh, route->dest_way_id, route->dest_way_sid); if (mw) { /* go through all the nodes */ tmplinestyle.width = 5; tmplinestyle.c = color[COLOR_white][3]; for (n = 0; n < mw->p_cnt; n++) { p2 = p1; nd.x = map_lon2km (view_lon - mw->p[n].lon, mw->p[n].lat); nd.y = map_lat2km (view_lat - mw->p[n].lat); p1.x = center.x - (nd.x / view_scale); p1.y = center.y + (nd.y / view_scale); if (n > 0) { draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle); } } } /* * draw the destination cross */ tmplinestyle.width = 2.0; tmplinestyle.c = tmplinestyle.borderc = color[COLOR_greengray][3]; p1 = draw_geo2screen (view_lon, view_lat, route->dest.lon, route->dest.lat); p1.x += center.x; p1.y += center.y; draw_line (NULL, p1.x-5, p1.y-5, p1.x+5, p1.y+5, tmplinestyle); draw_line (NULL, p1.x+5, p1.y-5, p1.x-5, p1.y+5, tmplinestyle); if (view_flags & DRAW_DEBUG && route->state > ROUTING_INIT) { p1 = draw_geo2screen (view_lon, view_lat, route->pos.lon, route->pos.lat); p1.x += center.x; p1.y += center.y; p2 = draw_geo2screen (view_lon, view_lat, route->dest.lon, route->dest.lat); p2.x += center.x; p2.y += center.y; draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle); } /* * display some information */ if (route->state == ROUTING_CALC) { sprintf (text, _("calculating: %5.2g%% %g/%g"), 100.0-(100.0*route->closest_distance/route->distance), route->closest_distance, route->distance); } else if (route->state == ROUTING_OPTIMIZE) { sprintf (text, _("optimizing:")); } else if (route->state == ROUTING_ONWAY) { sprintf (text, _("onway dist: %3.1fkm"), route->distance); } else if (route->state == ROUTING_INIT) { sprintf (text, _("init")); } else if (route->state == ROUTING_ABORT) { sprintf (text, _("abort")); } else { sprintf (text, _("unknown state: %d"), route->state); } gfx_draw_text (NULL, 0, gfx_screensize.y-32, text, &color[COLOR_greengray][3]); /* * draw compass */ tmplinestyle.width = 1.0; tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3]; draw_line (NULL, center.x-100, 40, center.x+100, 40, tmplinestyle); for (angle = 0.0; angle < 360.0; angle = angle + 45.0) { f = angle - drawgps_data.direction; if (f > 180.0) f = f - 360.0; if (f < -180.0) f = f + 360.0; if (f >= -100.0 && f <= 100.0) { draw_line (NULL, center.x+f, 40, center.x+f, 37, tmplinestyle); if (angle == 0.0) { sprintf (text, _("N")); gfx_draw_text (NULL, center.x+f-4, 41, text, &color[COLOR_white][3]); } else if (angle == 90.0) { sprintf (text, _("E")); gfx_draw_text (NULL, center.x+f-4, 41, text, &color[COLOR_white][3]); } else if (angle == 180.0) { sprintf (text, _("S")); gfx_draw_text (NULL, center.x+f-4, 41, text, &color[COLOR_white][3]); } else if (angle == 270.0) { sprintf (text, _("W")); gfx_draw_text (NULL, center.x+f-4, 41, text, &color[COLOR_white][3]); } } } f = route->angle - drawgps_data.direction; if (f > 180.0) f = f - 360.0; if (f < -180.0) f = f + 360.0; if (f < -100.0) f = -100.0; else if (f > 100.0) f = 100.0; else { tmplinestyle.width = 2.0; tmplinestyle.c = tmplinestyle.borderc = color[COLOR_greengray][3]; draw_line (NULL, center.x+f, 45, center.x+f, 35, tmplinestyle); gfx_draw_text (NULL, center.x+f-4, 41, "*", &color[COLOR_greengray][3]); } /* * debug information */ if (view_flags & DRAW_DEBUG) { for (j = 0; j < 4; j++) { if (j == 0) { rtlist = &route->stack1; tmplinestyle.width = 2; tmplinestyle.c = color[COLOR_blue][3]; draw_routelist (rtlist, tmplinestyle, 64); } else if (j == 1) { rtlist = &route->stack2; tmplinestyle.width = 2; tmplinestyle.c = color[COLOR_blue][3]; draw_routelist (rtlist, tmplinestyle, 64); } else if (j == 2) { rtlist = &route->stack3; tmplinestyle.width = 2; tmplinestyle.c = color[COLOR_blue][3]; draw_routelist (rtlist, tmplinestyle, 64); } else if (j == 3) { rtlist = &route->ways; tmplinestyle.width = 3; tmplinestyle.c = color[COLOR_red][2]; draw_routelist (rtlist, tmplinestyle, -1); } } /* * draw information about the way */ rtlist = NULL; /* check route->ways */ for (i = 0; i < route->ways.cnt; i++) { if (mouse_over_way_id == route->ways.array[i].way.id && mouse_over_way_sid == route->ways.array[i].way.sid) { rtlist = &route->ways; break; } } /* check route->stacks */ if (rtlist == NULL) for (i = 0; i < route->stack1.cnt; i++) { if (mouse_over_way_id == route->stack1.array[i].way.id && mouse_over_way_sid == route->stack1.array[i].way.sid) { rtlist = &route->stack1; break; } } if (rtlist == NULL) for (i = 0; i < route->stack2.cnt; i++) { if (mouse_over_way_id == route->stack2.array[i].way.id && mouse_over_way_sid == route->stack2.array[i].way.sid) { rtlist = &route->stack2; break; } } if (rtlist == NULL) for (i = 0; i < route->stack3.cnt; i++) { if (mouse_over_way_id == route->stack3.array[i].way.id && mouse_over_way_sid == route->stack3.array[i].way.sid) { rtlist = &route->stack3; break; } } if (rtlist && i >= 0) { sprintf (text, "dist2pos:%g dist2dest:%g step:%d", rtlist->array[i].dist2pos, rtlist->array[i].dist2dest, rtlist->array[i].step); gfx_draw_text (NULL, 200, gfx_screensize.y-16, text, &color[COLOR_yellow][3]); sprintf (text, "prio:%g deltadistr:%g", rtlist->array[i].priority, rtlist->array[i].deltadist); gfx_draw_text (NULL, 200, gfx_screensize.y-28, text, &color[COLOR_yellow][3]); sprintf (text, "%lld:%d (pnr:%d)", rtlist->array[i].way.id, rtlist->array[i].way.sid, rtlist->array[i].pnr); gfx_draw_text (NULL, 200, gfx_screensize.y-40, text, &color[COLOR_yellow][3]); sprintf (text, "way:%g cycle:%d:%d", rtlist->array[i].dist2dest, rtlist->array[i].cycle1, rtlist->array[i].cycle2); gfx_draw_text (NULL, 200, gfx_screensize.y-52, text, &color[COLOR_yellow][3]); } /* display additional information */ sprintf (text, "r->stack1: %d prio:%g", route->stack1.cnt, (route->stack1.cnt == 0) ? 0.0 : route->stack1.array[route->stack1.cnt-1].priority); gfx_draw_text (NULL, 80, 80, text, &color[COLOR_yellow][3]); sprintf (text, "r->stack2: %d prio:%g", route->stack2.cnt, (route->stack2.cnt == 0) ? 0.0 : route->stack2.array[route->stack2.cnt-1].priority); gfx_draw_text (NULL, 80, 96, text, &color[COLOR_yellow][3]); sprintf (text, "r->stack3: %d prio:%g", route->stack3.cnt, (route->stack3.cnt == 0) ? 0.0 : route->stack3.array[route->stack3.cnt-1].priority); gfx_draw_text (NULL, 80, 112, text, &color[COLOR_yellow][3]); sprintf (text, "r->ways: %d", route->ways.cnt); gfx_draw_text (NULL, 80, 128, text, &color[COLOR_yellow][2]); sprintf (text, "r->route: %d", route->route.cnt); gfx_draw_text (NULL, 80, 144, text, &color[COLOR_yellow][3]); } /* * draw the calculated route.. */ rtlist = &route->route; tmplinestyle.width = 3; tmplinestyle.c = color[COLOR_redgray][3]; draw_routelist (rtlist, tmplinestyle, -1); }; void draw_routelist (struct rtwaylist *rtlist, struct line_style linestyle, int cnt) { struct map_hash *mh; struct map_way *mw; iPoint p1, p2, center = {gfx_screensize.x/2, gfx_screensize.y/2}; fPoint nd; int n, i, ps, pe; struct rtway* rtw = NULL; if (rtlist) for (i = 0; i < rtlist->cnt && (i < cnt || cnt == -1); i++) { rtw = &rtlist->array[i]; mh = map_hash_get (rtw->pos.lon, rtw->pos.lat, MHLOAD_RELOAD); mw = map_way_find (mh, rtw->way.id, rtw->way.sid); // d_printf ("draw route %d: mw:%p id:%lld subid:%d pos:(%g,%g)", i, mw, route->ways.array[i].way.id, route->ways.array[i].way.sid, // route->ways.array[i].pos.lon, route->ways.array[i].pos.lat ); if (mw) { /* go through all the nodes */ if (rtlist == &route->route && i < rtlist->cnt-1) { ps = rtlist->array[i].pnr; for (n = 0, pe = mw->p_cnt; n < mw->n_cnt; n++) if (mw->n[n].d_id == rtlist->array[i+1].way.id && mw->n[n].d_subid == rtlist->array[i+1].way.sid) { pe = mw->n[n].pnr; } if (pe < ps) { n = pe; pe = ps; ps = n; } pe++; if (pe >= mw->p_cnt) pe = mw->p_cnt; //d_printf ("%d %lld:%d ps:%d pe:%d", i, rtlist->array[i].way.id, rtlist->array[i].way.sid, ps, pe); } else { ps = 0; pe = mw->p_cnt; } for (n = ps; n < pe; n++) { p2 = p1; nd.x = map_lon2km (view_lon - mw->p[n].lon, mw->p[n].lat); nd.y = map_lat2km (view_lat - mw->p[n].lat); p1.x = center.x - (nd.x / view_scale); p1.y = center.y + (nd.y / view_scale); if ((p1.x >= 0 && p1.x < gfx_screensize.x && p1.y >= 0 && p1.y < gfx_screensize.y) || (p2.x >= 0 && p2.x < gfx_screensize.x && p2.y >= 0 && p2.y < gfx_screensize.y)) { if (n > ps) { draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, linestyle); } } } for (n = 0; n < mw->n_cnt; n++) { nd.x = map_lon2km (view_lon - mw->n[n].d.lon, mw->n[n].d.lat); nd.y = map_lat2km (view_lat - mw->n[n].d.lat); p1.x = center.x - (nd.x / view_scale); p1.y = center.y + (nd.y / view_scale); nd.x = map_lon2km (view_lon - mw->p[mw->n[n].pnr].lon, mw->p[mw->n[n].pnr].lat); nd.y = map_lat2km (view_lat - mw->p[mw->n[n].pnr].lat); p2.x = center.x - (nd.x / view_scale); p2.y = center.y + (nd.y / view_scale); if ((p1.x >= 0 && p1.x < gfx_screensize.x && p1.y >= 0 && p1.y < gfx_screensize.y) || (p2.x >= 0 && p2.x < gfx_screensize.x && p2.y >= 0 && p2.y < gfx_screensize.y)) { draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, linestyle); } } } } };