4 |
* osm-gps-map.c |
* osm-gps-map.c |
5 |
* Copyright (C) Marcus Bauer 2008 <marcus.bauer@gmail.com> |
* Copyright (C) Marcus Bauer 2008 <marcus.bauer@gmail.com> |
6 |
* Copyright (C) John Stowers 2009 <john.stowers@gmail.com> |
* Copyright (C) John Stowers 2009 <john.stowers@gmail.com> |
7 |
|
* Copyright (C) Till Harbaum 2009 <till@harbaum.org> |
8 |
* |
* |
9 |
* Contributions by |
* Contributions by |
10 |
* Everaldo Canuto 2009 <everaldo.canuto@gmail.com> |
* Everaldo Canuto 2009 <everaldo.canuto@gmail.com> |
11 |
* |
* |
12 |
* osm-gps-map.c is free software: you can redistribute it and/or modify it |
* osm-gps-map.c is free software: you can redistribute it and/or modify it |
13 |
* under the terms of the GNU General Public License as published by the |
* under the terms of the GNU General Public License |
14 |
* Free Software Foundation, either version 3 of the License, or |
* as published by the Free Software Foundation; version 2. |
|
* (at your option) any later version. |
|
15 |
* |
* |
16 |
* osm-gps-map.c is distributed in the hope that it will be useful, but |
* This program is distributed in the hope that it will be useful, |
17 |
* WITHOUT ANY WARRANTY; without even the implied warranty of |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 |
* See the GNU General Public License for more details. |
* GNU General Public License for more details. |
20 |
* |
* |
21 |
* You should have received a copy of the GNU General Public License along |
* You should have received a copy of the GNU General Public License |
22 |
* with this program. If not, see <http://www.gnu.org/licenses/>. |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
23 |
*/ |
*/ |
24 |
|
|
25 |
#include "config.h" |
#include "config.h" |
36 |
#include <glib/gstdio.h> |
#include <glib/gstdio.h> |
37 |
#include <glib/gprintf.h> |
#include <glib/gprintf.h> |
38 |
#include <libsoup/soup.h> |
#include <libsoup/soup.h> |
39 |
|
#include <cairo.h> |
40 |
|
|
41 |
#include "converter.h" |
#include "converter.h" |
42 |
#include "osm-gps-map-types.h" |
#include "osm-gps-map-types.h" |
43 |
#include "osm-gps-map.h" |
#include "osm-gps-map.h" |
44 |
|
|
|
#ifdef USE_CAIRO |
|
|
#include <cairo.h> |
|
|
#endif |
|
|
|
|
45 |
#define ENABLE_DEBUG 0 |
#define ENABLE_DEBUG 0 |
46 |
|
|
47 |
#define EXTRA_BORDER (TILESIZE / 2) |
#define EXTRA_BORDER (TILESIZE / 2) |
48 |
|
|
49 |
#define OSM_GPS_MAP_SCROLL_STEP 10 |
#define OSM_GPS_MAP_SCROLL_STEP 10 |
50 |
|
|
|
/* any defined key enables key support */ |
|
|
#if (defined(OSM_GPS_MAP_KEY_FULLSCREEN) || \ |
|
|
defined(OSM_GPS_MAP_KEY_ZOOMIN) || \ |
|
|
defined(OSM_GPS_MAP_KEY_ZOOMOUT) || \ |
|
|
defined(OSM_GPS_MAP_KEY_UP) || \ |
|
|
defined(OSM_GPS_MAP_KEY_DOWN) || \ |
|
|
defined(OSM_GPS_MAP_KEY_LEFT) || \ |
|
|
defined(OSM_GPS_MAP_KEY_RIGHT)) |
|
|
#define OSM_GPS_MAP_KEYS |
|
|
#endif |
|
|
|
|
|
#ifdef OSM_GPS_MAP_KEYS |
|
|
#include <gdk/gdkkeysyms.h> |
|
|
#endif |
|
|
|
|
51 |
#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11" |
#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11" |
52 |
|
|
53 |
struct _OsmGpsMapPrivate |
struct _OsmGpsMapPrivate |
80 |
|
|
81 |
//where downloaded tiles are cached |
//where downloaded tiles are cached |
82 |
char *tile_dir; |
char *tile_dir; |
83 |
|
char *tile_base_dir; |
84 |
char *cache_dir; |
char *cache_dir; |
85 |
|
|
86 |
//contains flags indicating the various special characters |
//contains flags indicating the various special characters |
107 |
#ifdef OSD_DOUBLE_BUFFER |
#ifdef OSD_DOUBLE_BUFFER |
108 |
GdkPixmap *dbuf_pixmap; |
GdkPixmap *dbuf_pixmap; |
109 |
#endif |
#endif |
110 |
#endif |
#endif |
|
|
|
|
#ifdef OSM_GPS_MAP_KEY_FULLSCREEN |
|
|
gboolean fullscreen; |
|
|
#endif |
|
|
|
|
111 |
//additional images or tracks added to the map |
//additional images or tracks added to the map |
112 |
GSList *tracks; |
GSList *tracks; |
113 |
GSList *images; |
GSList *images; |
127 |
int drag_start_mouse_y; |
int drag_start_mouse_y; |
128 |
int drag_start_map_x; |
int drag_start_map_x; |
129 |
int drag_start_map_y; |
int drag_start_map_y; |
130 |
|
int drag_limit; |
131 |
guint drag_expose; |
guint drag_expose; |
132 |
|
|
133 |
//for customizing the redering of the gps track |
//for customizing the redering of the gps track |
135 |
int ui_gps_point_inner_radius; |
int ui_gps_point_inner_radius; |
136 |
int ui_gps_point_outer_radius; |
int ui_gps_point_outer_radius; |
137 |
|
|
138 |
|
//For storing keybindings |
139 |
|
guint keybindings[OSM_GPS_MAP_KEY_MAX]; |
140 |
|
|
141 |
|
guint fullscreen : 1; |
142 |
|
guint keybindings_enabled : 1; |
143 |
guint is_disposed : 1; |
guint is_disposed : 1; |
144 |
guint dragging : 1; |
guint dragging : 1; |
145 |
|
guint button_down : 1; |
146 |
|
guint double_pixel : 1; |
147 |
}; |
}; |
148 |
|
|
149 |
#define OSM_GPS_MAP_PRIVATE(o) (OSM_GPS_MAP (o)->priv) |
#define OSM_GPS_MAP_PRIVATE(o) (OSM_GPS_MAP (o)->priv) |
160 |
{ |
{ |
161 |
PROP_0, |
PROP_0, |
162 |
|
|
163 |
|
PROP_DOUBLE_PIXEL, |
164 |
PROP_AUTO_CENTER, |
PROP_AUTO_CENTER, |
165 |
PROP_RECORD_TRIP_HISTORY, |
PROP_RECORD_TRIP_HISTORY, |
166 |
PROP_SHOW_TRIP_HISTORY, |
PROP_SHOW_TRIP_HISTORY, |
168 |
PROP_REPO_URI, |
PROP_REPO_URI, |
169 |
PROP_PROXY_URI, |
PROP_PROXY_URI, |
170 |
PROP_TILE_CACHE_DIR, |
PROP_TILE_CACHE_DIR, |
171 |
|
PROP_TILE_CACHE_BASE_DIR, |
172 |
|
PROP_TILE_CACHE_DIR_IS_FULL_PATH, |
173 |
PROP_ZOOM, |
PROP_ZOOM, |
174 |
PROP_MAX_ZOOM, |
PROP_MAX_ZOOM, |
175 |
PROP_MIN_ZOOM, |
PROP_MIN_ZOOM, |
182 |
PROP_GPS_POINT_R1, |
PROP_GPS_POINT_R1, |
183 |
PROP_GPS_POINT_R2, |
PROP_GPS_POINT_R2, |
184 |
PROP_MAP_SOURCE, |
PROP_MAP_SOURCE, |
185 |
PROP_IMAGE_FORMAT |
PROP_IMAGE_FORMAT, |
186 |
|
PROP_DRAG_LIMIT, |
187 |
}; |
}; |
188 |
|
|
189 |
G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); |
G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); |
197 |
static void osm_gps_map_print_images (OsmGpsMap *map); |
static void osm_gps_map_print_images (OsmGpsMap *map); |
198 |
static void osm_gps_map_draw_gps_point (OsmGpsMap *map); |
static void osm_gps_map_draw_gps_point (OsmGpsMap *map); |
199 |
static void osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y); |
static void osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y); |
200 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
201 |
static void osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data); |
static void osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data); |
202 |
#else |
#else |
203 |
static void osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpointer user_data); |
static void osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpointer user_data); |
541 |
priv->gc_map, |
priv->gc_map, |
542 |
im->image, |
im->image, |
543 |
0,0, |
0,0, |
544 |
x-(im->w/2),y-(im->h/2), |
x-im->xoffset,y-im->yoffset, |
545 |
im->w,im->h, |
im->w,im->h, |
546 |
GDK_RGB_DITHER_NONE, 0, 0); |
GDK_RGB_DITHER_NONE, 0, 0); |
547 |
|
|
575 |
map_y0 = priv->map_y - EXTRA_BORDER; |
map_y0 = priv->map_y - EXTRA_BORDER; |
576 |
x = lon2pixel(priv->map_zoom, priv->gps->rlon) - map_x0; |
x = lon2pixel(priv->map_zoom, priv->gps->rlon) - map_x0; |
577 |
y = lat2pixel(priv->map_zoom, priv->gps->rlat) - map_y0; |
y = lat2pixel(priv->map_zoom, priv->gps->rlat) - map_y0; |
|
#ifdef USE_CAIRO |
|
578 |
cairo_t *cr; |
cairo_t *cr; |
579 |
cairo_pattern_t *pat; |
cairo_pattern_t *pat; |
|
#else |
|
|
GdkColor color; |
|
|
GdkGC *marker; |
|
|
#endif |
|
580 |
|
|
|
#ifdef USE_CAIRO |
|
581 |
cr = gdk_cairo_create(priv->pixmap); |
cr = gdk_cairo_create(priv->pixmap); |
582 |
|
|
583 |
// draw transparent area |
// draw transparent area |
623 |
cairo_arc (cr, x, y, r, 0, 2 * M_PI); |
cairo_arc (cr, x, y, r, 0, 2 * M_PI); |
624 |
cairo_stroke(cr); |
cairo_stroke(cr); |
625 |
} |
} |
626 |
|
|
627 |
cairo_destroy(cr); |
cairo_destroy(cr); |
628 |
gtk_widget_queue_draw_area (GTK_WIDGET(map), |
gtk_widget_queue_draw_area (GTK_WIDGET(map), |
629 |
x-mr, |
x-mr, |
630 |
y-mr, |
y-mr, |
631 |
mr*2, |
mr*2, |
632 |
mr*2); |
mr*2); |
|
#else |
|
|
marker = gdk_gc_new(priv->pixmap); |
|
|
color.red = 5000; |
|
|
color.green = 5000; |
|
|
color.blue = 55000; |
|
|
gdk_gc_set_rgb_fg_color(marker, &color); |
|
|
gdk_gc_set_line_attributes(marker, lw, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); |
|
|
|
|
|
if (r2 > 0) { |
|
|
gdk_draw_arc (priv->pixmap, |
|
|
marker, |
|
|
FALSE, //filled |
|
|
x-r2, y-r2, // x,y |
|
|
r2*2,r2*2, // width, height |
|
|
0, 360*64); // start-end angle 64th, from 3h, anti clockwise |
|
|
} |
|
|
if (r > 0) { |
|
|
gdk_draw_arc (priv->pixmap, |
|
|
marker, |
|
|
TRUE, //filled |
|
|
x-r, y-r, // x,y |
|
|
r*2,r*2, // width, height |
|
|
0, 360*64); // start-end angle 64th, from 3h, anti clockwise |
|
|
} |
|
|
|
|
|
g_object_unref(marker); |
|
|
gtk_widget_queue_draw_area (GTK_WIDGET(map), |
|
|
x-(mr+lw), |
|
|
y-(mr+lw), |
|
|
(mr*2)+lw+lw, |
|
|
(mr*2)+lw+lw); |
|
|
#endif |
|
633 |
} |
} |
634 |
} |
} |
635 |
|
|
636 |
static void |
static void |
637 |
osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y) |
osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y) |
638 |
{ |
{ |
639 |
OsmGpsMapPrivate *priv = map->priv; |
OsmGpsMapPrivate *priv = map->priv; |
640 |
|
|
641 |
g_debug("Queing redraw @ %d,%d (w:%d h:%d)", offset_x,offset_y, TILESIZE,TILESIZE); |
if (priv->double_pixel) { |
642 |
|
g_debug("Queing redraw @ %d,%d (w:%d h:%d)", offset_x,offset_y, TILESIZE*2,TILESIZE*2); |
643 |
|
|
644 |
|
GdkPixbuf *double_pixbuf = gdk_pixbuf_scale_simple (pixbuf, TILESIZE*2, TILESIZE*2, |
645 |
|
GDK_INTERP_NEAREST); |
646 |
|
|
647 |
/* draw pixbuf onto pixmap */ |
/* draw pixbuf onto pixmap */ |
648 |
gdk_draw_pixbuf (priv->pixmap, |
gdk_draw_pixbuf (priv->pixmap, |
649 |
priv->gc_map, |
priv->gc_map, |
650 |
pixbuf, |
double_pixbuf, |
651 |
0,0, |
0,0, |
652 |
offset_x,offset_y, |
offset_x,offset_y, |
653 |
TILESIZE,TILESIZE, |
TILESIZE*2,TILESIZE*2, |
654 |
GDK_RGB_DITHER_NONE, 0, 0); |
GDK_RGB_DITHER_NONE, 0, 0); |
655 |
|
g_object_unref (double_pixbuf); |
656 |
|
} |
657 |
|
else |
658 |
|
{ |
659 |
|
g_debug("Queing redraw @ %d,%d (w:%d h:%d)", offset_x,offset_y, TILESIZE,TILESIZE); |
660 |
|
|
661 |
|
/* draw pixbuf onto pixmap */ |
662 |
|
gdk_draw_pixbuf (priv->pixmap, |
663 |
|
priv->gc_map, |
664 |
|
pixbuf, |
665 |
|
0,0, |
666 |
|
offset_x,offset_y, |
667 |
|
TILESIZE,TILESIZE, |
668 |
|
GDK_RGB_DITHER_NONE, 0, 0); |
669 |
|
} |
670 |
} |
} |
671 |
|
|
672 |
/* libsoup-2.2 and libsoup-2.4 use different ways to store the body data */ |
/* libsoup-2.2 and libsoup-2.4 use different ways to store the body data */ |
673 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
674 |
#define soup_message_headers_append(a,b,c) soup_message_add_header(a,b,c) |
#define soup_message_headers_append(a,b,c) soup_message_add_header(a,b,c) |
675 |
#define MSG_RESPONSE_BODY(a) ((a)->response.body) |
#define MSG_RESPONSE_BODY(a) ((a)->response.body) |
676 |
#define MSG_RESPONSE_LEN(a) ((a)->response.length) |
#define MSG_RESPONSE_LEN(a) ((a)->response.length) |
681 |
#define MSG_RESPONSE_LEN_FORMAT "%lld" |
#define MSG_RESPONSE_LEN_FORMAT "%lld" |
682 |
#endif |
#endif |
683 |
|
|
684 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
685 |
static void |
static void |
686 |
osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data) |
osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data) |
687 |
#else |
#else |
797 |
} |
} |
798 |
else |
else |
799 |
{ |
{ |
800 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
801 |
soup_session_requeue_message(dl->session, msg); |
soup_session_requeue_message(dl->session, msg); |
802 |
#else |
#else |
803 |
soup_session_requeue_message(session, msg); |
soup_session_requeue_message(session, msg); |
819 |
//calculate the uri to download |
//calculate the uri to download |
820 |
dl->uri = replace_map_uri(map, priv->repo_uri, zoom, x, y); |
dl->uri = replace_map_uri(map, priv->repo_uri, zoom, x, y); |
821 |
|
|
822 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
823 |
dl->session = priv->soup_session; |
dl->session = priv->soup_session; |
824 |
#endif |
#endif |
825 |
|
|
863 |
} |
} |
864 |
} |
} |
865 |
|
|
866 |
#ifdef LIBSOUP22 |
#if USE_LIBSOUP22 |
867 |
soup_message_headers_append(msg->request_headers, |
soup_message_headers_append(msg->request_headers, |
868 |
"User-Agent", USER_AGENT); |
"User-Agent", USER_AGENT); |
869 |
#endif |
#endif |
909 |
tile->pixbuf = pixbuf; |
tile->pixbuf = pixbuf; |
910 |
g_hash_table_insert (priv->tile_cache, filename, tile); |
g_hash_table_insert (priv->tile_cache, filename, tile); |
911 |
} |
} |
912 |
|
else |
913 |
|
{ |
914 |
|
g_free (filename); |
915 |
|
} |
916 |
} |
} |
917 |
|
|
918 |
/* set/update the redraw_cycle timestamp on the tile */ |
/* set/update the redraw_cycle timestamp on the tile */ |
980 |
return osm_gps_map_render_missing_tile_upscaled (map, zoom, x, y); |
return osm_gps_map_render_missing_tile_upscaled (map, zoom, x, y); |
981 |
} |
} |
982 |
|
|
983 |
|
/* default tile lifetime is one week */ |
984 |
|
#ifndef OSD_GPS_MAP_TILE_TTL |
985 |
|
#define OSD_GPS_MAP_TILE_TTL (60*60*24*7) |
986 |
|
#endif |
987 |
|
|
988 |
|
static gboolean |
989 |
|
osm_gps_map_tile_age_exceeded(char *filename) |
990 |
|
{ |
991 |
|
struct stat buf; |
992 |
|
|
993 |
|
if(!g_stat(filename, &buf)) |
994 |
|
return(time(NULL) - buf.st_mtime > OSD_GPS_MAP_TILE_TTL); |
995 |
|
|
996 |
|
return FALSE; |
997 |
|
} |
998 |
|
|
999 |
static void |
static void |
1000 |
osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int offset_y) |
osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int offset_y) |
1001 |
{ |
{ |
1002 |
OsmGpsMapPrivate *priv = map->priv; |
OsmGpsMapPrivate *priv = map->priv; |
1003 |
gchar *filename; |
gchar *filename; |
1004 |
GdkPixbuf *pixbuf; |
GdkPixbuf *pixbuf = NULL; |
1005 |
|
|
1006 |
g_debug("Load tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); |
g_debug("Load tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); |
1007 |
|
|
1017 |
y, |
y, |
1018 |
priv->image_format); |
priv->image_format); |
1019 |
|
|
1020 |
/* try to get file from internal cache first */ |
gboolean needs_refresh = FALSE; |
1021 |
if(!(pixbuf = osm_gps_map_load_cached_tile(map, zoom, x, y))) |
if (g_file_test(filename, G_FILE_TEST_EXISTS)) { |
1022 |
pixbuf = gdk_pixbuf_new_from_file (filename, NULL); |
/* try to get file from internal cache first */ |
1023 |
|
if(!(pixbuf = osm_gps_map_load_cached_tile(map, zoom, x, y))) |
1024 |
|
pixbuf = gdk_pixbuf_new_from_file (filename, NULL); |
1025 |
|
|
1026 |
|
needs_refresh = osm_gps_map_tile_age_exceeded(filename); |
1027 |
|
} |
1028 |
|
|
1029 |
if(pixbuf) |
if(pixbuf) |
1030 |
{ |
{ |
1032 |
osm_gps_map_blit_tile(map, pixbuf, offset_x,offset_y); |
osm_gps_map_blit_tile(map, pixbuf, offset_x,offset_y); |
1033 |
g_object_unref (pixbuf); |
g_object_unref (pixbuf); |
1034 |
} |
} |
1035 |
else |
|
1036 |
|
|
1037 |
|
if(!pixbuf || needs_refresh) |
1038 |
{ |
{ |
1039 |
if (priv->map_auto_download) |
if (priv->map_auto_download) |
1040 |
osm_gps_map_download_tile(map, zoom, x, y, TRUE); |
osm_gps_map_download_tile(map, zoom, x, y, TRUE); |
1041 |
|
|
1042 |
/* try to render the tile by scaling cached tiles from other zoom |
if(!needs_refresh) { |
1043 |
* levels */ |
/* try to render the tile by scaling cached tiles from other zoom |
1044 |
pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y); |
* levels */ |
1045 |
if (pixbuf) |
pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y); |
1046 |
{ |
if (pixbuf) |
1047 |
gdk_draw_pixbuf (priv->pixmap, |
{ |
1048 |
priv->gc_map, |
osm_gps_map_blit_tile (map, pixbuf, offset_x,offset_y); |
1049 |
pixbuf, |
g_object_unref (pixbuf); |
1050 |
0,0, |
} |
1051 |
offset_x,offset_y, |
else |
1052 |
TILESIZE,TILESIZE, |
{ |
1053 |
GDK_RGB_DITHER_NONE, 0, 0); |
//prevent some artifacts when drawing not yet loaded areas. |
1054 |
g_object_unref (pixbuf); |
gdk_draw_rectangle (priv->pixmap, |
1055 |
} |
GTK_WIDGET(map)->style->white_gc, |
1056 |
else |
TRUE, offset_x, offset_y, TILESIZE, TILESIZE); |
1057 |
{ |
} |
|
//prevent some artifacts when drawing not yet loaded areas. |
|
|
gdk_draw_rectangle (priv->pixmap, |
|
|
GTK_WIDGET(map)->style->white_gc, |
|
|
TRUE, offset_x, offset_y, TILESIZE, TILESIZE); |
|
1058 |
} |
} |
1059 |
} |
} |
1060 |
g_free(filename); |
g_free(filename); |
1072 |
|
|
1073 |
g_debug("Fill tiles: %d,%d z:%d", priv->map_x, priv->map_y, priv->map_zoom); |
g_debug("Fill tiles: %d,%d z:%d", priv->map_x, priv->map_y, priv->map_zoom); |
1074 |
|
|
1075 |
offset_x = - priv->map_x % TILESIZE; |
if (priv->double_pixel) |
1076 |
offset_y = - priv->map_y % TILESIZE; |
{ |
1077 |
if (offset_x > 0) offset_x -= TILESIZE; |
width = GTK_WIDGET(map)->allocation.width; |
1078 |
if (offset_y > 0) offset_y -= TILESIZE; |
height = GTK_WIDGET(map)->allocation.height; |
1079 |
|
|
1080 |
offset_xn = offset_x + EXTRA_BORDER; |
offset_x = - priv->map_x % (TILESIZE*2); |
1081 |
offset_yn = offset_y + EXTRA_BORDER; |
offset_y = - priv->map_y % (TILESIZE*2); |
1082 |
|
if (offset_x > 0) offset_x -= (TILESIZE*2); |
1083 |
|
if (offset_y > 0) offset_y -= (TILESIZE*2); |
1084 |
|
|
1085 |
width = GTK_WIDGET(map)->allocation.width; |
offset_xn = offset_x + EXTRA_BORDER; |
1086 |
height = GTK_WIDGET(map)->allocation.height; |
offset_yn = offset_y + EXTRA_BORDER; |
1087 |
|
|
1088 |
tiles_nx = (width - offset_x) / TILESIZE + 1; |
tiles_nx = (width - offset_x) / (TILESIZE*2) + 1; |
1089 |
tiles_ny = (height - offset_y) / TILESIZE + 1; |
tiles_ny = (height - offset_y) / (TILESIZE*2) + 1; |
1090 |
|
|
1091 |
tile_x0 = floor((float)priv->map_x / (float)TILESIZE); |
tile_x0 = floor((float)priv->map_x / (float)(TILESIZE*2)); |
1092 |
tile_y0 = floor((float)priv->map_y / (float)TILESIZE); |
tile_y0 = floor((float)priv->map_y / (float)(TILESIZE*2)); |
1093 |
|
|
1094 |
//TODO: implement wrap around |
for (i=tile_x0; i<(tile_x0+tiles_nx);i++) |
|
for (i=tile_x0; i<(tile_x0+tiles_nx);i++) |
|
|
{ |
|
|
for (j=tile_y0; j<(tile_y0+tiles_ny); j++) |
|
1095 |
{ |
{ |
1096 |
if( j<0 || i<0 || i>=exp(priv->map_zoom * M_LN2) || j>=exp(priv->map_zoom * M_LN2)) |
for (j=tile_y0; j<(tile_y0+tiles_ny); j++) |
1097 |
{ |
{ |
1098 |
gdk_draw_rectangle (priv->pixmap, |
if( j<0 || i<0 || i>=exp(priv->map_zoom * M_LN2) || j>=exp(priv->map_zoom * M_LN2)) |
1099 |
GTK_WIDGET(map)->style->white_gc, |
{ |
1100 |
TRUE, |
gdk_draw_rectangle (priv->pixmap, |
1101 |
offset_xn, offset_yn, |
GTK_WIDGET(map)->style->white_gc, |
1102 |
TILESIZE,TILESIZE); |
TRUE, |
1103 |
|
offset_xn, offset_yn, |
1104 |
|
TILESIZE*2, TILESIZE*2); |
1105 |
|
} |
1106 |
|
else |
1107 |
|
{ |
1108 |
|
osm_gps_map_load_tile(map, |
1109 |
|
priv->map_zoom - 1, |
1110 |
|
i,j, |
1111 |
|
offset_xn,offset_yn); |
1112 |
|
} |
1113 |
|
offset_yn += TILESIZE*2; |
1114 |
} |
} |
1115 |
else |
offset_xn += TILESIZE*2; |
1116 |
|
offset_yn = offset_y + EXTRA_BORDER; |
1117 |
|
} |
1118 |
|
} |
1119 |
|
else |
1120 |
|
{ |
1121 |
|
offset_x = - priv->map_x % TILESIZE; |
1122 |
|
offset_y = - priv->map_y % TILESIZE; |
1123 |
|
if (offset_x > 0) offset_x -= TILESIZE; |
1124 |
|
if (offset_y > 0) offset_y -= TILESIZE; |
1125 |
|
|
1126 |
|
offset_xn = offset_x + EXTRA_BORDER; |
1127 |
|
offset_yn = offset_y + EXTRA_BORDER; |
1128 |
|
|
1129 |
|
width = GTK_WIDGET(map)->allocation.width; |
1130 |
|
height = GTK_WIDGET(map)->allocation.height; |
1131 |
|
|
1132 |
|
tiles_nx = (width - offset_x) / TILESIZE + 1; |
1133 |
|
tiles_ny = (height - offset_y) / TILESIZE + 1; |
1134 |
|
|
1135 |
|
tile_x0 = floor((float)priv->map_x / (float)TILESIZE); |
1136 |
|
tile_y0 = floor((float)priv->map_y / (float)TILESIZE); |
1137 |
|
|
1138 |
|
//TODO: implement wrap around |
1139 |
|
for (i=tile_x0; i<(tile_x0+tiles_nx);i++) |
1140 |
|
{ |
1141 |
|
for (j=tile_y0; j<(tile_y0+tiles_ny); j++) |
1142 |
{ |
{ |
1143 |
osm_gps_map_load_tile(map, |
if( j<0 || i<0 || i>=exp(priv->map_zoom * M_LN2) || j>=exp(priv->map_zoom * M_LN2)) |
1144 |
priv->map_zoom, |
{ |
1145 |
i,j, |
gdk_draw_rectangle (priv->pixmap, |
1146 |
offset_xn,offset_yn); |
GTK_WIDGET(map)->style->white_gc, |
1147 |
|
TRUE, |
1148 |
|
offset_xn, offset_yn, |
1149 |
|
TILESIZE,TILESIZE); |
1150 |
|
} |
1151 |
|
else |
1152 |
|
{ |
1153 |
|
osm_gps_map_load_tile(map, |
1154 |
|
priv->map_zoom, |
1155 |
|
i,j, |
1156 |
|
offset_xn,offset_yn); |
1157 |
|
} |
1158 |
|
offset_yn += TILESIZE; |
1159 |
} |
} |
1160 |
offset_yn += TILESIZE; |
offset_xn += TILESIZE; |
1161 |
|
offset_yn = offset_y + EXTRA_BORDER; |
1162 |
} |
} |
|
offset_xn += TILESIZE; |
|
|
offset_yn = offset_y + EXTRA_BORDER; |
|
1163 |
} |
} |
1164 |
} |
} |
1165 |
|
|
1173 |
int min_x = 0,min_y = 0,max_x = 0,max_y = 0; |
int min_x = 0,min_y = 0,max_x = 0,max_y = 0; |
1174 |
int lw = priv->ui_gps_track_width; |
int lw = priv->ui_gps_track_width; |
1175 |
int map_x0, map_y0; |
int map_x0, map_y0; |
|
#ifdef USE_CAIRO |
|
1176 |
cairo_t *cr; |
cairo_t *cr; |
|
#else |
|
|
int last_x = 0, last_y = 0; |
|
|
GdkColor color; |
|
|
GdkGC *gc; |
|
|
#endif |
|
1177 |
|
|
|
#ifdef USE_CAIRO |
|
1178 |
cr = gdk_cairo_create(priv->pixmap); |
cr = gdk_cairo_create(priv->pixmap); |
1179 |
cairo_set_line_width (cr, lw); |
cairo_set_line_width (cr, lw); |
1180 |
cairo_set_source_rgba (cr, 60000.0/65535.0, 0.0, 0.0, 0.6); |
cairo_set_source_rgba (cr, 60000.0/65535.0, 0.0, 0.0, 0.6); |
1181 |
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); |
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); |
1182 |
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); |
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); |
|
#else |
|
|
gc = gdk_gc_new(priv->pixmap); |
|
|
color.green = 0; |
|
|
color.blue = 0; |
|
|
color.red = 60000; |
|
|
gdk_gc_set_rgb_fg_color(gc, &color); |
|
|
gdk_gc_set_line_attributes(gc, lw, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); |
|
|
#endif |
|
1183 |
|
|
1184 |
map_x0 = priv->map_x - EXTRA_BORDER; |
map_x0 = priv->map_x - EXTRA_BORDER; |
1185 |
map_y0 = priv->map_y - EXTRA_BORDER; |
map_y0 = priv->map_y - EXTRA_BORDER; |
1192 |
|
|
1193 |
// first time through loop |
// first time through loop |
1194 |
if (list == trackpoint_list) { |
if (list == trackpoint_list) { |
|
#ifdef USE_CAIRO |
|
1195 |
cairo_move_to(cr, x, y); |
cairo_move_to(cr, x, y); |
|
#else |
|
|
last_x = x; |
|
|
last_y = y; |
|
|
#endif |
|
1196 |
} |
} |
1197 |
|
|
|
#ifdef USE_CAIRO |
|
1198 |
cairo_line_to(cr, x, y); |
cairo_line_to(cr, x, y); |
|
#else |
|
|
gdk_draw_line (priv->pixmap, gc, x, y, last_x, last_y); |
|
|
last_x = x; |
|
|
last_y = y; |
|
|
#endif |
|
1199 |
|
|
1200 |
max_x = MAX(x,max_x); |
max_x = MAX(x,max_x); |
1201 |
min_x = MIN(x,min_x); |
min_x = MIN(x,min_x); |
1210 |
max_x + (lw * 2), |
max_x + (lw * 2), |
1211 |
max_y + (lw * 2)); |
max_y + (lw * 2)); |
1212 |
|
|
|
#ifdef USE_CAIRO |
|
1213 |
cairo_stroke(cr); |
cairo_stroke(cr); |
1214 |
cairo_destroy(cr); |
cairo_destroy(cr); |
|
#else |
|
|
g_object_unref(gc); |
|
|
#endif |
|
1215 |
} |
} |
1216 |
|
|
1217 |
/* Prints the gps trip history, and any other tracks */ |
/* Prints the gps trip history, and any other tracks */ |
1329 |
} |
} |
1330 |
|
|
1331 |
static void |
static void |
1332 |
center_coord_update(GtkWidget *widget) { |
center_coord_update(OsmGpsMap *map) { |
1333 |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
|
1334 |
|
GtkWidget *widget = GTK_WIDGET(map); |
1335 |
|
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(map); |
1336 |
|
|
1337 |
// pixel_x,y, offsets |
// pixel_x,y, offsets |
1338 |
gint pixel_x = priv->map_x + widget->allocation.width/2; |
gint pixel_x = priv->map_x + widget->allocation.width/2; |
1340 |
|
|
1341 |
priv->center_rlon = pixel2lon(priv->map_zoom, pixel_x); |
priv->center_rlon = pixel2lon(priv->map_zoom, pixel_x); |
1342 |
priv->center_rlat = pixel2lat(priv->map_zoom, pixel_y); |
priv->center_rlat = pixel2lat(priv->map_zoom, pixel_y); |
1343 |
|
|
1344 |
|
g_signal_emit_by_name(widget, "changed"); |
1345 |
} |
} |
1346 |
|
|
|
#ifdef OSM_GPS_MAP_KEYS |
|
1347 |
static gboolean |
static gboolean |
1348 |
on_window_key_press(GtkWidget *widget, |
on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *priv) |
1349 |
GdkEventKey *event, OsmGpsMapPrivate *priv) { |
{ |
1350 |
gboolean handled = FALSE; |
int i; |
1351 |
int step = GTK_WIDGET(widget)->allocation.width/OSM_GPS_MAP_SCROLL_STEP; |
int step; |
1352 |
|
gboolean handled; |
1353 |
// the map handles some keys on its own ... |
OsmGpsMap *map; |
1354 |
switch(event->keyval) { |
|
1355 |
#ifdef OSM_GPS_MAP_KEY_FULLSCREEN |
//if no keybindings are set, let the app handle them... |
1356 |
case OSM_GPS_MAP_KEY_FULLSCREEN: { |
if (!priv->keybindings_enabled) |
1357 |
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget)); |
return FALSE; |
1358 |
if(!priv->fullscreen) |
|
1359 |
gtk_window_fullscreen(GTK_WINDOW(toplevel)); |
handled = FALSE; |
1360 |
else |
map = OSM_GPS_MAP(widget); |
1361 |
gtk_window_unfullscreen(GTK_WINDOW(toplevel)); |
step = GTK_WIDGET(widget)->allocation.width/OSM_GPS_MAP_SCROLL_STEP; |
1362 |
|
|
1363 |
priv->fullscreen = !priv->fullscreen; |
//the map handles some keys on its own |
1364 |
handled = TRUE; |
for (i = 0; i < OSM_GPS_MAP_KEY_MAX; i++) { |
1365 |
} break; |
//not the key we have a binding for |
1366 |
#endif |
if (map->priv->keybindings[i] != event->keyval) |
1367 |
|
continue; |
1368 |
#ifdef OSM_GPS_MAP_KEY_ZOOMIN |
|
1369 |
case OSM_GPS_MAP_KEY_ZOOMIN: |
switch(i) { |
1370 |
osm_gps_map_set_zoom(OSM_GPS_MAP(widget), priv->map_zoom+1); |
case OSM_GPS_MAP_KEY_FULLSCREEN: { |
1371 |
handled = TRUE; |
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget)); |
1372 |
break; |
if(!priv->fullscreen) |
1373 |
#endif |
gtk_window_fullscreen(GTK_WINDOW(toplevel)); |
1374 |
|
else |
1375 |
#ifdef OSM_GPS_MAP_KEY_ZOOMOUT |
gtk_window_unfullscreen(GTK_WINDOW(toplevel)); |
1376 |
case OSM_GPS_MAP_KEY_ZOOMOUT: |
|
1377 |
osm_gps_map_set_zoom(OSM_GPS_MAP(widget), priv->map_zoom-1); |
priv->fullscreen = !priv->fullscreen; |
1378 |
handled = TRUE; |
handled = TRUE; |
1379 |
break; |
} break; |
1380 |
#endif |
case OSM_GPS_MAP_KEY_ZOOMIN: |
1381 |
|
osm_gps_map_zoom_in(map); |
1382 |
#ifdef OSM_GPS_MAP_KEY_UP |
handled = TRUE; |
1383 |
case OSM_GPS_MAP_KEY_UP: |
break; |
1384 |
priv->map_y -= step; |
case OSM_GPS_MAP_KEY_ZOOMOUT: |
1385 |
center_coord_update(widget); |
osm_gps_map_zoom_out(map); |
1386 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
handled = TRUE; |
1387 |
handled = TRUE; |
break; |
1388 |
break; |
case OSM_GPS_MAP_KEY_UP: |
1389 |
#endif |
priv->map_y -= step; |
1390 |
|
center_coord_update(map); |
1391 |
#ifdef OSM_GPS_MAP_KEY_DOWN |
osm_gps_map_map_redraw_idle(map); |
1392 |
case OSM_GPS_MAP_KEY_DOWN: |
handled = TRUE; |
1393 |
priv->map_y += step; |
break; |
1394 |
center_coord_update(widget); |
case OSM_GPS_MAP_KEY_DOWN: |
1395 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
priv->map_y += step; |
1396 |
handled = TRUE; |
center_coord_update(map); |
1397 |
break; |
osm_gps_map_map_redraw_idle(map); |
1398 |
#endif |
handled = TRUE; |
1399 |
|
break; |
1400 |
#ifdef OSM_GPS_MAP_KEY_LEFT |
case OSM_GPS_MAP_KEY_LEFT: |
1401 |
case OSM_GPS_MAP_KEY_LEFT: |
priv->map_x -= step; |
1402 |
priv->map_x -= step; |
center_coord_update(map); |
1403 |
center_coord_update(widget); |
osm_gps_map_map_redraw_idle(map); |
1404 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
handled = TRUE; |
1405 |
handled = TRUE; |
break; |
1406 |
break; |
case OSM_GPS_MAP_KEY_RIGHT: |
1407 |
#endif |
priv->map_x += step; |
1408 |
|
center_coord_update(map); |
1409 |
#ifdef OSM_GPS_MAP_KEY_RIGHT |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
1410 |
case OSM_GPS_MAP_KEY_RIGHT: |
handled = TRUE; |
1411 |
priv->map_x += step; |
break; |
1412 |
center_coord_update(widget); |
default: |
1413 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
break; |
1414 |
handled = TRUE; |
} |
1415 |
break; |
} |
|
#endif |
|
|
|
|
|
default: |
|
|
break; |
|
|
} |
|
1416 |
|
|
1417 |
return handled; |
return handled; |
1418 |
} |
} |
|
#endif |
|
1419 |
|
|
1420 |
static void |
static void |
1421 |
osm_gps_map_init (OsmGpsMap *object) |
osm_gps_map_init (OsmGpsMap *object) |
1422 |
{ |
{ |
1423 |
|
int i; |
1424 |
OsmGpsMapPrivate *priv; |
OsmGpsMapPrivate *priv; |
1425 |
|
|
1426 |
priv = G_TYPE_INSTANCE_GET_PRIVATE (object, OSM_TYPE_GPS_MAP, OsmGpsMapPrivate); |
priv = G_TYPE_INSTANCE_GET_PRIVATE (object, OSM_TYPE_GPS_MAP, OsmGpsMapPrivate); |
1436 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
1437 |
priv->osd = NULL; |
priv->osd = NULL; |
1438 |
#endif |
#endif |
|
|
|
|
#ifdef OSM_GPS_MAP_BUTTON_FULLSCREEN |
|
|
priv->fullscreen = FALSE; |
|
|
#endif |
|
|
|
|
1439 |
priv->tracks = NULL; |
priv->tracks = NULL; |
1440 |
priv->images = NULL; |
priv->images = NULL; |
1441 |
|
|
1450 |
|
|
1451 |
priv->map_source = -1; |
priv->map_source = -1; |
1452 |
|
|
1453 |
#ifndef LIBSOUP22 |
priv->keybindings_enabled = FALSE; |
1454 |
//Change naumber of concurrent connections option? |
for (i = 0; i < OSM_GPS_MAP_KEY_MAX; i++) |
1455 |
priv->soup_session = |
priv->keybindings[i] = 0; |
1456 |
soup_session_async_new_with_options(SOUP_SESSION_USER_AGENT, |
|
1457 |
USER_AGENT, NULL); |
|
1458 |
#else |
#if USE_LIBSOUP22 |
1459 |
/* libsoup-2.2 has no special way to set the user agent, so we */ |
/* libsoup-2.2 has no special way to set the user agent, so we */ |
1460 |
/* set it seperately as an extra header field for each reuest */ |
/* set it seperately as an extra header field for each reuest */ |
1461 |
priv->soup_session = soup_session_async_new(); |
priv->soup_session = soup_session_async_new(); |
1462 |
|
#else |
1463 |
|
/* set the user agent */ |
1464 |
|
priv->soup_session = |
1465 |
|
soup_session_async_new_with_options(SOUP_SESSION_USER_AGENT, |
1466 |
|
USER_AGENT, NULL); |
1467 |
|
|
1468 |
#endif |
#endif |
1469 |
//Hash table which maps tile d/l URIs to SoupMessage requests |
//Hash table which maps tile d/l URIs to SoupMessage requests |
1470 |
priv->tile_queue = g_hash_table_new (g_str_hash, g_str_equal); |
priv->tile_queue = g_hash_table_new (g_str_hash, g_str_equal); |
1486 |
|
|
1487 |
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); |
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); |
1488 |
|
|
1489 |
#ifdef OSM_GPS_MAP_KEYS |
//Setup signal handlers |
1490 |
g_signal_connect(G_OBJECT(object), "key_press_event", |
g_signal_connect(G_OBJECT(object), "key_press_event", |
1491 |
G_CALLBACK(on_window_key_press), priv); |
G_CALLBACK(on_window_key_press), priv); |
|
#endif |
|
1492 |
} |
} |
1493 |
|
|
1494 |
|
static char* |
1495 |
|
osm_gps_map_get_cache_dir(OsmGpsMapPrivate *priv) |
1496 |
|
{ |
1497 |
|
if (priv->tile_base_dir) |
1498 |
|
return g_strdup(priv->tile_base_dir); |
1499 |
|
return osm_gps_map_get_default_cache_directory(); |
1500 |
|
} |
1501 |
|
|
1502 |
|
/* strcmp0 was introduced with glib 2.16 */ |
1503 |
|
#if ! GLIB_CHECK_VERSION (2, 16, 0) |
1504 |
|
int g_strcmp0(const char *str1, const char *str2) |
1505 |
|
{ |
1506 |
|
if( str1 == NULL && str2 == NULL ) return 0; |
1507 |
|
if( str1 == NULL ) return -1; |
1508 |
|
if( str2 == NULL ) return 1; |
1509 |
|
return strcmp(str1, str2); |
1510 |
|
} |
1511 |
|
#endif |
1512 |
|
|
1513 |
static void |
static void |
1514 |
osm_gps_map_setup(OsmGpsMapPrivate *priv) { |
osm_gps_map_setup(OsmGpsMapPrivate *priv) |
1515 |
|
{ |
1516 |
const char *uri; |
const char *uri; |
1517 |
|
|
1518 |
//user can specify a map source ID, or a repo URI as the map source |
//user can specify a map source ID, or a repo URI as the map source |
1519 |
uri = osm_gps_map_source_get_repo_uri(OSM_GPS_MAP_SOURCE_NULL); |
uri = osm_gps_map_source_get_repo_uri(OSM_GPS_MAP_SOURCE_NULL); |
1520 |
if ( (priv->map_source == 0) || (strcmp(priv->repo_uri, uri) == 0) ) { |
if ( (priv->map_source == 0) || (strcmp(priv->repo_uri, uri) == 0) ) { |
1521 |
g_debug("Using null source"); |
g_debug("Using null source"); |
1539 |
} |
} |
1540 |
} |
} |
1541 |
|
|
1542 |
const char *fname = osm_gps_map_source_get_friendly_name(priv->map_source); |
if (priv->tile_dir == NULL) |
1543 |
if(!fname) fname = "_unknown_"; |
priv->tile_dir = g_strdup(OSM_GPS_MAP_CACHE_DISABLED); |
1544 |
|
|
1545 |
if (priv->tile_dir) { |
if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_DISABLED) == 0 ) { |
1546 |
//the new cachedir is the given cache dir + the friendly name of the repo_uri |
priv->cache_dir = NULL; |
1547 |
priv->cache_dir = g_strdup_printf("%s%c%s", priv->tile_dir, G_DIR_SEPARATOR, fname); |
} else if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_AUTO) == 0 ) { |
1548 |
g_debug("Adjusting cache dir %s -> %s", priv->tile_dir, priv->cache_dir); |
char *base = osm_gps_map_get_cache_dir(priv); |
1549 |
|
#if GLIB_CHECK_VERSION (2, 16, 0) |
1550 |
|
char *md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, priv->repo_uri, -1); |
1551 |
|
#else |
1552 |
|
char *md5 = g_strdup(osm_gps_map_source_get_friendly_name(priv->map_source)); |
1553 |
|
#endif |
1554 |
|
priv->cache_dir = g_strdup_printf("%s%c%s", base, G_DIR_SEPARATOR, md5); |
1555 |
|
g_free(base); |
1556 |
|
g_free(md5); |
1557 |
|
} else if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_FRIENDLY) == 0 ) { |
1558 |
|
char *base = osm_gps_map_get_cache_dir(priv); |
1559 |
|
const char *fname = osm_gps_map_source_get_friendly_name(priv->map_source); |
1560 |
|
priv->cache_dir = g_strdup_printf("%s%c%s", base, G_DIR_SEPARATOR, fname); |
1561 |
|
g_free(base); |
1562 |
|
} else { |
1563 |
|
priv->cache_dir = g_strdup(priv->tile_dir); |
1564 |
} |
} |
1565 |
|
g_debug("Cache dir: %s", priv->cache_dir); |
1566 |
} |
} |
1567 |
|
|
1568 |
static GObject * |
static GObject * |
1597 |
g_hash_table_destroy(priv->missing_tiles); |
g_hash_table_destroy(priv->missing_tiles); |
1598 |
g_hash_table_destroy(priv->tile_cache); |
g_hash_table_destroy(priv->tile_cache); |
1599 |
|
|
1600 |
|
/* images and layers contain GObjects which need unreffing, so free here */ |
1601 |
osm_gps_map_free_images(map); |
osm_gps_map_free_images(map); |
1602 |
|
|
1603 |
if(priv->pixmap) |
if(priv->pixmap) |
1618 |
g_free(priv->gps); |
g_free(priv->gps); |
1619 |
|
|
1620 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
1621 |
if(priv->osd) |
if(priv->osd) { |
1622 |
priv->osd->free(priv->osd); |
priv->osd->free(priv->osd); |
1623 |
|
priv->osd = NULL; |
1624 |
|
} |
1625 |
|
|
1626 |
#ifdef OSD_DOUBLE_BUFFER |
#ifdef OSD_DOUBLE_BUFFER |
1627 |
if(priv->dbuf_pixmap) |
if(priv->dbuf_pixmap) |
1638 |
OsmGpsMap *map = OSM_GPS_MAP(object); |
OsmGpsMap *map = OSM_GPS_MAP(object); |
1639 |
OsmGpsMapPrivate *priv = map->priv; |
OsmGpsMapPrivate *priv = map->priv; |
1640 |
|
|
1641 |
if(priv->tile_dir) |
if (priv->tile_dir) |
1642 |
g_free(priv->tile_dir); |
g_free(priv->tile_dir); |
1643 |
|
|
1644 |
if(priv->cache_dir) |
if (priv->cache_dir) |
1645 |
g_free(priv->cache_dir); |
g_free(priv->cache_dir); |
1646 |
|
|
1647 |
g_free(priv->repo_uri); |
g_free(priv->repo_uri); |
1648 |
g_free(priv->image_format); |
g_free(priv->image_format); |
1649 |
|
|
1650 |
|
/* trip and tracks contain simple non GObject types, so free them here */ |
1651 |
osm_gps_map_free_trip(map); |
osm_gps_map_free_trip(map); |
1652 |
osm_gps_map_free_tracks(map); |
osm_gps_map_free_tracks(map); |
1653 |
|
|
1666 |
case PROP_AUTO_CENTER: |
case PROP_AUTO_CENTER: |
1667 |
priv->map_auto_center = g_value_get_boolean (value); |
priv->map_auto_center = g_value_get_boolean (value); |
1668 |
break; |
break; |
1669 |
|
case PROP_DOUBLE_PIXEL: |
1670 |
|
priv->double_pixel = g_value_get_boolean (value); |
1671 |
|
osm_gps_map_map_redraw_idle(map); |
1672 |
|
break; |
1673 |
case PROP_RECORD_TRIP_HISTORY: |
case PROP_RECORD_TRIP_HISTORY: |
1674 |
priv->record_trip_history = g_value_get_boolean (value); |
priv->record_trip_history = g_value_get_boolean (value); |
1675 |
break; |
break; |
1687 |
priv->proxy_uri = g_value_dup_string (value); |
priv->proxy_uri = g_value_dup_string (value); |
1688 |
g_debug("Setting proxy server: %s", priv->proxy_uri); |
g_debug("Setting proxy server: %s", priv->proxy_uri); |
1689 |
|
|
1690 |
#ifndef LIBSOUP22 |
#if USE_LIBSOUP22 |
1691 |
|
SoupUri* uri = soup_uri_new(priv->proxy_uri); |
1692 |
|
g_object_set(G_OBJECT(priv->soup_session), SOUP_SESSION_PROXY_URI, uri, NULL); |
1693 |
|
#else |
1694 |
GValue val = {0}; |
GValue val = {0}; |
|
|
|
1695 |
SoupURI* uri = soup_uri_new(priv->proxy_uri); |
SoupURI* uri = soup_uri_new(priv->proxy_uri); |
1696 |
g_value_init(&val, SOUP_TYPE_URI); |
g_value_init(&val, SOUP_TYPE_URI); |
1697 |
g_value_take_boxed(&val, uri); |
g_value_take_boxed(&val, uri); |
|
|
|
1698 |
g_object_set_property(G_OBJECT(priv->soup_session),SOUP_SESSION_PROXY_URI,&val); |
g_object_set_property(G_OBJECT(priv->soup_session),SOUP_SESSION_PROXY_URI,&val); |
|
#else |
|
|
SoupUri* uri = soup_uri_new(priv->proxy_uri); |
|
|
g_object_set(G_OBJECT(priv->soup_session), SOUP_SESSION_PROXY_URI, uri, NULL); |
|
1699 |
#endif |
#endif |
1700 |
} else |
} else |
1701 |
priv->proxy_uri = NULL; |
priv->proxy_uri = NULL; |
1702 |
|
|
1703 |
break; |
break; |
1704 |
case PROP_TILE_CACHE_DIR: |
case PROP_TILE_CACHE_DIR: |
1705 |
if ( g_value_get_string(value) ) |
priv->tile_dir = g_value_dup_string (value); |
1706 |
priv->tile_dir = g_value_dup_string (value); |
break; |
1707 |
|
case PROP_TILE_CACHE_BASE_DIR: |
1708 |
|
priv->tile_base_dir = g_value_dup_string (value); |
1709 |
break; |
break; |
1710 |
|
case PROP_TILE_CACHE_DIR_IS_FULL_PATH: |
1711 |
|
g_warning("GObject property tile-cache-is-full-path depreciated"); |
1712 |
|
break; |
1713 |
case PROP_ZOOM: |
case PROP_ZOOM: |
1714 |
priv->map_zoom = g_value_get_int (value); |
priv->map_zoom = g_value_get_int (value); |
1715 |
break; |
break; |
1721 |
break; |
break; |
1722 |
case PROP_MAP_X: |
case PROP_MAP_X: |
1723 |
priv->map_x = g_value_get_int (value); |
priv->map_x = g_value_get_int (value); |
1724 |
center_coord_update(GTK_WIDGET(object)); |
center_coord_update(map); |
1725 |
break; |
break; |
1726 |
case PROP_MAP_Y: |
case PROP_MAP_Y: |
1727 |
priv->map_y = g_value_get_int (value); |
priv->map_y = g_value_get_int (value); |
1728 |
center_coord_update(GTK_WIDGET(object)); |
center_coord_update(map); |
1729 |
break; |
break; |
1730 |
case PROP_GPS_TRACK_WIDTH: |
case PROP_GPS_TRACK_WIDTH: |
1731 |
priv->ui_gps_track_width = g_value_get_int (value); |
priv->ui_gps_track_width = g_value_get_int (value); |
1764 |
case PROP_IMAGE_FORMAT: |
case PROP_IMAGE_FORMAT: |
1765 |
priv->image_format = g_value_dup_string (value); |
priv->image_format = g_value_dup_string (value); |
1766 |
break; |
break; |
1767 |
|
case PROP_DRAG_LIMIT: |
1768 |
|
priv->drag_limit = g_value_get_int (value); |
1769 |
|
break; |
1770 |
default: |
default: |
1771 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1772 |
break; |
break; |
1777 |
osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) |
osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) |
1778 |
{ |
{ |
1779 |
g_return_if_fail (OSM_IS_GPS_MAP (object)); |
g_return_if_fail (OSM_IS_GPS_MAP (object)); |
|
float lat,lon; |
|
1780 |
OsmGpsMap *map = OSM_GPS_MAP(object); |
OsmGpsMap *map = OSM_GPS_MAP(object); |
1781 |
OsmGpsMapPrivate *priv = map->priv; |
OsmGpsMapPrivate *priv = map->priv; |
1782 |
|
|
1783 |
switch (prop_id) |
switch (prop_id) |
1784 |
{ |
{ |
1785 |
|
case PROP_DOUBLE_PIXEL: |
1786 |
|
g_value_set_boolean(value, priv->double_pixel); |
1787 |
|
break; |
1788 |
case PROP_AUTO_CENTER: |
case PROP_AUTO_CENTER: |
1789 |
g_value_set_boolean(value, priv->map_auto_center); |
g_value_set_boolean(value, priv->map_auto_center); |
1790 |
break; |
break; |
1806 |
case PROP_TILE_CACHE_DIR: |
case PROP_TILE_CACHE_DIR: |
1807 |
g_value_set_string(value, priv->cache_dir); |
g_value_set_string(value, priv->cache_dir); |
1808 |
break; |
break; |
1809 |
|
case PROP_TILE_CACHE_BASE_DIR: |
1810 |
|
g_value_set_string(value, priv->tile_base_dir); |
1811 |
|
break; |
1812 |
|
case PROP_TILE_CACHE_DIR_IS_FULL_PATH: |
1813 |
|
g_value_set_boolean(value, FALSE); |
1814 |
|
break; |
1815 |
case PROP_ZOOM: |
case PROP_ZOOM: |
1816 |
g_value_set_int(value, priv->map_zoom); |
g_value_set_int(value, priv->map_zoom); |
1817 |
break; |
break; |
1822 |
g_value_set_int(value, priv->min_zoom); |
g_value_set_int(value, priv->min_zoom); |
1823 |
break; |
break; |
1824 |
case PROP_LATITUDE: |
case PROP_LATITUDE: |
1825 |
lat = pixel2lat(priv->map_zoom, |
g_value_set_float(value, rad2deg(priv->center_rlat)); |
|
priv->map_y + (GTK_WIDGET(map)->allocation.height / 2)); |
|
|
g_value_set_float(value, rad2deg(lat)); |
|
1826 |
break; |
break; |
1827 |
case PROP_LONGITUDE: |
case PROP_LONGITUDE: |
1828 |
lon = pixel2lon(priv->map_zoom, |
g_value_set_float(value, rad2deg(priv->center_rlon)); |
|
priv->map_x + (GTK_WIDGET(map)->allocation.width / 2)); |
|
|
g_value_set_float(value, rad2deg(lon)); |
|
1829 |
break; |
break; |
1830 |
case PROP_MAP_X: |
case PROP_MAP_X: |
1831 |
g_value_set_int(value, priv->map_x); |
g_value_set_int(value, priv->map_x); |
1851 |
case PROP_IMAGE_FORMAT: |
case PROP_IMAGE_FORMAT: |
1852 |
g_value_set_string(value, priv->image_format); |
g_value_set_string(value, priv->image_format); |
1853 |
break; |
break; |
1854 |
|
case PROP_DRAG_LIMIT: |
1855 |
|
g_value_set_int(value, priv->drag_limit); |
1856 |
|
break; |
1857 |
default: |
default: |
1858 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1859 |
break; |
break; |
1864 |
osm_gps_map_scroll_event (GtkWidget *widget, GdkEventScroll *event) |
osm_gps_map_scroll_event (GtkWidget *widget, GdkEventScroll *event) |
1865 |
{ |
{ |
1866 |
OsmGpsMap *map = OSM_GPS_MAP(widget); |
OsmGpsMap *map = OSM_GPS_MAP(widget); |
|
OsmGpsMapPrivate *priv = map->priv; |
|
1867 |
|
|
1868 |
if (event->direction == GDK_SCROLL_UP) |
if (event->direction == GDK_SCROLL_UP) |
1869 |
{ |
osm_gps_map_zoom_in(map); |
1870 |
osm_gps_map_set_zoom(map, priv->map_zoom+1); |
else if (event->direction == GDK_SCROLL_DOWN) |
1871 |
} |
osm_gps_map_zoom_out(map); |
|
else |
|
|
{ |
|
|
osm_gps_map_set_zoom(map, priv->map_zoom-1); |
|
|
} |
|
1872 |
|
|
1873 |
return FALSE; |
return FALSE; |
1874 |
} |
} |
1876 |
static gboolean |
static gboolean |
1877 |
osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) |
osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) |
1878 |
{ |
{ |
1879 |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
OsmGpsMap *map = OSM_GPS_MAP(widget); |
1880 |
|
OsmGpsMapPrivate *priv = map->priv; |
1881 |
|
|
1882 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
1883 |
/* pressed inside OSD control? */ |
/* pressed inside OSD control? */ |
1894 |
switch(but) { |
switch(but) { |
1895 |
case OSD_UP: |
case OSD_UP: |
1896 |
priv->map_y -= step; |
priv->map_y -= step; |
1897 |
center_coord_update(widget); |
center_coord_update(map); |
1898 |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
1899 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
1900 |
break; |
break; |
1901 |
|
|
1902 |
case OSD_DOWN: |
case OSD_DOWN: |
1903 |
priv->map_y += step; |
priv->map_y += step; |
1904 |
center_coord_update(widget); |
center_coord_update(map); |
1905 |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
1906 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
1907 |
break; |
break; |
1908 |
|
|
1909 |
case OSD_LEFT: |
case OSD_LEFT: |
1910 |
priv->map_x -= step; |
priv->map_x -= step; |
1911 |
center_coord_update(widget); |
center_coord_update(map); |
1912 |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
1913 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
1914 |
break; |
break; |
1915 |
|
|
1916 |
case OSD_RIGHT: |
case OSD_RIGHT: |
1917 |
priv->map_x += step; |
priv->map_x += step; |
1918 |
center_coord_update(widget); |
center_coord_update(map); |
1919 |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); |
1920 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
1921 |
break; |
break; |
1940 |
} |
} |
1941 |
#endif |
#endif |
1942 |
|
|
1943 |
|
priv->button_down = TRUE; |
1944 |
priv->drag_counter = 0; |
priv->drag_counter = 0; |
1945 |
priv->drag_start_mouse_x = (int) event->x; |
priv->drag_start_mouse_x = (int) event->x; |
1946 |
priv->drag_start_mouse_y = (int) event->y; |
priv->drag_start_mouse_y = (int) event->y; |
1953 |
static gboolean |
static gboolean |
1954 |
osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) |
osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) |
1955 |
{ |
{ |
1956 |
|
OsmGpsMap *map = OSM_GPS_MAP(widget); |
1957 |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
1958 |
|
|
1959 |
|
if(!priv->button_down) |
1960 |
|
return FALSE; |
1961 |
|
|
1962 |
if (priv->dragging) |
if (priv->dragging) |
1963 |
{ |
{ |
1964 |
priv->dragging = FALSE; |
priv->dragging = FALSE; |
1969 |
priv->map_x += (priv->drag_start_mouse_x - (int) event->x); |
priv->map_x += (priv->drag_start_mouse_x - (int) event->x); |
1970 |
priv->map_y += (priv->drag_start_mouse_y - (int) event->y); |
priv->map_y += (priv->drag_start_mouse_y - (int) event->y); |
1971 |
|
|
1972 |
center_coord_update(widget); |
center_coord_update(map); |
1973 |
|
|
1974 |
osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw_idle(map); |
1975 |
} |
} |
1976 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
1977 |
/* pressed inside OSD control? */ |
/* pressed inside OSD control? */ |
1984 |
#endif |
#endif |
1985 |
|
|
1986 |
priv->drag_counter = -1; |
priv->drag_counter = -1; |
1987 |
|
priv->button_down = 0; |
1988 |
|
|
1989 |
return FALSE; |
return FALSE; |
1990 |
} |
} |
2009 |
GdkModifierType state; |
GdkModifierType state; |
2010 |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
2011 |
|
|
2012 |
|
if(!priv->button_down) |
2013 |
|
return FALSE; |
2014 |
|
|
2015 |
if (event->is_hint) |
if (event->is_hint) |
2016 |
gdk_window_get_pointer (event->window, &x, &y, &state); |
gdk_window_get_pointer (event->window, &x, &y, &state); |
2017 |
else |
else |
2032 |
if(!priv->drag_counter && |
if(!priv->drag_counter && |
2033 |
( (x - priv->drag_start_mouse_x) * (x - priv->drag_start_mouse_x) + |
( (x - priv->drag_start_mouse_x) * (x - priv->drag_start_mouse_x) + |
2034 |
(y - priv->drag_start_mouse_y) * (y - priv->drag_start_mouse_y) < |
(y - priv->drag_start_mouse_y) * (y - priv->drag_start_mouse_y) < |
2035 |
10*10)) |
priv->drag_limit*priv->drag_limit)) |
2036 |
return FALSE; |
return FALSE; |
2037 |
|
|
2038 |
priv->drag_counter++; |
priv->drag_counter++; |
2101 |
|
|
2102 |
osm_gps_map_map_redraw(OSM_GPS_MAP(widget)); |
osm_gps_map_map_redraw(OSM_GPS_MAP(widget)); |
2103 |
|
|
2104 |
|
g_signal_emit_by_name(widget, "changed"); |
2105 |
|
|
2106 |
return FALSE; |
return FALSE; |
2107 |
} |
} |
2108 |
|
|
2109 |
static gboolean |
static gboolean |
2110 |
osm_gps_map_expose (GtkWidget *widget, GdkEventExpose *event) |
osm_gps_map_expose (GtkWidget *widget, GdkEventExpose *event) |
2111 |
{ |
{ |
2112 |
OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget); |
OsmGpsMap *map = OSM_GPS_MAP(widget); |
2113 |
|
OsmGpsMapPrivate *priv = map->priv; |
2114 |
|
|
2115 |
#if defined(ENABLE_OSD) && defined(OSD_DOUBLE_BUFFER) |
#ifdef OSD_DOUBLE_BUFFER |
2116 |
GdkDrawable *drawable = priv->dbuf_pixmap; |
GdkDrawable *drawable = priv->dbuf_pixmap; |
2117 |
#else |
#else |
2118 |
GdkDrawable *drawable = widget->window; |
GdkDrawable *drawable = widget->window; |
2229 |
widget_class->scroll_event = osm_gps_map_scroll_event; |
widget_class->scroll_event = osm_gps_map_scroll_event; |
2230 |
|
|
2231 |
g_object_class_install_property (object_class, |
g_object_class_install_property (object_class, |
2232 |
|
PROP_DOUBLE_PIXEL, |
2233 |
|
g_param_spec_boolean ("double-pixel", |
2234 |
|
"double pixel", |
2235 |
|
"double map pixels for better readability", |
2236 |
|
FALSE, |
2237 |
|
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); |
2238 |
|
|
2239 |
|
|
2240 |
|
g_object_class_install_property (object_class, |
2241 |
PROP_AUTO_CENTER, |
PROP_AUTO_CENTER, |
2242 |
g_param_spec_boolean ("auto-center", |
g_param_spec_boolean ("auto-center", |
2243 |
"auto center", |
"auto center", |
2290 |
g_param_spec_string ("tile-cache", |
g_param_spec_string ("tile-cache", |
2291 |
"tile cache", |
"tile cache", |
2292 |
"osm local tile cache dir", |
"osm local tile cache dir", |
2293 |
|
OSM_GPS_MAP_CACHE_AUTO, |
2294 |
|
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
2295 |
|
|
2296 |
|
g_object_class_install_property (object_class, |
2297 |
|
PROP_TILE_CACHE_BASE_DIR, |
2298 |
|
g_param_spec_string ("tile-cache-base", |
2299 |
|
"tile cache-base", |
2300 |
|
"base directory to which friendly and auto paths are appended", |
2301 |
NULL, |
NULL, |
2302 |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
2303 |
|
|
2304 |
|
g_object_class_install_property (object_class, |
2305 |
|
PROP_TILE_CACHE_DIR_IS_FULL_PATH, |
2306 |
|
g_param_spec_boolean ("tile-cache-is-full-path", |
2307 |
|
"tile cache is full path", |
2308 |
|
"DEPRECIATED", |
2309 |
|
FALSE, |
2310 |
|
G_PARAM_READABLE | G_PARAM_WRITABLE)); |
2311 |
|
|
2312 |
g_object_class_install_property (object_class, |
g_object_class_install_property (object_class, |
2313 |
PROP_ZOOM, |
PROP_ZOOM, |
2314 |
g_param_spec_int ("zoom", |
g_param_spec_int ("zoom", |
2315 |
"zoom", |
"zoom", |
2316 |
"zoom level", |
"initial zoom level", |
2317 |
MIN_ZOOM, /* minimum property value */ |
MIN_ZOOM, /* minimum property value */ |
2318 |
MAX_ZOOM, /* maximum property value */ |
MAX_ZOOM, /* maximum property value */ |
2319 |
3, |
3, |
2406 |
"radius of the gps point inner circle", |
"radius of the gps point inner circle", |
2407 |
0, /* minimum property value */ |
0, /* minimum property value */ |
2408 |
G_MAXINT, /* maximum property value */ |
G_MAXINT, /* maximum property value */ |
2409 |
10, |
5, |
2410 |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); |
2411 |
|
|
2412 |
g_object_class_install_property (object_class, |
g_object_class_install_property (object_class, |
2424 |
g_param_spec_int ("map-source", |
g_param_spec_int ("map-source", |
2425 |
"map source", |
"map source", |
2426 |
"map source ID", |
"map source ID", |
2427 |
-1, /* minimum property value */ |
-1, /* minimum property value */ |
2428 |
G_MAXINT, /* maximum property value */ |
G_MAXINT, /* maximum property value */ |
2429 |
-1, |
-1, |
2430 |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); |
2436 |
"map source tile repository image format (jpg, png)", |
"map source tile repository image format (jpg, png)", |
2437 |
OSM_IMAGE_FORMAT, |
OSM_IMAGE_FORMAT, |
2438 |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
2439 |
|
|
2440 |
|
g_object_class_install_property (object_class, |
2441 |
|
PROP_DRAG_LIMIT, |
2442 |
|
g_param_spec_int ("drag-limit", |
2443 |
|
"drag limit", |
2444 |
|
"the number of pixels the user has to move the pointer in order to start dragging", |
2445 |
|
0, /* minimum property value */ |
2446 |
|
G_MAXINT, /* maximum property value */ |
2447 |
|
10, |
2448 |
|
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); |
2449 |
|
|
2450 |
|
g_signal_new ("changed", OSM_TYPE_GPS_MAP, |
2451 |
|
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, |
2452 |
|
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); |
2453 |
} |
} |
2454 |
|
|
2455 |
const char* |
const char* |
2463 |
return "OpenStreetMap I"; |
return "OpenStreetMap I"; |
2464 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
2465 |
return "OpenStreetMap II"; |
return "OpenStreetMap II"; |
2466 |
|
case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: |
2467 |
|
return "OpenAerialMap"; |
2468 |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
2469 |
return "OpenCycleMap"; |
return "OpenCycleMap"; |
2470 |
|
case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT: |
2471 |
|
return "Public Transport"; |
2472 |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
2473 |
return "OSMC Trails"; |
return "OSMC Trails"; |
2474 |
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
2491 |
return "Yahoo Satellite"; |
return "Yahoo Satellite"; |
2492 |
case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: |
case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: |
2493 |
return "Yahoo Hybrid"; |
return "Yahoo Hybrid"; |
2494 |
|
case OSM_GPS_MAP_SOURCE_LAST: |
2495 |
default: |
default: |
2496 |
return NULL; |
return NULL; |
2497 |
} |
} |
2511 |
return "none://"; |
return "none://"; |
2512 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
2513 |
return OSM_REPO_URI; |
return OSM_REPO_URI; |
2514 |
|
case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: |
2515 |
|
/* OpenAerialMap is down, offline till furthur notice |
2516 |
|
http://openaerialmap.org/pipermail/talk_openaerialmap.org/2008-December/000055.html */ |
2517 |
|
return NULL; |
2518 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
2519 |
return "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png"; |
return "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png"; |
2520 |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
2521 |
return "http://c.andy.sandbox.cloudmade.com/tiles/cycle/#Z/#X/#Y.png"; |
return "http://c.andy.sandbox.cloudmade.com/tiles/cycle/#Z/#X/#Y.png"; |
2522 |
|
case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT: |
2523 |
|
return "http://tile.xn--pnvkarte-m4a.de/tilegen/#Z/#X/#Y.png"; |
2524 |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
2525 |
return "http://topo.geofabrik.de/trails/#Z/#X/#Y.png"; |
return "http://topo.geofabrik.de/trails/#Z/#X/#Y.png"; |
2526 |
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
2527 |
return "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg"; |
return "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg"; |
2528 |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
2529 |
return "http://mt#R.google.com/vt/v=w2.97&x=#X&y=#Y&z=#Z"; |
return "http://mt#R.google.com/vt/v=w2.97&x=#X&y=#Y&z=#Z"; |
|
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
|
|
return "http://khm#R.google.com/kh?n=404&v=3&t=#Q"; |
|
2530 |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
2531 |
return NULL; /* No longer working "http://mt#R.google.com/mt?n=404&v=w2t.99&x=#X&y=#Y&zoom=#S" */ |
/* No longer working |
2532 |
|
"http://mt#R.google.com/mt?n=404&v=w2t.99&x=#X&y=#Y&zoom=#S" */ |
2533 |
|
return NULL; |
2534 |
|
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
2535 |
|
return "http://khm#R.google.com/kh/v=51&x=#X&y=#Y&z=#Z"; |
2536 |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
2537 |
return "http://a#R.ortho.tiles.virtualearth.net/tiles/r#W.jpeg?g=50"; |
return "http://a#R.ortho.tiles.virtualearth.net/tiles/r#W.jpeg?g=50"; |
2538 |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: |
2549 |
* z = zoom - (MAX_ZOOM - 17)); |
* z = zoom - (MAX_ZOOM - 17)); |
2550 |
*/ |
*/ |
2551 |
return NULL; |
return NULL; |
2552 |
|
case OSM_GPS_MAP_SOURCE_LAST: |
2553 |
default: |
default: |
2554 |
return NULL; |
return NULL; |
2555 |
} |
} |
2564 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
2565 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
2566 |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
2567 |
|
case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT: |
2568 |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
case OSM_GPS_MAP_SOURCE_OSMC_TRAILS: |
2569 |
return "png"; |
return "png"; |
2570 |
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: |
2571 |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
|
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
|
2572 |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
2573 |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
2574 |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: |
2576 |
case OSM_GPS_MAP_SOURCE_YAHOO_STREET: |
case OSM_GPS_MAP_SOURCE_YAHOO_STREET: |
2577 |
case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: |
case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: |
2578 |
case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: |
case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: |
2579 |
|
case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: |
2580 |
|
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
2581 |
return "jpg"; |
return "jpg"; |
2582 |
|
case OSM_GPS_MAP_SOURCE_LAST: |
2583 |
default: |
default: |
2584 |
return "bin"; |
return "bin"; |
2585 |
} |
} |
2601 |
return 18; |
return 18; |
2602 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: |
2603 |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP: |
2604 |
|
case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT: |
2605 |
return OSM_MAX_ZOOM; |
return OSM_MAX_ZOOM; |
2606 |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: |
2607 |
|
case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: |
2608 |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: |
2609 |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: |
2610 |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: |
2620 |
return 11; |
return 11; |
2621 |
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: |
2622 |
return 18; |
return 18; |
2623 |
|
case OSM_GPS_MAP_SOURCE_LAST: |
2624 |
default: |
default: |
2625 |
return 17; |
return 17; |
2626 |
} |
} |
2627 |
return 17; |
return 17; |
2628 |
} |
} |
2629 |
|
|
2630 |
|
gboolean |
2631 |
|
osm_gps_map_source_is_valid(OsmGpsMapSource_t source) |
2632 |
|
{ |
2633 |
|
return osm_gps_map_source_get_repo_uri(source) != NULL; |
2634 |
|
} |
2635 |
|
|
2636 |
void |
void |
2637 |
osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_start, int zoom_end) |
osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_start, int zoom_end) |
2638 |
{ |
{ |
2669 |
i, G_DIR_SEPARATOR, |
i, G_DIR_SEPARATOR, |
2670 |
j, |
j, |
2671 |
priv->image_format); |
priv->image_format); |
2672 |
if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
|
2673 |
|
if ((!g_file_test(filename, G_FILE_TEST_EXISTS)) || |
2674 |
|
osm_gps_map_tile_age_exceeded(filename)) |
2675 |
{ |
{ |
2676 |
osm_gps_map_download_tile(map, zoom, i, j, FALSE); |
osm_gps_map_download_tile(map, zoom, i, j, FALSE); |
2677 |
num_tiles++; |
num_tiles++; |
2678 |
} |
} |
2679 |
|
|
2680 |
g_free(filename); |
g_free(filename); |
2681 |
} |
} |
2682 |
} |
} |
2716 |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
2717 |
priv = map->priv; |
priv = map->priv; |
2718 |
|
|
2719 |
|
g_object_set(G_OBJECT(map), "auto-center", FALSE, NULL); |
2720 |
|
|
2721 |
priv->center_rlat = deg2rad(latitude); |
priv->center_rlat = deg2rad(latitude); |
2722 |
priv->center_rlon = deg2rad(longitude); |
priv->center_rlon = deg2rad(longitude); |
2723 |
|
|
2729 |
priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2; |
priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2; |
2730 |
|
|
2731 |
osm_gps_map_map_redraw_idle(map); |
osm_gps_map_map_redraw_idle(map); |
2732 |
|
|
2733 |
|
g_signal_emit_by_name(map, "changed"); |
2734 |
} |
} |
2735 |
|
|
2736 |
int |
int |
2756 |
priv->map_x = lon2pixel(priv->map_zoom, priv->center_rlon) - width_center; |
priv->map_x = lon2pixel(priv->map_zoom, priv->center_rlon) - width_center; |
2757 |
priv->map_y = lat2pixel(priv->map_zoom, priv->center_rlat) - height_center; |
priv->map_y = lat2pixel(priv->map_zoom, priv->center_rlat) - height_center; |
2758 |
|
|
2759 |
|
factor = pow(2, priv->map_zoom-zoom_old); |
2760 |
g_debug("Zoom changed from %d to %d factor:%f x:%d", |
g_debug("Zoom changed from %d to %d factor:%f x:%d", |
2761 |
zoom_old, priv->map_zoom, factor, priv->map_x); |
zoom_old, priv->map_zoom, factor, priv->map_x); |
2762 |
|
|
2763 |
|
/* adjust gps precision indicator */ |
2764 |
|
priv->ui_gps_point_outer_radius *= factor; |
2765 |
|
|
2766 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
2767 |
/* OSD may contain a scale, so we may have to re-render it */ |
/* OSD may contain a scale, so we may have to re-render it */ |
2768 |
if(priv->osd && OSM_IS_GPS_MAP (priv->osd->widget)) |
if(priv->osd && OSM_IS_GPS_MAP (priv->osd->widget)) |
2770 |
#endif |
#endif |
2771 |
|
|
2772 |
osm_gps_map_map_redraw_idle(map); |
osm_gps_map_map_redraw_idle(map); |
2773 |
|
|
2774 |
|
g_signal_emit_by_name(map, "changed"); |
2775 |
} |
} |
2776 |
return priv->map_zoom; |
return priv->map_zoom; |
2777 |
} |
} |
2778 |
|
|
2779 |
|
int |
2780 |
|
osm_gps_map_zoom_in (OsmGpsMap *map) |
2781 |
|
{ |
2782 |
|
g_return_val_if_fail (OSM_IS_GPS_MAP (map), 0); |
2783 |
|
return osm_gps_map_set_zoom(map, map->priv->map_zoom+1); |
2784 |
|
} |
2785 |
|
|
2786 |
|
int |
2787 |
|
osm_gps_map_zoom_out (OsmGpsMap *map) |
2788 |
|
{ |
2789 |
|
g_return_val_if_fail (OSM_IS_GPS_MAP (map), 0); |
2790 |
|
return osm_gps_map_set_zoom(map, map->priv->map_zoom-1); |
2791 |
|
} |
2792 |
|
|
2793 |
void |
void |
2794 |
osm_gps_map_add_track (OsmGpsMap *map, GSList *track) |
osm_gps_map_add_track (OsmGpsMap *map, GSList *track) |
2795 |
{ |
{ |
2805 |
} |
} |
2806 |
|
|
2807 |
void |
void |
2808 |
|
osm_gps_map_replace_track (OsmGpsMap *map, GSList *old_track, GSList *new_track) |
2809 |
|
{ |
2810 |
|
OsmGpsMapPrivate *priv; |
2811 |
|
|
2812 |
|
if(!old_track) { |
2813 |
|
osm_gps_map_add_track (map, new_track); |
2814 |
|
return; |
2815 |
|
} |
2816 |
|
|
2817 |
|
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
2818 |
|
priv = map->priv; |
2819 |
|
|
2820 |
|
GSList *old = g_slist_find(priv->tracks, old_track); |
2821 |
|
if(!old) { |
2822 |
|
g_warning("track to be replaced not found"); |
2823 |
|
return; |
2824 |
|
} |
2825 |
|
|
2826 |
|
old->data = new_track; |
2827 |
|
osm_gps_map_map_redraw_idle(map); |
2828 |
|
} |
2829 |
|
|
2830 |
|
void |
2831 |
osm_gps_map_clear_tracks (OsmGpsMap *map) |
osm_gps_map_clear_tracks (OsmGpsMap *map) |
2832 |
{ |
{ |
2833 |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
2837 |
} |
} |
2838 |
|
|
2839 |
void |
void |
2840 |
osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image) |
osm_gps_map_add_image_with_alignment (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign) |
2841 |
{ |
{ |
2842 |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
2843 |
|
|
2852 |
im->pt.rlat = deg2rad(latitude); |
im->pt.rlat = deg2rad(latitude); |
2853 |
im->pt.rlon = deg2rad(longitude); |
im->pt.rlon = deg2rad(longitude); |
2854 |
|
|
2855 |
|
//handle alignment |
2856 |
|
im->xoffset = xalign * im->w; |
2857 |
|
im->yoffset = yalign * im->h; |
2858 |
|
|
2859 |
g_object_ref(image); |
g_object_ref(image); |
2860 |
im->image = image; |
im->image = image; |
2861 |
|
|
2865 |
} |
} |
2866 |
} |
} |
2867 |
|
|
2868 |
|
void |
2869 |
|
osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image) |
2870 |
|
{ |
2871 |
|
osm_gps_map_add_image_with_alignment (map, latitude, longitude, image, 0.5, 0.5); |
2872 |
|
} |
2873 |
|
|
2874 |
gboolean |
gboolean |
2875 |
osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image) |
osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image) |
2876 |
{ |
{ |
2945 |
|
|
2946 |
priv->map_x = pixel_x - GTK_WIDGET(map)->allocation.width/2; |
priv->map_x = pixel_x - GTK_WIDGET(map)->allocation.width/2; |
2947 |
priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2; |
priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2; |
2948 |
center_coord_update(GTK_WIDGET(map)); |
center_coord_update(map); |
2949 |
} |
} |
2950 |
} |
} |
2951 |
|
|
3004 |
priv = map->priv; |
priv = map->priv; |
3005 |
|
|
3006 |
if (pixel_x) |
if (pixel_x) |
3007 |
*pixel_x = lon2pixel(priv->map_zoom, deg2rad(longitude)) - |
*pixel_x = lon2pixel(priv->map_zoom, deg2rad(longitude)) - |
3008 |
priv->map_x + priv->drag_mouse_dx; |
priv->map_x + priv->drag_mouse_dx; |
3009 |
if (pixel_y) |
if (pixel_y) |
3010 |
*pixel_y = lat2pixel(priv->map_zoom, deg2rad(latitude)) - |
*pixel_y = lat2pixel(priv->map_zoom, deg2rad(latitude)) - |
3011 |
priv->map_y + priv->drag_mouse_dy; |
priv->map_y + priv->drag_mouse_dy; |
3012 |
} |
} |
3013 |
|
|
3021 |
|
|
3022 |
priv->map_x += dx; |
priv->map_x += dx; |
3023 |
priv->map_y += dy; |
priv->map_y += dy; |
3024 |
center_coord_update(GTK_WIDGET(map)); |
center_coord_update(map); |
3025 |
|
|
3026 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
3027 |
/* OSD may contain a coordinate, so we may have to re-render it */ |
/* OSD may contain a coordinate, so we may have to re-render it */ |
3043 |
return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon); |
return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon); |
3044 |
} |
} |
3045 |
|
|
3046 |
|
char * osm_gps_map_get_default_cache_directory(void) |
3047 |
|
{ |
3048 |
|
return g_build_filename( |
3049 |
|
g_get_user_cache_dir(), |
3050 |
|
"osmgpsmap", |
3051 |
|
NULL); |
3052 |
|
} |
3053 |
|
|
3054 |
|
void osm_gps_map_set_keyboard_shortcut(OsmGpsMap *map, OsmGpsMapKey_t key, guint keyval) |
3055 |
|
{ |
3056 |
|
g_return_if_fail (OSM_IS_GPS_MAP (map)); |
3057 |
|
g_return_if_fail(key < OSM_GPS_MAP_KEY_MAX); |
3058 |
|
|
3059 |
|
map->priv->keybindings[key] = keyval; |
3060 |
|
map->priv->keybindings_enabled = TRUE; |
3061 |
|
} |
3062 |
|
|
3063 |
#ifdef ENABLE_OSD |
#ifdef ENABLE_OSD |
3064 |
|
|
3065 |
void |
void |