]> git.street.me.uk Git - andy/viking.git/commitdiff
Merge branch 'new-maps'
authorGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Tue, 12 Jan 2010 23:14:07 +0000 (00:14 +0100)
committerGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Tue, 12 Jan 2010 23:14:07 +0000 (00:14 +0100)
This (long lived) branch hosted a feature to allow automatic download
after a HTTP header check.

The merge is complex as Map_Type evolved to a GObject MapSource.
VikSlippyMapSource now has a new property to set the minimum age
before checking tiles.

1  2 
configure.ac
src/babel.c
src/geonamessearch.c
src/googlesearch.c
src/osm.c
src/vikdemlayer.c
src/vikgototool.c
src/vikmapslayer.c
src/vikmapsource.c
src/vikmapsource.h
src/vikslippymapsource.c

diff --cc configure.ac
Simple merge
diff --cc src/babel.c
Simple merge
Simple merge
index f9cb614c12de0ebd92fe881ac5f7b08764cf4af9,f7dd793d87f284b0cd26892ac44e07e1601c5379..bf98f64ab3cc445d0bd29764914f219cce3de5e7
  #include "util.h"
  #include "curl_download.h"
  
 -#define GOOGLE_SEARCH_URL_FMT "http://maps.google.com/maps?q=%s&output=js"
 -#define GOOGLE_SEARCH_PATTERN_1 "{center:{lat:"
 -#define GOOGLE_SEARCH_PATTERN_2 ",lng:"
 -#define GOOGLE_SEARCH_NOT_FOUND "not understand the location"
 +#include "googlesearch.h"
  
 -static gchar *last_search_str = NULL;
 -static VikCoord *last_coord = NULL;
 -static gchar *last_successful_search_str = NULL;
 +#define GOOGLE_GOTO_URL_FMT "http://maps.google.com/maps?q=%s&output=js"
 +#define GOOGLE_GOTO_PATTERN_1 "{center:{lat:"
 +#define GOOGLE_GOTO_PATTERN_2 ",lng:"
 +#define GOOGLE_GOTO_NOT_FOUND "not understand the location"
  
