745 lines
22 KiB
C
745 lines
22 KiB
C
![]() |
/*
|
||
|
* 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);
|
||
|
}
|