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.
spOSMroute/draw/draw_gps.c

220 lines
7.3 KiB

/*
* draw_gps.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 "gps.h"
/*
* drawgps_ variables needed for drawing gps stuff..
*/
struct gps_data drawgps_data;
unsigned long long int drawgps_on_way_id = 0;
unsigned short int drawgps_on_way_sid = 0;
char drawgps_on_way_name[MAP_W_NAMELEN] = "\0";
void drawgps_set_pos (struct gps_data *gpsdata) {
static char _gpspos_to = 0;
struct map_pos p, p1;
fPoint fp;
float f1;
memcpy (drawgps_data.sat, gpsdata->sat, 32*sizeof (struct gps_satelite));
drawgps_data.hdop = gpsdata->hdop;
drawgps_data.numofsatelites = gpsdata->numofsatelites;
drawgps_data.quality = gpsdata->quality;
if (gpsdata->valid) {
draw_set_flag (DRAW_GPS);
drawgps_data.lon = gpsdata->lon;
drawgps_data.lat = gpsdata->lat;
if (view_flags & DRAW_GPSFOLLOW && mousebtn == 0) {
iPoint ip = draw_geo2screen (view_lon, view_lat, drawgps_data.lon, drawgps_data.lat);
if (ip.x < (gfx_screensize.x / 4) || ip.x > (gfx_screensize.x - (gfx_screensize.x/4)) ||
(ip.y < (gfx_screensize.y / 4) || ip.y > (gfx_screensize.y - (gfx_screensize.y/4)))) {
view_lon = drawgps_data.lon;
view_lat = drawgps_data.lat;
/* recalc position */
if (gpsdata->speed > 20.0) {
/* speed factor */
f1 = (gpsdata->speed-20.0)/70.0;
if (f1 > 1.0) f1 = 1.0;
/* screen factor */
fp.x = sin (M_PI*gpsdata->direction/180.0) * f1 * gfx_screensize.x * 0.3 + gfx_screensize.x/2.0;
fp.y = -cos (M_PI*gpsdata->direction/180.0) * f1 * gfx_screensize.y * 0.3 + gfx_screensize.y/2.0;
draw_screen2geo (fp.x, fp.y, &p.lon, &p.lat);
view_lon = p.lon;
view_lat = p.lat;
}
}
}
if (gpsdata->valid) {
drawgps_data.time = gpsdata->time;
drawgps_data.speed = gpsdata->speed;
drawgps_data.valid = gpsdata->valid;
drawgps_data.direction = gpsdata->direction;
drawgps_data.height = gpsdata->height;
/* find closest way */
p.lon = drawgps_data.lon;
p.lat = drawgps_data.lat;
/* routing? */
map_way_findclosest (&p, &p1, 0, drawgps_on_way_name, MAP_W_NAMELEN, &drawgps_on_way_id, &drawgps_on_way_sid);
}
}
if (gpsdata->quality != 0 || ((view_flags & DRAW_DEBUG) && ((_gpspos_to--) < 0))) {
draw ();
_gpspos_to = 100;
}
};
/*****************************************************************************
* draw gps position and information
*/
void draw_gui_gps () {
struct line_style tmplinestyle;
iPoint p1, p2, center = {gfx_screensize.x/2, gfx_screensize.y/2};
int i;
char text[64];
struct gps_data *gpsdata;
/*
* gpsroute
*/
if (gps_isrunning() == 0 && gpsroute) {
if (gpsroute->cnt > 1) {
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][3];
p1 = draw_geo2screen (view_lon, view_lat, gpsroute->data[0].lon, gpsroute->data[0].lat);
p1.x += center.x;
p1.y += center.y;
for (i = 1; i < gpsroute->cnt; i++) {
p2 = draw_geo2screen (view_lon, view_lat, gpsroute->data[i].lon, gpsroute->data[i].lat);
p2.x += center.x;
p2.y += center.y;
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_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
p1 = p2;
}
}
if (gpsroute->pcnt > 0) {
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][1];
for (i = 0; i < gpsroute->pcnt; i++) {
p1 = draw_geo2screen (view_lon, view_lat, gpsroute->pdata[i].lon, gpsroute->pdata[i].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);
gfx_draw_text (NULL, p1.x-10, p1.y+5, gpsroute->pdata[i].name, &color[COLOR_redgray][3]);
}
}
}
/*
* basic gps information
*/
if (view_flags & DRAW_GPS) {
iPoint p3, p;
p = draw_geo2screen (view_lon, view_lat, drawgps_data.lon, drawgps_data.lat);
p.x += center.x;
p.y += center.y;
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_bluegray][3];
for (i = 1; i < 10; i++) {
p1.x = sin (M_PI*drawgps_data.direction/180.0) * 12 + p.x;
p1.y = -cos (M_PI*drawgps_data.direction/180.0) * 12 + p.y;
p2.x = sin (M_PI*(drawgps_data.direction-120.0)/180.0) * i + p.x;
p2.y = -cos (M_PI*(drawgps_data.direction-120.0)/180.0) * i + p.y;
p3.x = sin (M_PI*(drawgps_data.direction+120.0)/180.0) * i + p.x;
p3.y = -cos (M_PI*(drawgps_data.direction+120.0)/180.0) * i + p.y;
draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
draw_line (NULL, p1.x, p1.y, p3.x, p3.y, tmplinestyle);
draw_line (NULL, p3.x, p3.y, p2.x, p2.y, tmplinestyle);
}
i = 6;
p1.x = sin (M_PI*drawgps_data.direction/180.0) * 8 + p.x;
p1.y = -cos (M_PI*drawgps_data.direction/180.0) * 8 + p.y;
p2.x = sin (M_PI*(drawgps_data.direction-120.0)/180.0) * 5 + p.x;
p2.y = -cos (M_PI*(drawgps_data.direction-120.0)/180.0) * 5 + p.y;
p3.x = sin (M_PI*(drawgps_data.direction+120.0)/180.0) * 5 + p.x;
p3.y = -cos (M_PI*(drawgps_data.direction+120.0)/180.0) * 5 + p.y;
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3];
draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
draw_line (NULL, p1.x, p1.y, p3.x, p3.y, tmplinestyle);
draw_line (NULL, p2.x, p2.y, p3.x, p3.y, tmplinestyle);
}
if (view_flags & DRAW_DEBUG) if (gps_isrunning()) {
gpsdata = gps_getposition ();
/* draw sat satus */
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][2];
p1.x = 5;
p1.y = 60;
p2.x = 5 + 99;
p2.y = 60 + 32 * 3;
for (i = 0; i < 2; i++)
draw_line (NULL, p1.x+i*25, p1.y, p1.x+i*25, p2.y, tmplinestyle);
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3];
for (i = 0; i < 32; i++) {
p1.x = 5;
p1.y = 60 + i * 3;
p2.x = 5 + gpsdata->sat[i].quality;
p2.y = 60 + i * 3;
draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
sprintf (text, "Lon:%7.3f Lat:%7.3f Height:%4.0f", gpsdata->lon, gpsdata->lat, gpsdata->height);
gfx_draw_text (NULL, 0, 150, text, &color[COLOR_green][3]);
sprintf (text, "Sats:%d Quality:%d HDOP:%5.2f", gpsdata->numofsatelites, gpsdata->quality, gpsdata->hdop);
gfx_draw_text (NULL, 0, 162, text, &color[COLOR_green][3]);
sprintf (text, "GPS Signal");
gfx_draw_text (NULL, 0, 40, text, &color[COLOR_white][3]);
}
if (view_flags & DRAW_GPS) {
sprintf (text, "%3.0f km/h :%s", drawgps_data.speed, drawgps_on_way_name);
gfx_draw_text (NULL, 0, gfx_screensize.y-16, text, &color[COLOR_green][2]);
}
};