- static DownloadOptions googlesearch_options = { "http://maps.google.com/", 0, a_check_map_file };
+ static DownloadOptions googlesearch_options = { 0, "http://maps.google.com/", 0, a_check_map_file };
  
 -gchar * a_googlesearch_get_search_string_for_this_place(VikWindow *vw)
 -{
 -  if (!last_coord)
 -    return NULL;
 -
 -  VikViewport *vvp = vik_window_viewport(vw);
 -  const VikCoord *cur_center = vik_viewport_get_center(vvp);
 -  if (vik_coord_equals(cur_center, last_coord)) {
 -    return(last_successful_search_str);
 -  }
 -  else
 -    return NULL;
 -}
 -
 -static gboolean prompt_try_again(VikWindow *vw)
 -{
 -  GtkWidget *dialog = NULL;
 -  gboolean ret = TRUE;
 +static void google_goto_tool_class_init ( GoogleGotoToolClass *klass );
 +static void google_goto_tool_init ( GoogleGotoTool *vwd );
  
 -  dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL );
 -  gtk_window_set_title(GTK_WINDOW(dialog), _("Search"));
 +static void google_goto_tool_finalize ( GObject *gob );
  
 -  GtkWidget *search_label = gtk_label_new(_("I don't know that place. Do you want another search?"));
 -  gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), search_label, FALSE, FALSE, 5 );
 -  gtk_widget_show_all(dialog);
 +static gchar *google_goto_tool_get_url_format ( VikGotoTool *self );
 +static DownloadOptions *google_goto_tool_get_download_options ( VikGotoTool *self );
 +static gboolean google_goto_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll);
  
 -  if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT )
 -    ret = FALSE;
 +GType google_goto_tool_get_type()
 +{
 +  static GType w_type = 0;
 +
 +  if (!w_type)
 +  {
 +    static const GTypeInfo w_info = 
 +    {
 +      sizeof (GoogleGotoToolClass),
 +      NULL, /* base_init */
 +      NULL, /* base_finalize */
 +      (GClassInitFunc) google_goto_tool_class_init,
 +      NULL, /* class_finalize */
 +      NULL, /* class_data */
 +      sizeof (GoogleGotoTool),
 +      0,
 +      (GInstanceInitFunc) google_goto_tool_init,
 +    };
 +    w_type = g_type_register_static ( VIK_GOTO_TOOL_TYPE, "GoogleGotoTool", &w_info, 0 );
 +  }
  
 -  gtk_widget_destroy(dialog);
 -  return ret;
 +  return w_type;
  }
  
 -static gchar *  a_prompt_for_search_string(VikWindow *vw)
 +static void google_goto_tool_class_init ( GoogleGotoToolClass *klass )
  {
 -  GtkWidget *dialog = NULL;
 +  GObjectClass *object_class;
 +  VikGotoToolClass *parent_class;
  
 -  dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL );
 -  gtk_window_set_title(GTK_WINDOW(dialog), _("Search"));
 +  object_class = G_OBJECT_CLASS (klass);
  
 -  GtkWidget *search_label = gtk_label_new(_("Enter address or place name:"));
 -  GtkWidget *search_entry = gtk_entry_new();
 -  if (last_search_str)
 -    gtk_entry_set_text(GTK_ENTRY(search_entry), last_search_str);
 +  object_class->finalize = google_goto_tool_finalize;
  
 -  gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), search_label, FALSE, FALSE, 5 );
 -  gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), search_entry, FALSE, FALSE, 5 );
 -  gtk_widget_show_all(dialog);
 -
 -  if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT ) {
 -    gtk_widget_destroy(dialog);
 -    return NULL;
 -  }
 +  parent_class = VIK_GOTO_TOOL_CLASS (klass);
  
 -  gchar *search_str = g_strdup ( gtk_entry_get_text ( GTK_ENTRY(search_entry) ) );
 +  parent_class->get_url_format = google_goto_tool_get_url_format;
 +  parent_class->get_download_options = google_goto_tool_get_download_options;
 +  parent_class->parse_file_for_latlon = google_goto_tool_parse_file_for_latlon;
 +}
  
 -  gtk_widget_destroy(dialog);
 +GoogleGotoTool *google_goto_tool_new ()
 +{
 +  return GOOGLE_GOTO_TOOL ( g_object_new ( GOOGLE_GOTO_TOOL_TYPE, "label", "Google", NULL ) );
 +}
  
 -  if (search_str[0] != '\0') {
 -    if (last_search_str)
 -      g_free(last_search_str);
 -    last_search_str = g_strdup(search_str);
 -  }
 +static void google_goto_tool_init ( GoogleGotoTool *vlp )
 +{
 +}
  
 -  return(search_str);   /* search_str needs to be freed by caller */
 +static void google_goto_tool_finalize ( GObject *gob )
 +{
 +  G_OBJECT_GET_CLASS(gob)->finalize(gob);
  }
  
 -static gboolean parse_file_for_latlon(gchar *file_name, struct LatLon *ll)
 +static gboolean google_goto_tool_parse_file_for_latlon(VikGotoTool *self, gchar *file_name, struct LatLon *ll)
  {
    gchar *text, *pat;
    GMappedFile *mf;
diff --cc src/osm.c
index 50bc7bcd667107a13de1cbe68ae5ef563b6d1ee5,5495c320f5d95ee29d33a70d6c8b61f16550b3bd..e00dd41ff3aa7141fc8352de8b90a24f98f9504a
+++ b/src/osm.c
  
  /* initialisation */
  void osm_init () {
-   VikMapSource *osmarender_type = VIK_MAP_SOURCE(vik_slippy_map_source_new_with_id(12, "OpenStreetMap (Osmarender)", "tah.openstreetmap.org", "/Tiles/tile/%d/%d/%d.png"));
-   VikMapSource *mapnik_type = VIK_MAP_SOURCE(vik_slippy_map_source_new_with_id( 13, "OpenStreetMap (Mapnik)", "tile.openstreetmap.org", "/%d/%d/%d.png"));
-   VikMapSource *maplint_type = VIK_MAP_SOURCE(vik_slippy_map_source_new_with_id( 14, "OpenStreetMap (Maplint)", "tah.openstreetmap.org", "/Tiles/maplint.php/%d/%d/%d.png"));
-   VikMapSource *cycle_type = VIK_MAP_SOURCE(vik_slippy_map_source_new_with_id( 17, "OpenStreetMap (Cycle)", "thunderflames.org/tiles/cycle/", "%d/%d/%d.png" ));
 -  VikMapsLayer_MapType osmarender_type = { 12, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_osmarender_download, &osm_options };
 -  VikMapsLayer_MapType mapnik_type = { 13, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_mapnik_download, &osm_options };
 -  VikMapsLayer_MapType maplint_type = { 14, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_maplint_download, &osm_options };
 -  VikMapsLayer_MapType cycle_type = { 17, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, osm_cycle_download, &osm_options };
 -
 -#ifdef VIK_CONFIG_BLUEMARBLE
 -  VikMapsLayer_MapType bluemarble_type = { 15, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, bluemarble_download, &osm_options };
 -#endif
 -
 -#ifdef VIK_CONFIG_OPENAERIAL
 -  VikMapsLayer_MapType openaerialmap_type = { 20, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, osm_coord_to_mapcoord, osm_mapcoord_to_center_coord, openaerialmap_download, &osm_options };
 -#endif
 -
 -  maps_layer_register_type("OpenStreetMap (Osmarender)", 12, &osmarender_type);
 -  maps_layer_register_type("OpenStreetMap (Mapnik)", 13, &mapnik_type);
 -  maps_layer_register_type("OpenStreetMap (Maplint)", 14, &maplint_type);
 -  maps_layer_register_type("OpenStreetMap (Cycle)", 17, &cycle_type);
 -
 -#ifdef VIK_CONFIG_BLUEMARBLE
 -  maps_layer_register_type("BlueMarble", 15, &bluemarble_type);
 -#endif
 -#ifdef VIK_CONFIG_OPENAERIAL
 -  maps_layer_register_type("OpenAerialMap", 20, &openaerialmap_type);
 -#endif
++  VikMapSource *osmarender_type = 
++    VIK_MAP_SOURCE(g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
++                                "id", 12,
++                                "label", "OpenStreetMap (Osmarender)",
++                                "hostname", "tah.openstreetmap.org",
++                                "url", "/Tiles/tile/%d/%d/%d.png",
++                                "check-file-server-time", VIK_CONFIG_DEFAULT_TILE_AGE,
++                                NULL));
++  VikMapSource *mapnik_type =
++    VIK_MAP_SOURCE(g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
++                                "id", 13,
++                                "label", "OpenStreetMap (Mapnik)",
++                                "hostname", "tile.openstreetmap.org",
++                                "url", "/%d/%d/%d.png",
++                                "check-file-server-time", VIK_CONFIG_DEFAULT_TILE_AGE,
++                                NULL));
++  VikMapSource *maplint_type =
++    VIK_MAP_SOURCE(g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
++                                "id", 14,
++                                "label", "OpenStreetMap (Maplint)",
++                                "hostname", "tah.openstreetmap.org",
++                                "url", "/Tiles/maplint.php/%d/%d/%d.png",
++                                "check-file-server-time", VIK_CONFIG_DEFAULT_TILE_AGE,
++                                NULL));
++  VikMapSource *cycle_type =
++    VIK_MAP_SOURCE(g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
++                                "id", 17,
++                                "label", "OpenStreetMap (Cycle)",
++                                "hostname", "thunderflames.org/tiles/cycle/",
++                                "url", "%d/%d/%d.png",
++                                "check-file-server-time", VIK_CONFIG_DEFAULT_TILE_AGE,
++                                NULL));
 +
 +  maps_layer_register_map_source (osmarender_type);
 +  maps_layer_register_map_source (mapnik_type);
 +  maps_layer_register_map_source (maplint_type);
 +  maps_layer_register_map_source (cycle_type);
  
    // Webtools
    VikWebtoolCenter *webtool = NULL;
