mappix/mappix-trackdraw.c

745 lines
22 KiB
C
Raw Permalink Normal View History

/*
* trackdraw
*
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
*
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <string.h>
#include <math.h>
#include <cairo.h>
#include <sqlite3.h>
#include "mappix.h"
#include "geo-tools.h"
#include "geo-dist.h"
void
draw_waypoint_label (mapwin *Mapper, gint x, gint y, gchar *text_label)
{
PangoLayout *playout;
GdkColor fgc, bgc;
playout = gtk_widget_create_pango_layout (Mapper->drawarea, text_label);
gdk_color_parse("black", &fgc);
gdk_color_parse("yellow", &bgc);
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, x+10, y-20, playout, &fgc, &bgc);
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x+10, y-10, x, y);
gtk_widget_queue_draw(Mapper->drawarea);
}
static void
draw_city_name(mapwin *Mapper, gchar *city_name, guint x, guint y)
{
PangoLayout *playout;
GdkColor fgc;
// fprintf(stderr, "city %s\n", city_name);
playout = gtk_widget_create_pango_layout (Mapper->drawarea, city_name);
gdk_color_parse("black", &fgc);
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, x, y, playout, &fgc, NULL);
gtk_widget_queue_draw(Mapper->drawarea);
}
static int
city_db_callback(void *user_data, int argc, char **argv, char **azColName)
{
mapwin *Mapper = (mapwin *)user_data;
double lat, lon;
guint unitx, unity;
// str argv[0]
lat = g_ascii_strtod(argv[1] , NULL);
lon = g_ascii_strtod(argv[2] , NULL);
latlon2unit(lat, lon, unitx, unity);
unitx = (unitx - Mapper->xoffset) * Mapper->scale;
unity = (unity - Mapper->yoffset) * Mapper->scale;
draw_city_name(Mapper, argv[0], unitx, unity);
return 0;
}
void
draw_city_names(mapwin *Mapper)
{
sqlite3 *db;
/* re-scan for cities */
if (Mapper->show_cities && !sqlite3_open("cities.db", &db)) {
char *zErrMsg = 0;
gchar sql[256];
double lat_min, lon_min;
double lat_max, lon_max;
gchar lamax[32], lamin[32], lomax[32], lomin[32];
unit2latlon(Mapper->xmin, Mapper->ymin, lat_min, lon_min);
unit2latlon(Mapper->xmax, Mapper->ymax, lat_max, lon_max);
g_ascii_dtostr(lamax, 32, lat_max);
g_ascii_dtostr(lamin, 32, lat_min);
g_ascii_dtostr(lomax, 32, lon_max);
g_ascii_dtostr(lomin, 32, lon_min);
g_sprintf(sql, "SELECT city, lat, long FROM staedte WHERE lat > %s AND lat < %s AND long > %s AND long < %s;",
lamax, lamin, lomin, lomax);
sqlite3_exec(db, sql, city_db_callback, Mapper, &zErrMsg);
// fprintf(stderr, "sql: '%s'\n", sql);
sqlite3_close(db);
}
}
void
draw_scale(mapwin *Mapper)
{
PangoLayout *playout;
GdkColor fgc;
guint x1,x2,y;
double lat1, lat2, lon1, lon2, dist;
gchar scale_text[64];
// assuming we have 50px in the lower right corner
// fprintf(stderr, "city %s\n", city_name);
x1 = Mapper->xoffset;
x2 = Mapper->xoffset + (100. / Mapper->scale);
y = Mapper->yoffset;
unit2latlon(x1, y, lat1, lon1);
unit2latlon(x2, y, lat2, lon2);
//fprintf(stderr, "x=%d x2=%d y=%d lat1=%lf lat2=%lf lon1=%lf lon2=%lf\n", x1,x2,y,lat1,lat2,lon1,lon2);
dist = dist_ell(lat1, lon1, lat2, lon2, WGS84) * NAUTICAL_MILE;
if (dist > 1.0)
g_snprintf(scale_text, 64, "%.02lfkm", dist);
else {
g_snprintf(scale_text, 64, "%.00lfm", dist*100.);
}
playout = gtk_widget_create_pango_layout (Mapper->drawarea, scale_text);
gdk_color_parse("black", &fgc);
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x - 80, Mapper->canvas_y - 20, playout, &fgc, NULL);
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-110, Mapper->canvas_y - 20, Mapper->canvas_x-10, Mapper->canvas_y - 20);
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-110, Mapper->canvas_y - 25, Mapper->canvas_x-110, Mapper->canvas_y - 15);
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-10, Mapper->canvas_y - 25, Mapper->canvas_x-10, Mapper->canvas_y - 15);
for (x1 = (Mapper->canvas_x-100); x1 < (Mapper->canvas_x-10); x1+=10)
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x1, Mapper->canvas_y - 25, x1, Mapper->canvas_y - 20);
gtk_widget_queue_draw(Mapper->drawarea);
}
void
do_redraw(mapwin *Mapper)
{
draw_tracks(Mapper);
if (Mapper->show_cities)
draw_city_names(Mapper);
if (Mapper->show_waypoints)
draw_waypoints(Mapper);
if (Mapper->show_scale)
draw_scale(Mapper);
gtk_widget_queue_draw(Mapper->drawarea);
}
void
change_scale(mapwin *Mapper, double new_scale)
{
Mapper->scale = new_scale;
do_redraw(Mapper);
}
void
zoom_in_cb (GtkSpinButton *widget, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
gdouble scale_inc;
guint x,y;
scale_inc = Mapper->scale / 10.;
x = (Mapper->canvas_x / 2) / Mapper->scale;
y = (Mapper->canvas_y / 2) / Mapper->scale;
Mapper->scale += scale_inc;
Mapper->xoffset += x - ((Mapper->canvas_x / 2) / Mapper->scale);
Mapper->yoffset += y - ((Mapper->canvas_y / 2) / Mapper->scale);
Mapper->xmin = Mapper->xoffset;
Mapper->ymin = Mapper->yoffset;
Mapper->xmax = Mapper->xmin + (Mapper->canvas_x / Mapper->scale);
Mapper->ymax = Mapper->ymin + (Mapper->canvas_y / Mapper->scale);
change_scale(Mapper, Mapper->scale);
}
void
zoom_out_cb (GtkSpinButton *widget, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
gdouble scale_inc;
guint x,y;
scale_inc = Mapper->scale / 10.;
if (scale_inc < 0)
scale_inc = 0;
x = (Mapper->canvas_x / 2) / Mapper->scale;
y = (Mapper->canvas_y / 2) / Mapper->scale;
Mapper->scale -= scale_inc;
Mapper->xoffset += x - ((Mapper->canvas_x / 2) / Mapper->scale);
Mapper->yoffset += y - ((Mapper->canvas_y / 2) / Mapper->scale);
Mapper->xmin = Mapper->xoffset;
Mapper->ymin = Mapper->yoffset;
Mapper->xmax = Mapper->xmin + (Mapper->canvas_x / Mapper->scale);
Mapper->ymax = Mapper->ymin + (Mapper->canvas_y / Mapper->scale);
change_scale(Mapper, Mapper->scale);
}
void
zoom_area_cb (GtkRadioToolButton *widget, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
Mapper->toolmode = MAPPIX_TOOL_ZOOM_REGION;
}
void
move_cb (GtkRadioToolButton *widget, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
Mapper->toolmode = MAPPIX_TOOL_MOVE;
}
void
auto_scale (GtkButton *widget, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
change_scale(Mapper, calc_scale(Mapper));
}
void
draw_line(gint x1, gint y1, gint x2, gint y2, gint linewidth, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, linewidth, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_MITER);
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x1, y1, x2, y2);
}
void
draw_marker(gint x1, gint y1, gint psize, gint marker_type, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
GdkGC *marker_gc;
if (!Mapper->show_marker)
return;
if (marker_type & MARKER_SELECTED) {
marker_gc = Mapper->blue_gc;
marker_type &= ~MARKER_SELECTED;
} else
marker_gc = Mapper->red_gc;
if (marker_type != MARKER_TYPE_NONE) {
if (marker_type == MARKER_TYPE_FILLED_SQUARE) {
gdk_draw_rectangle(Mapper->mappix, marker_gc, TRUE, x1 - (psize/2), y1 - (psize/2), psize, psize);
} else if (marker_type == MARKER_TYPE_SQUARE) {
gdk_draw_rectangle(Mapper->mappix, marker_gc, FALSE, x1 - (psize/2), y1 - (psize/2), psize, psize);
} else if (marker_type == MARKER_TYPE_CROSS) {
psize = psize / 2;
gdk_gc_set_line_attributes(marker_gc, 0 /*linewidth*/, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
gdk_draw_line(Mapper->mappix, marker_gc, x1-psize, y1-psize, x1+psize, y1+psize);
gdk_draw_line(Mapper->mappix, marker_gc, x1+psize, y1-psize, x1-psize, y1+psize);
}
}
}
void
draw_markers(track_head *trackh, double bbxmin, double bbxmax, double bbymin, double bbymax, mapwin *Mapper, cairo_t *cr)
{
GList *track = trackh->track;
trackdata *tdata;
GList *lp;
gboolean start_newline = TRUE;
if (Mapper->show_marker && Mapper->scale > 0.0009) {
double ox, oy;
double angle;
ox = 0.; oy = 0.;
cairo_set_line_width(cr, 1.5 / Mapper->scale);
for (lp = track; lp; lp=g_list_next(lp)) {
tdata = (trackdata *)lp->data;
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
start_newline = TRUE;
} else {
if (start_newline) {
ox = (double)tdata->unitx;
oy = (double)tdata->unity;
} else {
angle = -1. * atan2((double)tdata->unitx - ox,
(double)tdata->unity - oy);
cairo_move_to(cr, (double)tdata->unitx, (double)tdata->unity);
/* draw marker arrow */
cairo_save (cr);
if (tdata->selected)
cairo_set_source_rgb (cr, .0,.0,.9);
else
cairo_set_source_rgb (cr, .0,.0,.0);
// cairo_set_line_width(cr, 1.5 / Mapper->scale);
cairo_rotate(cr, angle);
cairo_rel_move_to (cr, -5./ Mapper->scale, -5./ Mapper->scale);
cairo_rel_line_to (cr, 5./ Mapper->scale,5. / Mapper->scale);
cairo_rel_line_to (cr, 5./ Mapper->scale,-5. / Mapper->scale);
cairo_stroke (cr);
cairo_restore (cr);
ox = (double)tdata->unitx;
oy = (double)tdata->unity;
}
start_newline = FALSE;
}
}
}
}
void
draw_line_with_marker(gint x1, gint y1, gint x2, gint y2, gint psize, gint linewidth, gint marker_type, gpointer user_data)
{
draw_marker(x1, y1, psize, marker_type, user_data);
draw_marker(x2, y2, psize, marker_type, user_data);
draw_line(x1, y1, x2, y2, linewidth, user_data);
}
double
do_calc_scale(mapwin *Mapper)
{
double xscale, yscale;
double scale;
/* we calculate both scales and choose the smaller scale factor so that all data will fit */
xscale = Mapper->canvas_x / (gdouble)(Mapper->xmax - Mapper->xmin);
yscale = Mapper->canvas_y / (gdouble)(Mapper->ymax - Mapper->ymin);
if (xscale < yscale)
scale = xscale;
else
scale = yscale;
/* this should bring the tracks to the lower left corner */
Mapper->xoffset = Mapper->xmin;
Mapper->yoffset = Mapper->ymin;
// g_message("xmax=%d ymax=%d xmin=%d ymax=%d xscale=%f yscale=%f scale=%f", Mapper->xmax, Mapper->ymax, Mapper->xmin, Mapper->ymin, Mapper->xscale, Mapper->yscale, Mapper->scale);
return scale;
}
double
calc_scale(mapwin *Mapper)
{
trackdata *tdata;
track_head *thead;
GList *trackh, *trackp;
// fprintf(stderr,"cs\n");
Mapper->xmin=WORLD_SIZE_UNITS;
Mapper->xmax=0;
Mapper->ymin=WORLD_SIZE_UNITS;
Mapper->ymax=0;
for (trackh=Mapper->tracklist; trackh; trackh=g_list_next(trackh)) {
// fprintf(stderr," +cs\n");
thead = (track_head *)trackh->data;
if (thead->show) {
for (trackp=thead->track; trackp; trackp=g_list_next(trackp)) {
tdata = (trackdata *)trackp->data;
// fprintf(stderr,"latmin=%lf latmax=%lf longmin=%lf longmax=%lf\n", latmin, latmax, longmin, longmax);
if (tdata->unitx < Mapper->xmin)
Mapper->xmin = tdata->unitx;
else if (tdata->unitx > Mapper->xmax)
Mapper->xmax = tdata->unitx;
if (tdata->unity < Mapper->ymin)
Mapper->ymin = tdata->unity;
else if (tdata->unity > Mapper->ymax)
Mapper->ymax = tdata->unity;
}
}
}
return do_calc_scale(Mapper);
}
void
draw_waypoints(mapwin *Mapper)
{
GList *lp;
waypoint *wpdata;
if (!Mapper->show_waypoints)
return;
for (lp = Mapper->waypoints; lp; lp=g_list_next(lp)) {
double x,y;
wpdata = (waypoint *)lp->data;
x = (wpdata->unitx - Mapper->xoffset) * Mapper->scale;
y = (wpdata->unity - Mapper->yoffset) * Mapper->scale;
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", tdata->longitude, tdata->latitude, Mapper->scale);
if (x < 0 || y < 0)
continue;
if (x > Mapper->canvas_x)
continue;
if (y > Mapper->canvas_y)
continue;
draw_waypoint_label (Mapper, x, y, wpdata->name);
}
}
#if 0
static void
print_matrix(cairo_t *cr)
{
cairo_matrix_t cmatrix;
cairo_get_matrix(cr, &cmatrix);
fprintf(stderr, "xx=%lf xy=%lf x0=%lf\n", cmatrix.xx, cmatrix.xy, cmatrix.x0);
fprintf(stderr, "yx=%lf yy=%lf y0=%lf\n", cmatrix.yx, cmatrix.yy, cmatrix.y0);
}
#endif
void
draw_track(track_head *trackh, gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
GList *track = trackh->track;
trackdata *tdata;
gboolean start_newline = TRUE;
GList *lp;
cairo_t *cr;
cairo_matrix_t cmatrix;
double bbxmin, bbxmax;
double bbymin, bbymax;
// double TRACK_FACTOR = (1. / (2. * Mapper->scale)) + (100000. * Mapper->scale);
double TRACK_FACTOR = (4000. * (Mapper->scale * Mapper->scale)) * (1. / Mapper->scale);
if (TRACK_FACTOR < (0.8 / Mapper->scale))
TRACK_FACTOR = 0.8 / Mapper->scale;
if (track == NULL)
return;
cr = gdk_cairo_create (GDK_DRAWABLE(Mapper->mappix));
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
/* first set drawing for the outline of track or for non-outlined */
if (Mapper->show_marker) {
cairo_set_source_rgb (cr, 0,0,0);
cairo_set_line_width(cr, 1.0 / Mapper->scale);
} else {
switch (trackh->type) {
case UNKNOWN:
case OUTLINE: /* always visible in 1.0pt */
cairo_set_source_rgb (cr, 0,0,0);
cairo_set_line_width(cr, 1.0 / Mapper->scale);
break;
case FOOTPATH:
cairo_set_source_rgb (cr, 0,0,0);
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
break;
case RIVER:
cairo_set_source_rgb (cr, 0,0,.9);
cairo_set_line_width(cr, 1.3 * TRACK_FACTOR);
break;
case AGRI:
cairo_set_source_rgb (cr, 0.4,0.4,0.4);
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
break;
case CITY:
cairo_set_source_rgb (cr, .5,.5,.5);
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
break;
case URBAN:
cairo_set_source_rgb (cr, .3,.3,.3);
cairo_set_line_width(cr, 1.5 * TRACK_FACTOR);
break;
case MOTORWAY:
cairo_set_source_rgb (cr, .3,.3,.3);
cairo_set_line_width(cr, 3.5 * TRACK_FACTOR);
break;
case HIGHWAY:
cairo_set_source_rgb (cr, .1,.1,.1);
cairo_set_line_width(cr, 4.5 * TRACK_FACTOR);
break;
default:
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
break;
}
}
// fprintf(stderr, "scale is: %lf\n", Mapper->scale);
cairo_matrix_init_identity(&cmatrix);
cairo_matrix_init_scale(&cmatrix, Mapper->scale, Mapper->scale);
cairo_matrix_translate(&cmatrix, -((double)Mapper->xoffset),
-((double)Mapper->yoffset));
cairo_set_matrix(cr, &cmatrix);
bbxmin = Mapper->xoffset;
bbxmax = bbxmin + ((double)Mapper->canvas_x / Mapper->scale);
bbymin = Mapper->yoffset;
bbymax = bbymin + ((double)Mapper->canvas_y / Mapper->scale);
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
for (lp = track; lp; lp=g_list_next(lp)) {
tdata = (trackdata *)lp->data;
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
/* first finish this line, even if the target is outside */
if (!start_newline)
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
start_newline = TRUE;
} else {
//draw_line_with_marker(x, y, x2, y2, Mapper->marker_size, Mapper->linewidth, Mapper->marker_type, Mapper);
if (start_newline) {
// fprintf(stderr, "mt\n");
cairo_move_to (cr, (double)tdata->unitx, (double)tdata->unity);
} else {
// fprintf(stderr, "lt\n");
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
}
start_newline = FALSE;
}
}
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
// print_matrix(cr);
cairo_stroke (cr);
if (!(Mapper->show_marker || trackh->type == UNKNOWN || trackh->type == OUTLINE
|| trackh->type == RIVER || trackh->type == FOOTPATH
|| trackh->type == AGRI)) {
cairo_set_source_rgb (cr, 0.7,0.7,0.7);
cairo_set_line_width(cr, (double)Mapper->linewidth / Mapper->scale);
/* second set drawing for the inner colored track */
switch (trackh->type) {
case CITY:
cairo_set_source_rgb (cr, 1.,1.,1.);
cairo_set_line_width(cr, .5 * TRACK_FACTOR);
break;
case URBAN:
cairo_set_source_rgb (cr, 1.,1.,.7);
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
break;
case MOTORWAY:
cairo_set_source_rgb (cr, 1.,1.,.5);
cairo_set_line_width(cr, 2.5 * TRACK_FACTOR);
break;
case HIGHWAY:
cairo_set_source_rgb (cr, 9.,0.,0.);
cairo_set_line_width(cr, 3.5 * TRACK_FACTOR);
break;
default:
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
break;
}
for (lp = track; lp; lp=g_list_next(lp)) {
tdata = (trackdata *)lp->data;
// x = (tdata->unitx - Mapper->xoffset) * Mapper->scale;
// y = (tdata->unity - Mapper->yoffset) * Mapper->scale;
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", (double)tdata->unitx, (double)tdata->unity, Mapper->scale);
// fprintf(stderr,"x=%lf y=%lf\n", x, y);
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
// fprintf(stderr, "nl\n");
/* first finish this line, even if the target is outside */
if (!start_newline)
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
start_newline = TRUE;
} else {
//draw_line_with_marker(x, y, x2, y2, Mapper->marker_size, Mapper->linewidth, Mapper->marker_type, Mapper);
if (start_newline) {
// fprintf(stderr, "mt\n");
cairo_move_to (cr, (double)tdata->unitx, (double)tdata->unity);
} else {
// fprintf(stderr, "lt\n");
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
}
start_newline = FALSE;
}
}
cairo_stroke (cr);
}
if (Mapper->show_marker)
draw_markers(trackh, bbxmin, bbxmax, bbymin, bbymax, Mapper, cr);
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
// print_matrix(cr);
cairo_stroke (cr);
cairo_destroy (cr);
}
static gboolean
draw_idle(gpointer user_data)
{
mapwin *Mapper = (mapwin *)user_data;
static GList *track=NULL;
static track_head *trackh=NULL;
trackdata *tdata;
double x,y;
static double x2=-1,y2=-1;
static GList *lp=NULL;
if (Mapper->tracklist == NULL) {
// fprintf(stderr,"tracklist==NULL -> end\n");
/* erase drawing area */
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
gtk_widget_queue_draw(Mapper->drawarea);
Mapper->draw_idle_active = FALSE;
track = NULL;
lp = NULL;
x2 = -1;
y2 = -1;
return FALSE;
}
// start new drawing
if (!Mapper->draw_idle_active) {
// fprintf(stderr,"new drawing -> starting\n");
Mapper->draw_idle_active = TRUE;
track = Mapper->tracklist;
/* erase drawing area */
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
lp = NULL;
x2 = -1; y2 = -1;
}
trackh=(track_head *)track->data;
if (trackh->xmax < Mapper->xoffset ||
trackh->ymax < Mapper->yoffset ||
trackh->xmin > (Mapper->xoffset + (Mapper->canvas_x / Mapper->scale)) ||
trackh->ymin > (Mapper->yoffset + (Mapper->canvas_y / Mapper->scale))) {
/* fprintf(stderr, "not drawing track '%s'\n", trackh->name); */
} else if (trackh->track != NULL && trackh->show) {
if (lp == NULL)
lp = trackh->track;
tdata = (trackdata *)lp->data;
x = (tdata->unitx - Mapper->xoffset) * Mapper->scale;
y = (tdata->unity - Mapper->yoffset) * Mapper->scale;
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", tdata->longitude, tdata->latitude, Mapper->scale);
/* if the next point is the same as the previous we do not see a line so we do not paint it */
if ((guint)x != (guint)x2 || (guint)y != (guint)y2) {
if (x2 < 0 && y2 < 0) {
x2 = x; y2 = y;
draw_marker(x,y,Mapper->marker_size, Mapper->marker_type | (tdata->selected ? MARKER_SELECTED : 0), Mapper);
} else {
if ((x < 0 || x > Mapper->canvas_x) || (y < 0 || y > Mapper->canvas_y)) {
x2 = -1; y2 = -1;
} else {
draw_marker(x,y,Mapper->marker_size, Mapper->marker_type | (tdata->selected ? MARKER_SELECTED : 0), Mapper);
draw_line(x, y, x2, y2, Mapper->linewidth, Mapper);
x2 = x;
y2 = y;
}
}
}
}
// OK, done with this track
lp = g_list_next(lp);
if (lp == NULL) {
// fprintf(stderr,"track end -> next track\n");
gtk_widget_queue_draw(Mapper->drawarea);
track = g_list_next(track);
if (track != NULL) {
trackh = (track_head *)track->data;
lp = trackh->track;
x2 = -1; y2 = -1;
}
}
if (track == NULL) {
// fprintf(stderr,"end of tracks -> end\n");
draw_waypoints(Mapper);
Mapper->draw_idle_active = FALSE;
gtk_widget_queue_draw(Mapper->drawarea);
return FALSE;
}
return TRUE;
}
void
draw_tracks(mapwin *Mapper)
{
if (Mapper->use_idledraw) {
if (Mapper->draw_idle_active) {
Mapper->draw_idle_active = FALSE;
g_idle_remove_by_data(Mapper);
}
g_idle_add_full(G_PRIORITY_HIGH_IDLE + 20, draw_idle, Mapper, NULL);
} else {
GList *track;
track_head *trackh;
/* erase drawing area */
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
gtk_widget_queue_draw(Mapper->drawarea);
if (Mapper->tracklist != NULL) {
for (track=Mapper->tracklist; track; track=g_list_next(track)) {
trackh = (track_head *)track->data;
if (trackh->show) {
if (trackh->xmax < Mapper->xoffset ||
trackh->ymax < Mapper->yoffset ||
trackh->xmin > (Mapper->xoffset + (Mapper->canvas_x / Mapper->scale)) ||
trackh->ymin > (Mapper->yoffset + (Mapper->canvas_y / Mapper->scale))) {
// fprintf(stderr, "not drawing track '%s'\n", trackh->name);
} else
draw_track(trackh, Mapper);
}
}
}
}
}
void
draw_filename (gchar *fname, mapwin *Mapper)
{
if (gpxread(fname, Mapper) < 0)
return;
draw_tracks(Mapper);
draw_city_names(Mapper);
draw_waypoints(Mapper);
gtk_widget_queue_draw(Mapper->drawarea);
}