/* * trackdraw * * Copyright (C) 2006 Nils Faerber * * * 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 #include #include #include #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); }