Simple merge
index 4ed2dfeed227916ba2124ed788a18af6ed378b20,0000000000000000000000000000000000000000..81f18b4291854598ca79332db245d77afbff2886
mode 100644,000000..100644
--- /dev/null
@@@ -1,280 -1,0 +1,280 @@@
-   if (curl_download_uri(uri, tmp_file, vik_goto_tool_get_download_options(self))) {  /* error */
 +/*
 + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
 + *
 + * Copyright (C) 2009, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + *
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include "vikgototool.h"
 +#include "util.h"
 +#include "curl_download.h"
 +
 +#include <string.h>
 +
 +#include <glib.h>
 +#include <glib/gi18n.h>
 +#include <glib/gstdio.h>
 +
 +static void goto_tool_class_init ( VikGotoToolClass *klass );
 +static void goto_tool_init ( VikGotoTool *vlp );
 +
 +static GObjectClass *parent_class;
 +
 +static void goto_tool_finalize ( GObject *gob );
 +static gchar *goto_tool_get_label ( VikGotoTool *vw );
 +static DownloadOptions *goto_tool_get_download_options ( VikGotoTool *self );
 +
 +typedef struct _VikGotoToolPrivate VikGotoToolPrivate;
 +
 +struct _VikGotoToolPrivate
 +{
 +  gint   id;
 +  gchar *label;
 +};
 +
 +#define GOTO_TOOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
 +                                    VIK_GOTO_TOOL_TYPE,          \
 +                                    VikGotoToolPrivate))
 +
 +GType vik_goto_tool_get_type()
 +{
 +  static GType w_type = 0;
 +
 +  if (!w_type)
 +  {
 +    static const GTypeInfo w_info = 
 +    {
 +      sizeof (VikGotoToolClass),
 +      NULL, /* base_init */
 +      NULL, /* base_finalize */
 +      (GClassInitFunc) goto_tool_class_init,
 +      NULL, /* class_finalize */
 +      NULL, /* class_data */
 +      sizeof (VikGotoTool),
 +      0,
 +      (GInstanceInitFunc) goto_tool_init,
 +    };
 +    w_type = g_type_register_static ( G_TYPE_OBJECT, "VikGotoTool", &w_info, G_TYPE_FLAG_ABSTRACT );
 +  }
 +
 +  return w_type;
 +}
 +
 +enum
 +{
 +  PROP_0,
 +
 +  PROP_ID,
 +  PROP_LABEL,
 +};
 +
 +static void
 +goto_tool_set_property (GObject      *object,
 +                          guint         property_id,
 +                          const GValue *value,
 +                          GParamSpec   *pspec)
 +{
 +  VikGotoTool *self = VIK_GOTO_TOOL (object);
 +  VikGotoToolPrivate *priv = GOTO_TOOL_GET_PRIVATE (self);
 +
 +  switch (property_id)
 +    {
 +    case PROP_ID:
 +      priv->id = g_value_get_uint (value);
 +      g_debug ("VikGotoTool.id: %d", priv->id);
 +      break;
 +
 +    case PROP_LABEL:
 +      g_free (priv->label);
 +      priv->label = g_value_dup_string (value);
 +      g_debug ("VikGotoTool.label: %s", priv->label);
 +      break;
 +
 +    default:
 +      /* We don't have any other property... */
 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 +      break;
 +    }
 +}
 +
 +static void
 +goto_tool_get_property (GObject    *object,
 +                          guint       property_id,
 +                          GValue     *value,
 +                          GParamSpec *pspec)
 +{
 +  VikGotoTool *self = VIK_GOTO_TOOL (object);
 +  VikGotoToolPrivate *priv = GOTO_TOOL_GET_PRIVATE (self);
 +
 +  switch (property_id)
 +    {
 +    case PROP_ID:
 +      g_value_set_uint (value, priv->id);
 +      break;
 +
 +    case PROP_LABEL:
 +      g_value_set_string (value, priv->label);
 +      break;
 +
 +    default:
 +      /* We don't have any other property... */
 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 +      break;
 +    }
 +}
 +
 +static void goto_tool_class_init ( VikGotoToolClass *klass )
 +{
 +  GObjectClass *gobject_class;
 +  GParamSpec *pspec;
 +
 +  gobject_class = G_OBJECT_CLASS (klass);
 +  gobject_class->finalize = goto_tool_finalize;
 +  gobject_class->set_property = goto_tool_set_property;
 +  gobject_class->get_property = goto_tool_get_property;
 +
 +  pspec = g_param_spec_string ("label",
 +                               "Label",
 +                               "Set the label",
 +                               "<no-set>" /* default value */,
 +                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class,
 +                                   PROP_LABEL,
 +                                   pspec);
 +
 +  pspec = g_param_spec_uint ("id",
 +                             "Id of the tool",
 +                             "Set the id",
 +                             0  /* minimum value */,
 +                             G_MAXUINT16 /* maximum value */,
 +                             0  /* default value */,
 +                             G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class,
 +                                   PROP_ID,
 +                                   pspec);
 +
 +  klass->get_label = goto_tool_get_label;
 +  klass->get_download_options = goto_tool_get_download_options;
 +
 +  parent_class = g_type_class_peek_parent (klass);
 +
 +  g_type_class_add_private (klass, sizeof (VikGotoToolPrivate));
 +}
 +
 +VikGotoTool *vik_goto_tool_new ()
 +{
 +  return VIK_GOTO_TOOL ( g_object_new ( VIK_GOTO_TOOL_TYPE, NULL ) );
 +}
 +
 +static void goto_tool_init ( VikGotoTool *self )
 +{
 +  VikGotoToolPrivate *priv = GOTO_TOOL_GET_PRIVATE (self);
 +  priv->label = NULL;
 +}
 +
 +static void goto_tool_finalize ( GObject *gob )
 +{
 +  VikGotoToolPrivate *priv = GOTO_TOOL_GET_PRIVATE ( gob );
 +  g_free ( priv->label ); priv->label = NULL;
 +  G_OBJECT_CLASS(parent_class)->finalize(gob);
 +}
 +
 +static gchar *goto_tool_get_label ( VikGotoTool *self )
 +{
 +  VikGotoToolPrivate *priv = NULL;
 +  priv = GOTO_TOOL_GET_PRIVATE (self);
 +  return g_strdup ( priv->label );
 +}
 +
 +static DownloadOptions *goto_tool_get_download_options ( VikGotoTool *self )
 +{
 +  // Default: return NULL
 +  return NULL;
 +}
 +
 +gchar *vik_goto_tool_get_label ( VikGotoTool *self )
 +{
 +  return VIK_GOTO_TOOL_GET_CLASS( self )->get_label( self );
 +}
 +
 +gchar *vik_goto_tool_get_url_format ( VikGotoTool *self )
 +{
 +  return VIK_GOTO_TOOL_GET_CLASS( self )->get_url_format( self );
 +}
 +
 +DownloadOptions *vik_goto_tool_get_download_options ( VikGotoTool *self )
 +{
 +  return VIK_GOTO_TOOL_GET_CLASS( self )->get_download_options( self );
 +}
 +
 +gboolean vik_goto_tool_parse_file_for_latlon (VikGotoTool *self, gchar *filename, struct LatLon *ll)
 +{
 +  return VIK_GOTO_TOOL_GET_CLASS( self )->parse_file_for_latlon( self, filename, ll );
 +}
 +
 +int vik_goto_tool_get_coord ( VikGotoTool *self, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord )
 +{
 +  FILE *tmp_file;
 +  int tmp_fd;
 +  gchar *tmpname;
 +  gchar *uri;
 +  gchar *escaped_srch_str;
 +  int ret = 0;  /* OK */
 +  struct LatLon ll;
 +
 +  g_debug("%s: raw goto: %s", __FUNCTION__, srch_str);
 +
 +  escaped_srch_str = uri_escape(srch_str);
 +
 +  g_debug("%s: escaped goto: %s", __FUNCTION__, escaped_srch_str);
 +
 +  if ((tmp_fd = g_file_open_tmp ("vikgoto.XXXXXX", &tmpname, NULL)) == -1) {
 +    g_critical(_("couldn't open temp file"));
 +    return -1;
 +  }
 +  
 +  tmp_file = fdopen(tmp_fd, "r+");
 +  uri = g_strdup_printf(vik_goto_tool_get_url_format(self), escaped_srch_str);
 +
 +  /* TODO: curl may not be available */
++  if (curl_download_uri(uri, tmp_file, vik_goto_tool_get_download_options(self), 0)) {  /* error */
 +    fclose(tmp_file);
 +    tmp_file = NULL;
 +    ret = -1;
 +    goto done;
 +  }
 +
 +  fclose(tmp_file);
 +  tmp_file = NULL;
 +  g_debug("%s: %s", __FILE__, tmpname);
 +  if (!vik_goto_tool_parse_file_for_latlon(self, tmpname, &ll)) {
 +    ret = -1;
 +    goto done;
 +  }
 +  vik_coord_load_from_latlon ( coord, vik_viewport_get_coord_mode(vvp), &ll );
 +
 +done:
 +  g_free(escaped_srch_str);
 +  g_free(uri);
 +  g_remove(tmpname);
 +  g_free(tmpname);
 +  return ret;
 +}
