#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;
/* 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;
--- /dev/null
- 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;
+}
#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;
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 );
--- /dev/null
+/* -*- 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);
+}
--- /dev/null
+/* -*- 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_ */
--- /dev/null
+/* -*- 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);
+}