You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
11 KiB
326 lines
11 KiB
/*
|
|
* draw_route.c
|
|
* Copyright (C) Steffen Pohle 2011 <steffen@gulpe.de>
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <sys/time.h>
|
|
#include <math.h>
|
|
|
|
#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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
};
|