index f2453be53ecaf1a49f8e2b548bb861f028360393,e09d54d99d4b74535289f64dbcf2ddec07a49e6e..04a6fd9615085bb32ba987d9161738577025848e
@@@ -636,10 -638,15 +640,15 @@@ static void maps_layer_draw_section ( V
  #ifdef DEBUG
        fputs(stderr, "DEBUG: Starting autodownload\n");
  #endif
-       start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NONE );
 -      if ( map_type->options != NULL && map_type->options->check_file_server_time )
++      if ( vik_map_source_supports_if_modified_since (map) )
+         // Try to download newer tiles
+         start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NEW );
+       else
+         // Download only missing tiles
+         start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NONE );
      }
  
 -    if ( map_type->tilesize_x == 0 && !existence_only ) {
 +    if ( vik_map_source_get_tilesize_x(map) == 0 && !existence_only ) {
        for ( x = xmin; x <= xmax; x++ ) {
          for ( y = ymin; y <= ymax; y++ ) {
            ulm.x = x;
@@@ -1197,6 -1222,14 +1224,13 @@@ static void maps_layer_add_menu_items 
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
    gtk_widget_show ( item );
  
 -  if ( MAPS_LAYER_NTH_TYPE(vml->maptype)->options != NULL && 
 -       MAPS_LAYER_NTH_TYPE(vml->maptype)->options->check_file_server_time ) {
++  if ( vik_map_source_supports_if_modified_since (MAPS_LAYER_NTH_TYPE(vml->maptype)) ) {
+     item = gtk_menu_item_new_with_label ( _("Download new Onscreen Maps from server") );
+     g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_download_new_onscreen_maps), pass_along );
+     gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+     gtk_widget_show ( item );
+   }
    /* TODO Add GTK_STOCK_REFRESH icon */
    item = gtk_menu_item_new_with_label ( _("Refresh Onscreen Tiles") );
    g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_redownload_all_onscreen_maps), pass_along );
index 48a679f08d555101f21339e0b1913ce5fb727052,0000000000000000000000000000000000000000..de756992f5d122124a3e14876c0c71d14e23d98c
mode 100644,000000..100644
--- /dev/null
@@@ -1,169 -1,0 +1,191 @@@
 +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 +/*
 + * viking
 + * Copyright (C) Guilhem Bonnefille 2009 <guilhem.bonnefille@gmail.com>
 + * 
 + * viking is free software: you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License as published by the
 + * Free Software Foundation, either version 3 of the License, or
 + * (at your option) any later version.
 + * 
 + * viking is distributed in the hope that it will be useful, but
 + * WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 + * See the GNU General Public License for more details.
 + * 
 + * You should have received a copy of the GNU General Public License along
 + * with this program.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include "vikviewport.h"
 +#include "vikcoord.h"
 +#include "mapcoord.h"
 +
 +#include "vikmapsource.h"
 +
 +static void vik_map_source_init (VikMapSource *object);
 +static void vik_map_source_finalize (GObject *object);
 +static void vik_map_source_class_init (VikMapSourceClass *klass);
 +
++static void _supports_if_modified_since (VikMapSource *object);
++
 +G_DEFINE_TYPE_EXTENDED (VikMapSource, vik_map_source, G_TYPE_OBJECT, (GTypeFlags)G_TYPE_FLAG_ABSTRACT,);
 +
 +static void
 +vik_map_source_init (VikMapSource *object)
 +{
 +      /* TODO: Add initialization code here */
 +}
 +
 +static void
 +vik_map_source_finalize (GObject *object)
 +{
 +      /* TODO: Add deinitalization code here */
 +
 +      G_OBJECT_CLASS (vik_map_source_parent_class)->finalize (object);
 +}
 +
 +static void
 +vik_map_source_class_init (VikMapSourceClass *klass)
 +{
 +      GObjectClass* object_class = G_OBJECT_CLASS (klass);
 +
 +      klass->get_uniq_id = NULL;
 +      klass->get_label = NULL;
 +      klass->get_tilesize_x = NULL;
 +      klass->get_tilesize_y = NULL;
 +      klass->get_drawmode = NULL;
++      klass->supports_if_modified_since = _supports_if_modified_since;
 +      klass->coord_to_mapcoord = NULL;
 +      klass->mapcoord_to_center_coord = NULL;
 +      klass->download = NULL;
 +      
 +      object_class->finalize = vik_map_source_finalize;
 +}
 +
