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.c

815 lines
24 KiB

/* draw.c
* Copyright (C) Steffen Pohle 2010 <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 "system.h"
#include "gui.h"
#include "vector.h"
#include "memoryleak.h"
/**************************************************************************
* color definitions, hopfully this can go out soon, need to find a way to
* specify only the rgb values like it is in HTML and thats it.
* i.e. color = 0xFF0000; for red.
*/
struct line_style draw_linestyle[MWAY_MAX];
struct color color_polygon[MAREA_MAX];
struct color color_bg;
struct color color_fg;
struct color color[COLOR_MAX][COLOR_steps];
/**************************************************************************
* current screen data, center of the screen? where we look at the scale,
* and the drawing flags. All these values start with view_*
*/
float view_scale = 0.001;
float view_lon = 11.183;
float view_lat = 48.736;
int view_flags = DRAW_GPSFOLLOW;
/**************************************************************************
* internal variables set by some functions within the drawing stuff and
* from withing the *_gfx sources.. Some drawing functon will have vriables
* declared on top of the first function. (i.E. drawing lines, polygones.
*/
int draw_type[MAREA_MAX+MWAY_MAX];
/*
* selection variables
*/
struct map_pos select_pos;
int select_enabled = 0;
char statusline_text[255] = "";
int statusline_progress = 0;
void draw_line (struct image *img, int x1, int y1, int x2, int y2, struct line_style style);
void draw_lineway (struct image *img, int x1, int y1, int x2, int y2, struct line_style style);
void draw_rectangle (struct image *img, int x1, int y1, int x2, int y2, struct line_style style);
/*************************************************************************
* to prevent the flickering screen, we create two images inside the
* memory. One which keeps a larger area of the map (so we only draw
* the map once in a while) and a second map with the on screen data.
* img_map: keeps the current map screen values.
* img_screen: is the final data with the on screen data to copy on
* the screen.
*/
struct image *img_map = NULL; // image data of the current map
struct map_pos img_map_pos; // position of the current map
float img_map_scale; // scale of the current map
/**************************************************************************
*
* functions to convert between geo data and screen data
*
*/
iPoint draw_geo2screen (float center_lon, float center_lat, float lon, float lat) {
iPoint r;
r.x = - (map_lon2km (center_lon - lon, lat) / view_scale);
r.y = (map_lat2km (center_lat - lat) / view_scale);
return r;
};
void draw_screen2geo (int x, int y, float *lon, float *lat) {
y = y - gfx_screensize.y/2;
x = x - gfx_screensize.x/2;
*lat = -map_km2lat(((float)y) * view_scale);
*lon = map_km2lon(((float)x) * view_scale, view_lat + *lat);
*lat = view_lat + *lat;
*lon = view_lon + *lon;
};
/******************************************************************************
* set the new scale, and check what will have to be shown
*/
void draw_setscale (int newscale) {
float scale = view_scale;
if (newscale < 0) {
scale = scale / 1.5;
}
else {
scale = scale * 1.5;
}
d_printf ("scale: %f -> %f (i:%d)", view_scale, scale, newscale);
draw_setscalef (scale);
};
void draw_setscalef (float newscale) {
int i;
view_scale = newscale;
if (view_scale < 0.001) view_scale = 0.001;
else if (view_scale > 0.5) view_scale = 0.5;
/* change display settings */
if (view_scale < 0.01) {
for (i = 0; i < MWAY_MAX+MAREA_MAX; i++)
draw_type [i] = TRUE;
}
else if (view_scale < 0.1) {
for (i = 0; i < MWAY_MAX+MAREA_MAX; i++) {
switch (i) {
case (MWAY_tertiary):
case (MWAY_highway):
case (MWAY_MAX + MAREA_greenfield):
case (MWAY_MAX + MAREA_water):
case (MWAY_MAX + MAREA_industrial):
case (MWAY_MAX + MAREA_residential):
draw_type [i] = TRUE;
break;
default:
draw_type [i] = FALSE;
}
}
}
else {
for (i = 0; i < MWAY_MAX+MAREA_MAX; i++) {
switch (i) {
case (MWAY_highway):
case (MWAY_MAX + MAREA_greenfield):
case (MWAY_MAX + MAREA_wood):
case (MWAY_MAX + MAREA_water):
case (MWAY_MAX + MAREA_residential):
draw_type [i] = TRUE;
break;
default:
draw_type [i] = FALSE;
}
}
}
main_wnd_update();
};
void draw_set_flag (int flag) {
view_flags |= flag;
};
void draw_del_flag (int flag) {
view_flags &= (0xFFFF - flag);
};
/**************************************************************************+
* drawing initial functions
*/
void draw_init () {
int n;
d_printf ("draw_init");
draw_init_color ();
for (n = 0; n < MAREA_MAX; n++) draw_type[n] = 1;
view_lon = cfg.last_lon;
view_lat = cfg.last_lat;
view_scale = cfg.last_scale;
};
void draw_init_color () {
int n, i, r,g,b;
d_printf ("draw_init_color");
for (n = 0; n < COLOR_MAX; n++) for (i = COLOR_steps-1; i >= 0; i--) {
if (i == COLOR_steps-1) {
if (n == COLOR_white) gfx_color_alloc (&color[n][i], 0xFFFF, 0xFFFF, 0xFFFF);
else if (n == COLOR_red) gfx_color_alloc (&color[n][i], 0xFFFF, 0x0, 0x0);
else if (n == COLOR_redgray) gfx_color_alloc (&color[n][i], 0xFFFF, 0xA000, 0xA000);
else if (n == COLOR_blue) gfx_color_alloc (&color[n][i], 0x0, 0x0, 0xFFFF);
else if (n == COLOR_bluegray) gfx_color_alloc (&color[n][i], 0xA000, 0xA000, 0xFFFF);
else if (n == COLOR_green) gfx_color_alloc (&color[n][i], 0x0, 0xFFFF, 0x0);
else if (n == COLOR_greengray) gfx_color_alloc (&color[n][i], 0xA000, 0xFFFF, 0xA000);
else if (n == COLOR_brown) gfx_color_alloc (&color[n][i], 0xFFFF, 0x8000, 0x0);
else if (n == COLOR_pink) gfx_color_alloc (&color[n][i], 0xFFFF, 0x0, 0xFFFF);
else if (n == COLOR_yellow) gfx_color_alloc (&color[n][i], 0xFFFF, 0xFFFF, 0x0000);
else {
d_printf ("%s:%d not all colors have been defined..", __FILE__, __LINE__);
exit (1);
}
}
else {
r = color[n][COLOR_steps-1].r;
g = color[n][COLOR_steps-1].g;
b = color[n][COLOR_steps-1].b;
if (n == COLOR_white) {
if (i == 0) {
r = g = b = 0;
}
else {
r = r*(i)/COLOR_steps-1;
g = g*(i)/COLOR_steps-1;
b = b*(i)/COLOR_steps-1;
}
}
else {
r = r*(i+1)/COLOR_steps;
g = g*(i+1)/COLOR_steps;
b = b*(i+1)/COLOR_steps;
}
gfx_color_alloc (&color[n][i], r, g, b);
}
gfx_color_alloc (&color_bg, 0,0,0); // background
gfx_color_alloc (&color_fg, 0x8000,0x8000,0x8000); // foreground
}
for (n = 0; n < MWAY_MAX; n++) {
draw_linestyle[n].width = 0.0;
gfx_color_alloc (&draw_linestyle[n].borderc, 0x8000, 0x8000,0x8000);
switch (n) {
case (MWAY_highway):
draw_linestyle[n].width = 4.0;
gfx_color_alloc (&draw_linestyle[n].c, 0xFFFF,0xFFFF,0x8000);
break;
case (MWAY_tertiary):
draw_linestyle[n].width = 3.0;
gfx_color_alloc (&draw_linestyle[n].c, 0xA000,0xA000,0x0000);
break;
case (MWAY_residential):
draw_linestyle[n].width = 2.0;
gfx_color_alloc (&draw_linestyle[n].c, 0xA000,0xA000,0xA000);
break;
case (MWAY_cycleway):
gfx_color_alloc (&draw_linestyle[n].c, 0x4000,0xA000,0x4000);
break;
case (MWAY_footway):
gfx_color_alloc (&draw_linestyle[n].c, 0x4000,0x4000,0xA000);
break;
case (MWAY_railway):
gfx_color_alloc (&draw_linestyle[n].c, 0x8000,0x8000,0x8000);
break;
case (MWAY_unknown_railway):
gfx_color_alloc (&draw_linestyle[n].c, 0x6000,0x6000,0x6000);
break;
case (MWAY_service):
gfx_color_alloc (&draw_linestyle[n].c, 0x6000,0x6000,0x6000);
break;
case (MWAY_unknown):
case (MWAY_unknown_way):
default:
gfx_color_alloc (&draw_linestyle[n].c, 0x7000,0x5000,0x5000);
break;
}
}
for (n = 0; n < MAREA_MAX; n++) switch (n) {
case (MAREA_water):
gfx_color_alloc (&color_polygon[n], 0x4000,0x4000,0xFFFF);
break;
case (MAREA_greenfield):
gfx_color_alloc (&color_polygon[n], 0x2000,0x8000,0x2000);
break;
case (MAREA_wood):
gfx_color_alloc (&color_polygon[n], 0x0000,0x6000,0x0000);
break;
case (MAREA_land):
gfx_color_alloc (&color_polygon[n], 0x6000,0x6000,0x0000);
break;
case (MAREA_residential):
gfx_color_alloc (&color_polygon[n], 0x2000,0x2000,0x2000);
break;
case (MAREA_farm):
gfx_color_alloc (&color_polygon[n], 0x8000,0x4000,0x2000);
break;
case (MAREA_industrial):
gfx_color_alloc (&color_polygon[n], 0x8000,0x6000,0x8000);
break;
case (MAREA_commercial):
gfx_color_alloc (&color_polygon[n], 0x8000,0x0000,0x8000);
break;
case (MAREA_military):
gfx_color_alloc (&color_polygon[n], 0x2000,0x2000,0x2000);
break;
case (MAREA_building):
gfx_color_alloc (&color_polygon[n], 0x6000,0x6000,0x6000);
break;
default:
gfx_color_alloc (&color_polygon[n],0xFFFF,0x0000,0x0000);
break;
}
};
/**************************************************************************+
* drawing subfunctions
*/
/*
* rectangle
*/
void draw_rectangle (struct image *dimg, int x1, int y1, int x2, int y2, struct line_style style) {
gfx_draw_line (dimg, x1, y1, x2, y1, style);
gfx_draw_line (dimg, x2, y1, x2, y2, style);
gfx_draw_line (dimg, x2, y2, x1, y2, style);
gfx_draw_line (dimg, x1, y2, x1, y1, style);
};
/*
* lines
*/
void draw_line (struct image *dimg, int x1, int y1, int x2, int y2, struct line_style style) {
int width, height;
if (dimg == NULL) {
width = gfx_screensize.x;
height = gfx_screensize.y;
}
else {
width = dimg->width;
height = dimg->height;
}
if ((x1 >= 0 && x1 <= width && y1 >= 0 && y1 <= height) ||
(x2 >= 0 && x2 <= width && y2 >= 0 && y2 <= height) ||
(x1 <= 0 && x2 >= width) || (x2 <= 0 && x1 >= width) ||
(y1 <= 0 && y2 >= height) || (y2 <= 0 && y1 >= height))
gfx_draw_line (dimg, x1, y1, x2, y2, style);
};
/*
* draw a polygon..
*/
static iPoint _polypoints[POLYGON_MAX_POINTS];
static int _polycnt;
void draw_polygonstart () {
_polycnt = 0;
};
void draw_polygonadd (int x, int y) {
if (_polycnt >= POLYGON_MAX_POINTS) {
printf ("%s:%d draw_polygonadd: too many points.\n", __FILE__, __LINE__);
return;
}
_polypoints[_polycnt].x = x;
_polypoints[_polycnt].y = y;
_polycnt++;
};
void draw_polygonfinish (struct image *dimg, struct line_style ls, struct color c, int border) {
int i;
gfx_draw_polygon (dimg, _polypoints, _polycnt, ls, c);
if (border) {
for (i = 1; i < _polycnt; i++) {
gfx_draw_line (dimg, _polypoints[i-1].x, _polypoints[i-1].y, _polypoints[i].x, _polypoints[i].y, ls);
}
gfx_draw_line (dimg, _polypoints[_polycnt-1].x, _polypoints[_polycnt-1].y, _polypoints[0].x, _polypoints[0].y, ls);
}
_polycnt = 0;
};
void draw_lineway (struct image *dimg, int x1, int y1, int x2, int y2, struct line_style style) {
struct line_style tmplinestyle = style;
if (view_scale < 0.01)
tmplinestyle.width = tmplinestyle.width * (0.005/view_scale);
draw_line (dimg, x1, y1, x2, y2, tmplinestyle);
};
/************************************************************************
* the drawing stuff itself.
* before drawing everything on the screen, check if we need to redraw
* the map or just copy a part of it into the gui image.
* After copying the map into the gui screen draw the gui, afterwards
* copy the gui screen onto the display.
*/
void draw_map () {
struct map_hash *mh;
struct map_way *cway;
struct map_area *carea;
struct map_place *cplace;
struct map_poi *cpoi;
int w, n, i;
struct map_hashpos h, hs, he;
iPoint p1, p2;
fPoint nd, v1, v2, v3;
struct line_style tmplinestyle;
iPoint center;
struct map_pos hashstart, hashend;
struct color *c;
char text[255];
d_printf ("view_lon: %f view_lat:%f", view_lon, view_lat);
gfx_clear (img_map, &color_bg);
center.x = img_map->width / 2;
center.y = img_map->height / 2;
tmplinestyle.width = 1.0;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][2];
hashstart.lat = view_lat - map_km2lat(view_scale * ((float)img_map->width));
hashstart.lon = view_lon - map_km2lon(view_scale * ((float)img_map->height), hashstart.lat);
hashend.lat = view_lat + map_km2lat(view_scale * ((float)img_map->height));
hashend.lon = view_lon + map_km2lon(view_scale * ((float)img_map->width), hashend.lat);
hs.ilon = map_geo2igeo (hashstart.lon);
hs.ilat = map_geo2igeo (hashstart.lat);
he.ilon = map_geo2igeo (hashend.lon);
he.ilat = map_geo2igeo (hashend.lat);
/*
* draw areas
*/
for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++)
for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) {
if (app.status == APPSTATUS_nothing) mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_RELOAD);
else mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_NONE);
if (mh) {
carea = mh->areas;
while (carea) {
if (draw_type[carea->type + MWAY_MAX]) {
draw_polygonstart ();
for (n = 0; n < carea->p_cnt; n++)
if (n == 0 || n == carea->p_cnt-1 || view_scale < 0.01
|| ((view_scale < 0.1 && (n % 2) == 0) || carea->p_cnt < 5)
|| ((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);
draw_polygonadd (p1.x + center.x, p1.y + center.y);
}
draw_polygonfinish (img_map, tmplinestyle, color_polygon[carea->type], 0);
}
carea = carea->next;
}
}
}
/*
* draw ways
*/
/* draw outside */
for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++)
for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) {
/*
* draw the hash..
*/
if (app.status == APPSTATUS_nothing) mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_RELOAD);
else mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_NONE);
if (mh) {
/*
* ways
*/
cway = mh->ways;
while (cway) {
if (cway->id != 0 && draw_type[cway->type]) {
/* go through all the nodes */
tmplinestyle.width = draw_linestyle[cway->type].width * (0.005/view_scale) + 2;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][1];
if (view_scale < 0.01) {
for (n = 0; n < cway->p_cnt; n++) {
p2 = p1;
nd.x = map_lon2km (view_lon - cway->p[n].lon, cway->p[n].lat);
nd.y = map_lat2km (view_lat - cway->p[n].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n > 0)
draw_line (img_map, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
}
else {
for (n = -1; n < cway->n_cnt;) {
/* find next node */
if (n == -1) {
i = 0;
n++;
}
else {
for (n = 0, w = cway->p_cnt; n < cway->n_cnt; n++) {
if (cway->n[n].pnr > i && cway->n[n].pnr < w) w = cway->n[n].pnr;
}
if (w == cway->p_cnt) i = cway->p_cnt - 1;
else {
i = w;
n = 1;
}
}
p2 = p1;
nd.x = map_lon2km (view_lon - cway->p[i].lon, cway->p[i].lat);
nd.y = map_lat2km (view_lat - cway->p[i].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n > 0)
draw_line (img_map, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
}
/* draw the waynodes */
for (n = 0; n < cway->n_cnt; n++) if (cway->n[n].pnr < cway->p_cnt) {
p1 = draw_geo2screen (view_lon, view_lat, cway->n[n].d.lon, cway->n[n].d.lat);
p2 = draw_geo2screen (view_lon, view_lat, cway->p[cway->n[n].pnr].lon, cway->p[cway->n[n].pnr].lat);
p1.x += center.x;
p1.y += center.y;
p2.x += center.x;
p2.y += center.y;
draw_line (img_map, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
}
cway = cway->next;
}
}
}
/* ways inside */
for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++)
for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) {
/*
* draw the hash..
*/
if (app.status == APPSTATUS_nothing) mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_RELOAD);
else mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_NONE);
if (mh) {
/*
* ways
*/
cway = mh->ways;
while (cway) {
if (cway->id != 0 && draw_type[cway->type] && (cway->flags & MWAY_F_planed) == 0) {
/* go through all the nodes */
if (view_scale < 0.01) {
for (n = 0; n < cway->p_cnt; n++) {
p2 = p1;
nd.x = map_lon2km (view_lon - cway->p[n].lon, cway->p[n].lat);
nd.y = map_lat2km (view_lat - cway->p[n].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n > 0) {
if (cway->type >= MWAY_MAX)
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[MWAY_unknown]);
else
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[cway->type]);
/* one way arrow */
if (cway->flags & MWAY_F_oneway && view_scale < 0.004) {
tmplinestyle.width = 1;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][0];
nd.x = (p1.x+p2.x)/2;
nd.y = (p1.y+p2.y)/2;
v1.x = p1.x-p2.x;
v1.y = p1.y-p2.y;
v1 = vec_one (v1);
v2 = vec_turn90 (v1);
v3 = vec_mirror (v2);
v1 = vec_mul (v1, 3.0);
v2 = vec_mul (v2, 3.0);
v3 = vec_mul (v3, 3.0);
v1 = vec_add (v1, nd);
v2 = vec_add (v2, nd);
v3 = vec_add (v3, nd);
draw_line (img_map, v1.x, v1.y, v2.x, v2.y, tmplinestyle);
draw_line (img_map, v1.x, v1.y, v3.x, v3.y, tmplinestyle);
}
}
}
}
else {
for (n = -1; n < cway->n_cnt;) {
// d_printf ("LINE: %lld n_cnt:%d p_cnt:%d", cway->id, cway->n_cnt, cway->p_cnt);
/* find next node */
if (n == -1) {
i = 0;
n++;
}
else {
for (n = 0, w = cway->p_cnt; n < cway->n_cnt; n++) {
if (cway->n[n].pnr > i && cway->n[n].pnr < w) w = cway->n[n].pnr;
}
if (w == cway->p_cnt) i = cway->p_cnt - 1;
else {
i = w;
n = 1;
}
}
// d_printf (" i:%d n:%d", i, n);
p2 = p1;
nd.x = map_lon2km (view_lon - cway->p[i].lon, cway->p[i].lat);
nd.y = map_lat2km (view_lat - cway->p[i].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n > 0) {
if (cway->type >= MWAY_MAX)
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[MWAY_unknown]);
else
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[cway->type]);
}
}
}
/* draw the waynodes */
for (n = 0; n < cway->n_cnt; n++) if (cway->n[n].pnr < cway->p_cnt) {
p1 = draw_geo2screen (view_lon, view_lat, cway->n[n].d.lon, cway->n[n].d.lat);
p2 = draw_geo2screen (view_lon, view_lat, cway->p[cway->n[n].pnr].lon, cway->p[cway->n[n].pnr].lat);
p1.x += center.x;
p1.y += center.y;
p2.x += center.x;
p2.y += center.y;
if (cway->type >= MWAY_MAX)
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[MWAY_unknown]);
else
draw_lineway (img_map, p1.x, p1.y, p2.x, p2.y, draw_linestyle[cway->type]);
}
else d_printf ("%s:%d wayid:%lld cway->n[n].pnr(%d) < cway->p_cnt(%d) doesn't match", __FILE__, __LINE__, cway->id, cway->n[n].pnr, cway->p_cnt);
}
cway = cway->next;
}
}
}
/*
* draw places, pois just on top layers
*/
for (h.ilon = hs.ilon; h.ilon <= he.ilon; h.ilon++)
for (h.ilat = hs.ilat; h.ilat <= he.ilat; h.ilat++) {
if (app.status == APPSTATUS_nothing) mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_RELOAD);
else mh = map_hash_geti (h.ilon, h.ilat, MHLOAD_NONE);
if (mh) {
/*
* places
*/
cplace = mh->places;
i = 0;
while (cplace) {
if (view_scale < 0.01
|| cplace->type == MAP_PLACE_city
|| cplace->type == MAP_PLACE_town
|| (cplace->type == MAP_PLACE_village && view_scale < 0.05)) {
i++;
p1 = draw_geo2screen(view_lon, view_lat, cplace->lon, cplace->lat);
p1.x += center.x;
p1.y += center.y;
switch (cplace->type) {
case (MAP_PLACE_city):
case (MAP_PLACE_town):
case (MAP_PLACE_village):
gfx_draw_text (img_map, p1.x,p1.y, cplace->name, &color[COLOR_white][3]);
break;
case (MAP_PLACE_hamlet):
case (MAP_PLACE_suburb):
gfx_draw_text (img_map, p1.x,p1.y, cplace->name, &color[COLOR_bluegray][2]);
break;
default:
gfx_draw_text (img_map, p1.x,p1.y, cplace->name, &color[COLOR_bluegray][2]);
break;
}
}
cplace = cplace->next;
}
/*
* poi
*/
cpoi = mh->pois;
i = 0;
if (view_scale < 0.01) while (cpoi) {
p1 = draw_geo2screen(view_lon, view_lat, cpoi->lon, cpoi->lat);
p1.x += center.x;
p1.y += center.y;
if (cpoi->type != MAP_POI_unknown &&
((view_scale < 0.01 && cpoi->type == MAP_POI_gasstation)
|| (view_scale < 0.0015))) {
switch (cpoi->type) {
case (MAP_POI_campsite):
sprintf (text, "C");
c = &color[COLOR_greengray][3];
break;
default:
sprintf (text, "?");
c = &color[COLOR_red][3];
}
gfx_draw_text (img_map, p1.x-4, p1.y-4, text, c);
gfx_draw_text (img_map, p1.x-strlen(cpoi->name)*2, p1.y+8, cpoi->name, c);
}
cpoi = cpoi->next;
}
}
}
// tmplinestyle.width = 4.0;
// tmplinestyle.c = tmplinestyle.borderc = color_red1;
// draw_line (img_map, center.x-100, center.y, center.x+100, center.y, tmplinestyle);
// draw_line (img_map, center.x, center.y-100, center.x, center.y+100, tmplinestyle);
// draw_lines (img_map);
// sprintf (text, "%f,%f", view_lon, view_lat);
// gfx_img_draw_text (img_map, center.x,center.y, text, &color_blue1);
/*
* save data of the map drawed
*/
img_map_pos.lon = view_lon;
img_map_pos.lat = view_lat;
img_map_scale = view_scale;
};
int draw_mapcopy () {
iPoint p1, p2;
p2 = draw_geo2screen (img_map_pos.lon, img_map_pos.lat, view_lon, view_lat);
p1.x = img_map->width/2 + p2.x - gfx_screensize.x/2;
p1.y = img_map->height/2 + p2.y - gfx_screensize.y/2;
if (p1.x < 0 || p1.y < 0
|| p1.x > (img_map->width - gfx_screensize.x)
|| p1.y > (img_map->height - gfx_screensize.y)) return 0;
gfx_draw_img (NULL, 0, 0, gfx_screensize.x, gfx_screensize.y, img_map, p1.x, p1.y);
return 1;
};
void draw () {
static int still_drawing = 0;
/* only run once at the time.. */
if (still_drawing) return;
still_drawing = 1;
while (view_lon > 180.0) view_lon -= 360.0;
while (view_lon < -180.0) view_lon += 360.0;
while (view_lat > 180.0) view_lat -= 360.0;
while (view_lat < -180.0) view_lat += 360.0;
/* do we need to alloc the screens */
if (img_map != NULL && (img_map->width != gfx_screensize.x * 2 || img_map->height != gfx_screensize.y * 2)) {
gfx_img_free (img_map);
img_map = NULL;
}
if (img_map == NULL) {
// img_map = gfx_img_alloc (400 * 2, 400 * 2);
img_map = gfx_img_alloc (gfx_screensize.x * 2, gfx_screensize.y * 2);
img_map_scale = -1.0;
}
/* draw the map, if needed */
if (img_map_scale < 0.0 || img_map_scale != view_scale) {
draw_map ();
}
gfx_clear (NULL, &color[COLOR_white][0]);
if (draw_mapcopy () == 0) {
draw_map ();
draw_mapcopy ();
}
draw_gui ();
gfx_flip ();
still_drawing = 0;
};
void draw_redrawmap () {
img_map_scale = -1;
draw ();
};