Diff of /trunk/src/osm-gps-map.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 279 by harbaum, Sat Dec 12 12:54:37 2009 UTC revision 280 by harbaum, Fri May 21 19:28:16 2010 UTC
# Line 4  Line 4 
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"
# Line 36  Line 36 
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
# Line 98  struct _OsmGpsMapPrivate Line 80  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
# Line 124  struct _OsmGpsMapPrivate Line 107  struct _OsmGpsMapPrivate
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;
# Line 149  struct _OsmGpsMapPrivate Line 127  struct _OsmGpsMapPrivate
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
# Line 156  struct _OsmGpsMapPrivate Line 135  struct _OsmGpsMapPrivate
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)
# Line 174  enum Line 160  enum
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,
# Line 181  enum Line 168  enum
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,
# Line 193  enum Line 182  enum
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);
# Line 207  static gchar    *replace_map_uri(OsmGpsM Line 197  static gchar    *replace_map_uri(OsmGpsM
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);
# Line 551  osm_gps_map_print_images (OsmGpsMap *map Line 541  osm_gps_map_print_images (OsmGpsMap *map
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    
# Line 585  osm_gps_map_draw_gps_point (OsmGpsMap *m Line 575  osm_gps_map_draw_gps_point (OsmGpsMap *m
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
# Line 639  osm_gps_map_draw_gps_point (OsmGpsMap *m Line 623  osm_gps_map_draw_gps_point (OsmGpsMap *m
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)
# Line 710  osm_gps_map_blit_tile(OsmGpsMap *map, Gd Line 681  osm_gps_map_blit_tile(OsmGpsMap *map, Gd
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
# Line 826  osm_gps_map_tile_download_complete (Soup Line 797  osm_gps_map_tile_download_complete (Soup
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);
# Line 848  osm_gps_map_download_tile (OsmGpsMap *ma Line 819  osm_gps_map_download_tile (OsmGpsMap *ma
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    
# Line 892  osm_gps_map_download_tile (OsmGpsMap *ma Line 863  osm_gps_map_download_tile (OsmGpsMap *ma
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
# Line 938  osm_gps_map_load_cached_tile (OsmGpsMap Line 909  osm_gps_map_load_cached_tile (OsmGpsMap
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 */
# Line 1005  osm_gps_map_render_missing_tile (OsmGpsM Line 980  osm_gps_map_render_missing_tile (OsmGpsM
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    
# Line 1026  osm_gps_map_load_tile (OsmGpsMap *map, i Line 1017  osm_gps_map_load_tile (OsmGpsMap *map, i
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      {      {
# Line 1036  osm_gps_map_load_tile (OsmGpsMap *map, i Line 1032  osm_gps_map_load_tile (OsmGpsMap *map, i
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);
# Line 1078  osm_gps_map_fill_tiles_pixel (OsmGpsMap Line 1072  osm_gps_map_fill_tiles_pixel (OsmGpsMap
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    
# Line 1132  osm_gps_map_print_track (OsmGpsMap *map, Line 1173  osm_gps_map_print_track (OsmGpsMap *map,
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;
# Line 1166  osm_gps_map_print_track (OsmGpsMap *map, Line 1192  osm_gps_map_print_track (OsmGpsMap *map,
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);
# Line 1195  osm_gps_map_print_track (OsmGpsMap *map, Line 1210  osm_gps_map_print_track (OsmGpsMap *map,
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 */
# Line 1318  osm_gps_map_map_redraw_idle (OsmGpsMap * Line 1329  osm_gps_map_map_redraw_idle (OsmGpsMap *
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;
# Line 1327  center_coord_update(GtkWidget *widget) { Line 1340  center_coord_update(GtkWidget *widget) {
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);
# Line 1427  osm_gps_map_init (OsmGpsMap *object) Line 1436  osm_gps_map_init (OsmGpsMap *object)
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    
# Line 1446  osm_gps_map_init (OsmGpsMap *object) Line 1450  osm_gps_map_init (OsmGpsMap *object)
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);
# Line 1476  osm_gps_map_init (OsmGpsMap *object) Line 1486  osm_gps_map_init (OsmGpsMap *object)
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");
# Line 1510  osm_gps_map_setup(OsmGpsMapPrivate *priv Line 1539  osm_gps_map_setup(OsmGpsMapPrivate *priv
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 *
# Line 1552  osm_gps_map_dispose (GObject *object) Line 1597  osm_gps_map_dispose (GObject *object)
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)
# Line 1572  osm_gps_map_dispose (GObject *object) Line 1618  osm_gps_map_dispose (GObject *object)
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)
# Line 1590  osm_gps_map_finalize (GObject *object) Line 1638  osm_gps_map_finalize (GObject *object)
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    
# Line 1617  osm_gps_map_set_property (GObject *objec Line 1666  osm_gps_map_set_property (GObject *objec
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;
# Line 1634  osm_gps_map_set_property (GObject *objec Line 1687  osm_gps_map_set_property (GObject *objec
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;
# Line 1665  osm_gps_map_set_property (GObject *objec Line 1721  osm_gps_map_set_property (GObject *objec
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);
# Line 1708  osm_gps_map_set_property (GObject *objec Line 1764  osm_gps_map_set_property (GObject *objec
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;
# Line 1718  static void Line 1777  static void
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;
# Line 1745  osm_gps_map_get_property (GObject *objec Line 1806  osm_gps_map_get_property (GObject *objec
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;
# Line 1755  osm_gps_map_get_property (GObject *objec Line 1822  osm_gps_map_get_property (GObject *objec
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);
# Line 1788  osm_gps_map_get_property (GObject *objec Line 1851  osm_gps_map_get_property (GObject *objec
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;
# Line 1798  static gboolean Line 1864  static gboolean
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  }  }
# Line 1815  osm_gps_map_scroll_event (GtkWidget *wid Line 1876  osm_gps_map_scroll_event (GtkWidget *wid
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? */
# Line 1832  osm_gps_map_button_press (GtkWidget *wid Line 1894  osm_gps_map_button_press (GtkWidget *wid
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;
# Line 1878  osm_gps_map_button_press (GtkWidget *wid Line 1940  osm_gps_map_button_press (GtkWidget *wid
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;
# Line 1890  osm_gps_map_button_press (GtkWidget *wid Line 1953  osm_gps_map_button_press (GtkWidget *wid
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;
# Line 1902  osm_gps_map_button_release (GtkWidget *w Line 1969  osm_gps_map_button_release (GtkWidget *w
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? */
# Line 1917  osm_gps_map_button_release (GtkWidget *w Line 1984  osm_gps_map_button_release (GtkWidget *w
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  }  }
# Line 1941  osm_gps_map_motion_notify (GtkWidget *wi Line 2009  osm_gps_map_motion_notify (GtkWidget *wi
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
# Line 1961  osm_gps_map_motion_notify (GtkWidget *wi Line 2032  osm_gps_map_motion_notify (GtkWidget *wi
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++;
# Line 2030  osm_gps_map_configure (GtkWidget *widget Line 2101  osm_gps_map_configure (GtkWidget *widget
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;
# Line 2155  osm_gps_map_class_init (OsmGpsMapClass * Line 2229  osm_gps_map_class_init (OsmGpsMapClass *
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",
# Line 2207  osm_gps_map_class_init (OsmGpsMapClass * Line 2290  osm_gps_map_class_init (OsmGpsMapClass *
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,
# Line 2307  osm_gps_map_class_init (OsmGpsMapClass * Line 2406  osm_gps_map_class_init (OsmGpsMapClass *
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,
# Line 2325  osm_gps_map_class_init (OsmGpsMapClass * Line 2424  osm_gps_map_class_init (OsmGpsMapClass *
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));
# Line 2337  osm_gps_map_class_init (OsmGpsMapClass * Line 2436  osm_gps_map_class_init (OsmGpsMapClass *
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*
# Line 2350  osm_gps_map_source_get_friendly_name(Osm Line 2463  osm_gps_map_source_get_friendly_name(Osm
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:
# Line 2374  osm_gps_map_source_get_friendly_name(Osm Line 2491  osm_gps_map_source_get_friendly_name(Osm
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      }      }
# Line 2393  osm_gps_map_source_get_repo_uri(OsmGpsMa Line 2511  osm_gps_map_source_get_repo_uri(OsmGpsMa
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:
# Line 2423  osm_gps_map_source_get_repo_uri(OsmGpsMa Line 2549  osm_gps_map_source_get_repo_uri(OsmGpsMa
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      }      }
# Line 2437  osm_gps_map_source_get_image_format(OsmG Line 2564  osm_gps_map_source_get_image_format(OsmG
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:
# Line 2449  osm_gps_map_source_get_image_format(OsmG Line 2576  osm_gps_map_source_get_image_format(OsmG
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      }      }
# Line 2471  osm_gps_map_source_get_max_zoom(OsmGpsMa Line 2601  osm_gps_map_source_get_max_zoom(OsmGpsMa
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:
# Line 2488  osm_gps_map_source_get_max_zoom(OsmGpsMa Line 2620  osm_gps_map_source_get_max_zoom(OsmGpsMa
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  {  {
# Line 2530  osm_gps_map_download_maps (OsmGpsMap *ma Line 2669  osm_gps_map_download_maps (OsmGpsMap *ma
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              }              }
# Line 2574  osm_gps_map_set_center (OsmGpsMap *map, Line 2716  osm_gps_map_set_center (OsmGpsMap *map,
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    
# Line 2585  osm_gps_map_set_center (OsmGpsMap *map, Line 2729  osm_gps_map_set_center (OsmGpsMap *map,
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
# Line 2610  osm_gps_map_set_zoom (OsmGpsMap *map, in Line 2756  osm_gps_map_set_zoom (OsmGpsMap *map, in
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))
# Line 2620  osm_gps_map_set_zoom (OsmGpsMap *map, in Line 2770  osm_gps_map_set_zoom (OsmGpsMap *map, in
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  {  {
# Line 2639  osm_gps_map_add_track (OsmGpsMap *map, G Line 2805  osm_gps_map_add_track (OsmGpsMap *map, G
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));
# Line 2648  osm_gps_map_clear_tracks (OsmGpsMap *map Line 2837  osm_gps_map_clear_tracks (OsmGpsMap *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    
# Line 2663  osm_gps_map_add_image (OsmGpsMap *map, f Line 2852  osm_gps_map_add_image (OsmGpsMap *map, f
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    
# Line 2672  osm_gps_map_add_image (OsmGpsMap *map, f Line 2865  osm_gps_map_add_image (OsmGpsMap *map, f
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  {  {
# Line 2746  osm_gps_map_draw_gps (OsmGpsMap *map, fl Line 2945  osm_gps_map_draw_gps (OsmGpsMap *map, fl
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    
# Line 2805  osm_gps_map_geographic_to_screen (OsmGps Line 3004  osm_gps_map_geographic_to_screen (OsmGps
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    
# Line 2822  osm_gps_map_scroll (OsmGpsMap *map, gint Line 3021  osm_gps_map_scroll (OsmGpsMap *map, gint
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 */
# Line 2844  osm_gps_map_get_scale(OsmGpsMap *map) Line 3043  osm_gps_map_get_scale(OsmGpsMap *map)
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

Legend:
Removed from v.279  
changed lines
  Added in v.280