++void
++_supports_if_modified_since (VikMapSource *self)
++{
++      // Default feature: does not support
++      return FALSE;
++}
 +
 +guint8
 +vik_map_source_get_uniq_id (VikMapSource *self)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, (guint8 )0);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), (guint8 )0);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_uniq_id != NULL, (guint8 )0);
 +
 +      return (*klass->get_uniq_id)(self);
 +}
 +
 +const gchar *
 +vik_map_source_get_label (VikMapSource *self)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, NULL);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), NULL);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_label != NULL, NULL);
 +
 +      return (*klass->get_label)(self);
 +}
 +
 +guint16
 +vik_map_source_get_tilesize_x (VikMapSource *self)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, (guint16 )0);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), (guint16 )0);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_tilesize_x != NULL, (guint16 )0);
 +
 +      return (*klass->get_tilesize_x)(self);
 +}
 +
 +guint16
 +vik_map_source_get_tilesize_y (VikMapSource *self)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, (guint16 )0);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), (guint16 )0);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_tilesize_y != NULL, (guint16 )0);
 +
 +      return (*klass->get_tilesize_y)(self);
 +}
 +
 +VikViewportDrawMode
 +vik_map_source_get_drawmode (VikMapSource *self)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, (VikViewportDrawMode )0);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), (VikViewportDrawMode )0);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_drawmode != NULL, (VikViewportDrawMode )0);
 +
 +      return (*klass->get_drawmode)(self);
 +}
 +
++gboolean
++vik_map_source_supports_if_modified_since (VikMapSource * self)
++{
++      VikMapSourceClass *klass;
++      g_return_val_if_fail (self != NULL, 0);
++      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), 0);
++      klass = VIK_MAP_SOURCE_GET_CLASS(self);
++
++      g_return_val_if_fail (klass->supports_if_modified_since != NULL, 0);
++
++      return (*klass->supports_if_modified_since)(self);
++}
++
 +gboolean
 +vik_map_source_coord_to_mapcoord (VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, FALSE);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), FALSE);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->coord_to_mapcoord != NULL, FALSE);
 +
 +      return (*klass->coord_to_mapcoord)(self, src, xzoom, yzoom, dest);
 +}
 +
 +void
 +vik_map_source_mapcoord_to_center_coord (VikMapSource *self, MapCoord *src, VikCoord *dest)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_if_fail (self != NULL);
 +      g_return_if_fail (VIK_IS_MAP_SOURCE (self));
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_if_fail (klass->mapcoord_to_center_coord != NULL);
 +
 +      return (*klass->mapcoord_to_center_coord)(self, src, dest);
 +}
 +
 +int
 +vik_map_source_download (VikMapSource * self, MapCoord * src, const gchar * dest_fn)
 +{
 +      VikMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, 0);
 +      g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), 0);
 +      klass = VIK_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->download != NULL, 0);
 +
 +      return (*klass->download)(self, src, dest_fn);
 +}
index 29080ffd61f2897fca6059e0bfc12dfe33ed0d10,0000000000000000000000000000000000000000..c02fc5c152facf8903df7e4b40516f851f02f593
mode 100644,000000..100644
--- /dev/null
@@@ -1,73 -1,0 +1,75 @@@
 +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 +/*
 + * viking
 + * Copyright (C) Guilhem Bonnefille 2009 <guilhem.bonnefille@gmail.com>
 + * 
 + * viking is free software: you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License as published by the
 + * Free Software Foundation, either version 3 of the License, or
 + * (at your option) any later version.
 + * 
 + * viking is distributed in the hope that it will be useful, but
 + * WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 + * See the GNU General Public License for more details.
 + * 
 + * You should have received a copy of the GNU General Public License along
 + * with this program.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#ifndef _VIK_MAP_SOURCE_H_
 +#define _VIK_MAP_SOURCE_H_
 +
 +#include <glib-object.h>
 +
 +#include "vikviewport.h"
 +#include "vikcoord.h"
 +#include "mapcoord.h"
 +
 +G_BEGIN_DECLS
 +
 +#define VIK_TYPE_MAP_SOURCE             (vik_map_source_get_type ())
 +#define VIK_MAP_SOURCE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIK_TYPE_MAP_SOURCE, VikMapSource))
 +#define VIK_MAP_SOURCE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), VIK_TYPE_MAP_SOURCE, VikMapSourceClass))
 +#define VIK_IS_MAP_SOURCE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIK_TYPE_MAP_SOURCE))
 +#define VIK_IS_MAP_SOURCE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), VIK_TYPE_MAP_SOURCE))
 +#define VIK_MAP_SOURCE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), VIK_TYPE_MAP_SOURCE, VikMapSourceClass))
 +
 +typedef struct _VikMapSourceClass VikMapSourceClass;
 +typedef struct _VikMapSource VikMapSource;
 +
 +struct _VikMapSourceClass
 +{
 +      GObjectClass parent_class;
 +      
 +      guint8 (* get_uniq_id) (VikMapSource * self);
 +      const gchar * (* get_label) (VikMapSource * self);
 +      guint16 (* get_tilesize_x) (VikMapSource * self);
 +      guint16 (* get_tilesize_y) (VikMapSource * self);
 +      VikViewportDrawMode (* get_drawmode) (VikMapSource * self);
++      gboolean (* supports_if_modified_since) (VikMapSource * self);
 +      gboolean (* coord_to_mapcoord) (VikMapSource * self, const VikCoord * src, gdouble xzoom, gdouble yzoom, MapCoord * dest);
 +      void (* mapcoord_to_center_coord) (VikMapSource * self, MapCoord * src, VikCoord * dest);
 +      int (* download) (VikMapSource * self, MapCoord * src, const gchar * dest_fn);
 +};
 +
 +struct _VikMapSource
 +{
 +      GObject parent_instance;
 +};
 +
 +GType vik_map_source_get_type (void) G_GNUC_CONST;
 +
 +guint8 vik_map_source_get_uniq_id (VikMapSource * self);
 +const gchar *vik_map_source_get_label (VikMapSource * self);
 +guint16 vik_map_source_get_tilesize_x (VikMapSource * self);
 +guint16 vik_map_source_get_tilesize_y (VikMapSource * self);
 +VikViewportDrawMode vik_map_source_get_drawmode (VikMapSource * self);
++gboolean vik_map_source_supports_if_modified_since (VikMapSource * self);
 +gboolean vik_map_source_coord_to_mapcoord (VikMapSource * self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest );
 +void vik_map_source_mapcoord_to_center_coord (VikMapSource * self, MapCoord *src, VikCoord *dest);
 +int vik_map_source_download (VikMapSource * self, MapCoord * src, const gchar * dest_fn);
 +
 +G_END_DECLS
 +
 +#endif /* _VIK_MAP_SOURCE_H_ */
index 99ef39ec2cdaac4cc21ebfb71adedc52669dfa55,0000000000000000000000000000000000000000..44bf8b3174c8e50997f399d42917174ae7a02dc9
mode 100644,000000..100644
--- /dev/null
@@@ -1,353 -1,0 +1,385 @@@
 +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 +/*
 + * viking
 + * Copyright (C) Guilhem Bonnefille 2009 <guilhem.bonnefille@gmail.com>
 + * 
 + * viking is free software: you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License as published by the
 + * Free Software Foundation, either version 3 of the License, or
 + * (at your option) any later version.
 + * 
 + * viking is distributed in the hope that it will be useful, but
 + * WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 + * See the GNU General Public License for more details.
 + * 
 + * You should have received a copy of the GNU General Public License along
 + * with this program.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#ifdef HAVE_MATH_H
 +#include <math.h>
 +#endif
 +
 +#include "globals.h"
 +#include "vikslippymapsource.h"
 +
 +static gboolean _coord_to_mapcoord ( VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest );
 +static void _mapcoord_to_center_coord ( VikMapSource *self, MapCoord *src, VikCoord *dest );
 +static int _download ( VikMapSource *self, MapCoord *src, const gchar *dest_fn );
++static gboolean _supports_if_modified_since (VikMapSource *self );
 +
 +static gchar *_get_uri( VikSlippyMapSource *self, MapCoord *src );
 +static gchar *_get_hostname( VikSlippyMapSource *self );
 +static DownloadOptions *_get_download_options( VikSlippyMapSource *self );
 +
 +typedef struct _VikSlippyMapSourcePrivate VikSlippyMapSourcePrivate;
 +struct _VikSlippyMapSourcePrivate
 +{
 +  gchar *hostname;
 +  gchar *url;
 +  DownloadOptions options;
 +};
 +
 +#define VIK_SLIPPY_MAP_SOURCE_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIK_TYPE_SLIPPY_MAP_SOURCE, VikSlippyMapSourcePrivate))
 +
 +/* properties */
 +enum
 +{
 +  PROP_0,
 +
 +  PROP_HOSTNAME,
 +  PROP_URL,
 +  PROP_REFERER,
 +  PROP_FOLLOW_LOCATION,
++  PROP_CHECK_FILE_SERVER_TIME,
 +};
 +
 +G_DEFINE_TYPE_EXTENDED (VikSlippyMapSource, vik_slippy_map_source, VIK_TYPE_MAP_SOURCE_DEFAULT, (GTypeFlags)0,);
 +
 +static void
 +vik_slippy_map_source_init (VikSlippyMapSource *self)
 +{
 +  /* initialize the object here */
 +  VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
 +
 +  priv->hostname = NULL;
 +  priv->url = NULL;
 +  priv->options.referer = NULL;
 +  priv->options.follow_location = 0;
 +  priv->options.check_file = a_check_map_file;
++  priv->options.check_file_server_time = 0;
 +
 +  g_object_set (G_OBJECT (self),
 +                "tilesize-x", 256,
 +                "tilesize-y", 256,
 +                "drawmode", VIK_VIEWPORT_DRAWMODE_MERCATOR,
 +                NULL);
 +}
 +
 +static void
 +vik_slippy_map_source_finalize (GObject *object)
 +{
 +  VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
 +  VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
 +
 +  g_free (priv->hostname);
 +  priv->hostname = NULL;
 +  g_free (priv->url);
 +  priv->url = NULL;
 +  g_free (priv->options.referer);
 +  priv->options.referer = NULL;
 +
 +  G_OBJECT_CLASS (vik_slippy_map_source_parent_class)->finalize (object);
 +}
 +
 +static void
 +vik_slippy_map_source_set_property (GObject      *object,
 +                                    guint         property_id,
 +                                    const GValue *value,
 +                                    GParamSpec   *pspec)
 +{
 +  VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
 +  VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
 +
 +  switch (property_id)
 +    {
 +    case PROP_HOSTNAME:
 +      g_free (priv->hostname);
 +      priv->hostname = g_value_dup_string (value);
 +      break;
 +
 +    case PROP_URL:
 +      g_free (priv->url);
 +      priv->url = g_value_dup_string (value);
 +      break;
 +
 +    case PROP_REFERER:
 +      g_free (priv->options.referer);
 +      priv->options.referer = g_value_dup_string (value);
 +      break;
 +
 +    case PROP_FOLLOW_LOCATION:
 +      priv->options.follow_location = g_value_get_long (value);
 +      break;
 +
++    case PROP_CHECK_FILE_SERVER_TIME:
++      priv->options.check_file_server_time = g_value_get_uint (value);
++      break;
++
 +    default:
 +      /* We don't have any other property... */
 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 +      break;
 +    }
 +}
 +
 +static void
 +vik_slippy_map_source_get_property (GObject    *object,
 +                                    guint       property_id,
 +                                    GValue     *value,
 +                                    GParamSpec *pspec)
 +{
 +  VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
 +  VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
 +
 +  switch (property_id)
 +    {
 +    case PROP_HOSTNAME:
 +      g_value_set_string (value, priv->hostname);
 +      break;
 +
 +    case PROP_URL:
 +      g_value_set_string (value, priv->url);
 +      break;
 +
 +    case PROP_REFERER:
 +      g_value_set_string (value, priv->options.referer);
 +      break;
 +
 +    case PROP_FOLLOW_LOCATION:
 +      g_value_set_long (value, priv->options.follow_location);
 +      break;
 +
++    case PROP_CHECK_FILE_SERVER_TIME:
++      g_value_set_uint (value, priv->options.check_file_server_time);
++      break;
++        
 +    default:
 +      /* We don't have any other property... */
 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 +      break;
 +    }
 +}
 +
 +static void
 +vik_slippy_map_source_class_init (VikSlippyMapSourceClass *klass)
 +{
 +      GObjectClass* object_class = G_OBJECT_CLASS (klass);
 +      VikMapSourceClass* parent_class = VIK_MAP_SOURCE_CLASS (klass);
 +      GParamSpec *pspec = NULL;
 +              
 +      object_class->set_property = vik_slippy_map_source_set_property;
 +    object_class->get_property = vik_slippy_map_source_get_property;
 +
 +      /* Overiding methods */
 +      parent_class->coord_to_mapcoord =        _coord_to_mapcoord;
 +      parent_class->mapcoord_to_center_coord = _mapcoord_to_center_coord;
 +      parent_class->download =                 _download;
++      parent_class->supports_if_modified_since = _supports_if_modified_since;
 +      
 +      /* Default implementation of methods */
 +      klass->get_uri = _get_uri;
 +      klass->get_hostname = _get_hostname;
 +      klass->get_download_options = _get_download_options;
 +
 +      pspec = g_param_spec_string ("hostname",
 +                                   "Hostname",
 +                                   "The hostname of the map server",
 +                                   "<no-set>" /* default value */,
 +                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +      g_object_class_install_property (object_class, PROP_HOSTNAME, pspec);
 +
 +      pspec = g_param_spec_string ("url",
 +                                   "URL",
 +                                   "The template of the tiles' URL",
 +                                   "<no-set>" /* default value */,
 +                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +      g_object_class_install_property (object_class, PROP_URL, pspec);
 +
 +      pspec = g_param_spec_string ("referer",
 +                                   "Referer",
 +                                   "The REFERER string to use in HTTP request",
 +                                   NULL /* default value */,
 +                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +      g_object_class_install_property (object_class, PROP_REFERER, pspec);
 +      
 +      pspec = g_param_spec_long ("follow-location",
 +                                 "Follow location",
 +                               "Specifies the number of retries to follow a redirect while downloading a page",
 +                               0  /* minimum value */,
 +                               G_MAXLONG /* maximum value */,
 +                               0  /* default value */,
 +                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 +      g_object_class_install_property (object_class, PROP_FOLLOW_LOCATION, pspec);
++      
++      pspec = g_param_spec_uint ("check-file-server-time",
++                                 "Check file server time",
++                               "Age of current cache before redownloading tile",
++                               0  /* minimum value */,
++                               G_MAXUINT16 /* maximum value */,
++                               0  /* default value */,
++                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
++      g_object_class_install_property (object_class, PROP_CHECK_FILE_SERVER_TIME, pspec);
 +
 +      g_type_class_add_private (klass, sizeof (VikSlippyMapSourcePrivate));
 +      
 +      object_class->finalize = vik_slippy_map_source_finalize;
 +}
 +
 +/* 1 << (x) is like a 2**(x) */
 +#define GZ(x) ((1<<x))
 +
 +static const gdouble scale_mpps[] = { GZ(0), GZ(1), GZ(2), GZ(3), GZ(4), GZ(5), GZ(6), GZ(7), GZ(8), GZ(9),
 +                                           GZ(10), GZ(11), GZ(12), GZ(13), GZ(14), GZ(15), GZ(16), GZ(17) };
 +
 +static const gint num_scales = (sizeof(scale_mpps) / sizeof(scale_mpps[0]));
 +
 +#define ERROR_MARGIN 0.01
 +static guint8 slippy_zoom ( gdouble mpp ) {
 +  gint i;
 +  for ( i = 0; i < num_scales; i++ ) {
 +    if ( ABS(scale_mpps[i] - mpp) < ERROR_MARGIN )
 +      return i;
 +  }
 +  return 255;
 +}
 +
 +gchar *
 +vik_slippy_map_source_get_uri( VikSlippyMapSource *self, MapCoord *src )
 +{
 +      VikSlippyMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, 0);
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE (self), 0);
 +      klass = VIK_SLIPPY_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_uri != NULL, 0);
 +
 +      return (*klass->get_uri)(self, src);
 +}
 +
 +gchar *
 +vik_slippy_map_source_get_hostname( VikSlippyMapSource *self )
 +{
 +      VikSlippyMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, 0);
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE (self), 0);
 +      klass = VIK_SLIPPY_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_hostname != NULL, 0);
 +
 +      return (*klass->get_hostname)(self);
 +}
 +
 +DownloadOptions *
 +vik_slippy_map_source_get_download_options( VikSlippyMapSource *self )
 +{
 +      VikSlippyMapSourceClass *klass;
 +      g_return_val_if_fail (self != NULL, 0);
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE (self), 0);
 +      klass = VIK_SLIPPY_MAP_SOURCE_GET_CLASS(self);
 +
 +      g_return_val_if_fail (klass->get_download_options != NULL, 0);
 +
 +      return (*klass->get_download_options)(self);
 +}
 +
++gboolean
++_supports_if_modified_since (VikMapSource *self)
++{
++      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
++      
++    VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
++      
++      g_debug ("%s: priv->options.check_file_server_time = %d", __FUNCTION__, priv->options.check_file_server_time);
++      
++      return priv->options.check_file_server_time != 0;
++}
 +static gboolean
 +_coord_to_mapcoord ( VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
 +{
 +  g_assert ( src->mode == VIK_COORD_LATLON );
 +
 +  if ( xzoom != yzoom )
 +    return FALSE;
 +
 +  dest->scale = slippy_zoom ( xzoom );
 +  if ( dest->scale == 255 )
 +    return FALSE;
 +
 +  dest->x = (src->east_west + 180) / 360 * GZ(17) / xzoom;
 +  dest->y = (180 - MERCLAT(src->north_south)) / 360 * GZ(17) / xzoom;
 +  dest->z = 0;
 +
 +  return TRUE;
 +}
 +
 +static void
 +_mapcoord_to_center_coord ( VikMapSource *self, MapCoord *src, VikCoord *dest )
 +{
 +  gdouble socalled_mpp = GZ(src->scale);
 +  dest->mode = VIK_COORD_LATLON;
 +  dest->east_west = ((src->x+0.5) / GZ(17) * socalled_mpp * 360) - 180;
 +  dest->north_south = DEMERCLAT(180 - ((src->y+0.5) / GZ(17) * socalled_mpp * 360));
 +}
 +
 +static int
 +_download ( VikMapSource *self, MapCoord *src, const gchar *dest_fn )
 +{
 +   int res;
 +   gchar *uri = vik_slippy_map_source_get_uri(VIK_SLIPPY_MAP_SOURCE(self), src);
 +   gchar *host = vik_slippy_map_source_get_hostname(VIK_SLIPPY_MAP_SOURCE(self));
 +   DownloadOptions *options = vik_slippy_map_source_get_download_options(VIK_SLIPPY_MAP_SOURCE(self));
 +   res = a_http_download_get_url ( host, uri, dest_fn, options );
 +   g_free ( uri );
 +   g_free ( host );
 +   return res;
 +}
 +
 +static gchar *
 +_get_uri( VikSlippyMapSource *self, MapCoord *src )
 +{
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
 +      
 +    VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
 +      gchar *uri = g_strdup_printf (priv->url, 17 - src->scale, src->x, src->y);
 +      return uri;
 +} 
 +
 +static gchar *
 +_get_hostname( VikSlippyMapSource *self )
 +{
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
 +      
 +    VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
 +      return g_strdup( priv->hostname );
 +}
 +
 +static DownloadOptions *
 +_get_download_options( VikSlippyMapSource *self )
 +{
 +      g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
 +      
 +      VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
 +      return &(priv->options);
 +}
 +
 +VikSlippyMapSource *
 +vik_slippy_map_source_new_with_id (guint8 id, const gchar *label, const gchar *hostname, const gchar *url)
 +{
 +      return g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
 +                          "id", id, "label", label, "hostname", hostname, "url", url, NULL);
 +}