*
* Copyright (C) 2005, Evan Battaglia <viking@greentorch.org>
* UTM multi-zone stuff by Kit Transue <notlostyet@didactek.com>
+ * Dynamic map type by 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
#include "mapcoord.h"
#include "terraserver.h"
-#include "googlemaps.h"
-#include "google.h"
-#include "khmaps.h"
-#include "expedia.h"
-typedef struct {
- guint8 uniq_id;
- guint16 tilesize_x;
- guint16 tilesize_y;
- guint drawmode;
- gboolean (*coord_to_mapcoord) ( const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest );
- void (*mapcoord_to_center_coord) ( MapCoord *src, VikCoord *dest );
- void (*download) ( MapCoord *src, const gchar *dest_fn );
- /* TODO: constant size (yay!) */
-} VikMapsLayer_MapType;
+/****** MAP TYPES ******/
+static GList *__map_types = NULL;
-/****** MAP TYPES ******/
+#define NUM_MAP_TYPES g_list_length(__map_types)
-static const VikMapsLayer_MapType __map_types[] = {
-
-{ 2, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_topo_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_topo_download },
-{ 1, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_aerial_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_aerial_download },
-{ 4, 200, 200, VIK_VIEWPORT_DRAWMODE_UTM, terraserver_urban_coord_to_mapcoord, terraserver_mapcoord_to_center_coord, terraserver_urban_download },
-{ 5, 0, 0, VIK_VIEWPORT_DRAWMODE_EXPEDIA, expedia_coord_to_mapcoord, expedia_mapcoord_to_center_coord, expedia_download },
-{ 9, 128, 128, VIK_VIEWPORT_DRAWMODE_GOOGLE, googlemaps_coord_to_mapcoord, googlemaps_mapcoord_to_center_coord, googlemaps_download },
-{ 8, 256, 256, VIK_VIEWPORT_DRAWMODE_KH, khmaps_coord_to_mapcoord, khmaps_mapcoord_to_center_coord, khmaps_download },
-{ 7, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, google_coord_to_mapcoord, google_mapcoord_to_center_coord, google_download },
-{ 10, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, google_coord_to_mapcoord, google_mapcoord_to_center_coord, google_trans_download },
-{ 11, 256, 256, VIK_VIEWPORT_DRAWMODE_MERCATOR, google_coord_to_mapcoord, google_mapcoord_to_center_coord, google_kh_download },
-};
+/* List of label for each map type */
+static GList *params_maptypes = NULL;
-#define NUM_MAP_TYPES (sizeof(__map_types)/sizeof(__map_types[0]))
+/* Corresponding IDS. (Cf. field uniq_id in VikMapsLayer struct) */
+static GList *params_maptypes_ids = NULL;
/******** MAPZOOMS *********/
-static gchar *params_mapzooms[] = { "Use Viking Zoom Level", "0.25", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "USGS 10k", "USGS 24k", "USGS 25k", "USGS 50k", "USGS 100k", "USGS 200k", "USGS 250k" };
+static gchar *params_mapzooms[] = { "Use Viking Zoom Level", "0.25", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "USGS 10k", "USGS 24k", "USGS 25k", "USGS 50k", "USGS 100k", "USGS 200k", "USGS 250k", NULL };
static gdouble __mapzooms_x[] = { 0.0, 0.25, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 1.016, 2.4384, 2.54, 5.08, 10.16, 20.32, 25.4 };
static gdouble __mapzooms_y[] = { 0.0, 0.25, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 1.016, 2.4384, 2.54, 5.08, 10.16, 20.32, 25.4 };
-static gchar *params_maptypes[] = { "Terraserver Topos", "Terraserver Aerials", "Terraserver Urban Areas", "Expedia (Street Maps)", "Google Maps (Street)", "KH Maps", "New (Mercator) Google", "Transparent Google", "New (Mercator) KH" };
-static guint params_maptypes_ids[] = { 2, 1, 4, 5, 9, 8, 7, 10, 11 };
-#define NUM_MAPZOOMS (sizeof(params_mapzooms)/sizeof(params_mapzooms[0]))
+#define NUM_MAPZOOMS (sizeof(params_mapzooms)/sizeof(params_mapzooms[0]) - 1)
/**************************/
static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp );
+static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len );
+static VikMapsLayer *maps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp );
static gboolean maps_layer_set_param ( VikMapsLayer *vml, guint16 id, VikLayerParamData data, VikViewport *vvp );
static VikLayerParamData maps_layer_get_param ( VikMapsLayer *vml, guint16 id );
static void maps_layer_draw ( VikMapsLayer *vml, VikViewport *vvp );
static void maps_layer_free ( VikMapsLayer *vml );
static gboolean maps_layer_download_release ( VikMapsLayer *vml, GdkEventButton *event, VikViewport *vvp );
static gboolean maps_layer_download_click ( VikMapsLayer *vml, GdkEventButton *event, VikViewport *vvp );
+static gpointer maps_layer_download_create ( VikWindow *vw, VikViewport *vvp );
static void maps_layer_set_cache_dir ( VikMapsLayer *vml, const gchar *dir );
static void start_download_thread ( VikMapsLayer *vml, VikViewport *vvp, const VikCoord *ul, const VikCoord *br, gint redownload );
static void maps_layer_add_menu_items ( VikMapsLayer *vml, GtkMenu *menu, VikLayersPanel *vlp );
};
VikLayerParam maps_layer_params[] = {
- { "mode", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Map Type:", VIK_LAYER_WIDGET_RADIOGROUP, params_maptypes, params_maptypes_ids },
+ { "mode", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Map Type:", VIK_LAYER_WIDGET_RADIOGROUP, NULL, NULL },
{ "directory", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, "Maps Directory (Optional):", VIK_LAYER_WIDGET_FILEENTRY },
{ "alpha", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Alpha:", VIK_LAYER_WIDGET_HSCALE, params_scales },
{ "autodownload", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_GROUP_NONE, "Autodownload maps:", VIK_LAYER_WIDGET_CHECKBUTTON },
enum { PARAM_MAPTYPE=0, PARAM_CACHE_DIR, PARAM_ALPHA, PARAM_AUTODOWNLOAD, PARAM_MAPZOOM, NUM_PARAMS };
static VikToolInterface maps_tools[] = {
- { "Maps Download", (VikToolInterfaceFunc) maps_layer_download_click, (VikToolInterfaceFunc) maps_layer_download_release },
+ { "Maps Download", (VikToolConstructorFunc) maps_layer_download_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) maps_layer_download_click, NULL, (VikToolMouseFunc) maps_layer_download_release },
};
VikLayerInterface vik_maps_layer_interface = {
NULL,
0,
+ VIK_MENU_ITEM_ALL,
+
(VikLayerFuncCreate) maps_layer_new,
(VikLayerFuncRealize) NULL,
(VikLayerFuncPostRead) NULL,
(VikLayerFuncDraw) maps_layer_draw,
(VikLayerFuncChangeCoordMode) NULL,
+ (VikLayerFuncSetMenuItemsSelection) NULL,
+ (VikLayerFuncGetMenuItemsSelection) NULL,
+
(VikLayerFuncAddMenuItems) maps_layer_add_menu_items,
(VikLayerFuncSublayerAddMenuItems) NULL,
(VikLayerFuncSublayerToggleVisible) NULL,
(VikLayerFuncCopy) maps_layer_copy,
+ (VikLayerFuncMarshall) maps_layer_marshall,
+ (VikLayerFuncUnmarshall) maps_layer_unmarshall,
(VikLayerFuncSetParam) maps_layer_set_param,
(VikLayerFuncGetParam) maps_layer_get_param,
(VikLayerFuncReadFileData) NULL,
(VikLayerFuncWriteFileData) NULL,
+ (VikLayerFuncDeleteItem) NULL,
(VikLayerFuncCopyItem) NULL,
(VikLayerFuncPasteItem) NULL,
(VikLayerFuncFreeCopiedItem) NULL,
gdouble xmapzoom, ymapzoom;
gboolean autodownload;
+ VikCoord *last_center;
+ gdouble last_xmpp;
+ gdouble last_ympp;
gint dl_tool_x, dl_tool_y;
VikViewport *redownload_vvp;
};
-enum { REDOWNLOAD_NONE = 0, REDOWNLOAD_BAD, REDOWNLOAD_ALL };
+enum { REDOWNLOAD_NONE = 0, REDOWNLOAD_BAD, REDOWNLOAD_ALL, DOWNLOAD_OR_REFRESH };
+
+
+/****************************************/
+/******** MAPS LAYER TYPES **************/
+/****************************************/
+
+void maps_layer_register_type ( const char *label, guint id, VikMapsLayer_MapType *map_type )
+{
+ g_assert(label != NULL);
+ g_assert(map_type != NULL);
+ g_assert(id == map_type->uniq_id);
+
+ /* Add the label */
+ params_maptypes = g_list_append(params_maptypes, g_strdup(label));
+
+ /* Add the id */
+ params_maptypes_ids = g_list_append(params_maptypes_ids, (gpointer)id);
+
+ /* We have to clone */
+ VikMapsLayer_MapType *clone = g_memdup(map_type, sizeof(VikMapsLayer_MapType));
+ /* Register the clone in the list */
+ __map_types = g_list_append(__map_types, clone);
+
+ /* Hack
+ We have to ensure the mode LayerParam reference the up-to-date
+ GLists.
+ */
+ /*
+ memcpy(&maps_layer_params[0].widget_data, ¶ms_maptypes, sizeof(gpointer));
+ memcpy(&maps_layer_params[0].extra_widget_data, ¶ms_maptypes_ids, sizeof(gpointer));
+ */
+ maps_layer_params[0].widget_data = params_maptypes;
+ maps_layer_params[0].extra_widget_data = params_maptypes_ids;
+}
+
+#define MAPS_LAYER_NTH_LABEL(n) ((gchar*)g_list_nth_data(params_maptypes, (n)))
+#define MAPS_LAYER_NTH_ID(n) ((guint)g_list_nth_data(params_maptypes_ids, (n)))
+#define MAPS_LAYER_NTH_TYPE(n) ((VikMapsLayer_MapType*)g_list_nth_data(__map_types, (n)))
+gint vik_maps_layer_get_map_type(VikMapsLayer *vml)
+{
+ return(vml->maptype);
+}
+
+gchar *vik_maps_layer_get_map_label(VikMapsLayer *vml)
+{
+ return(g_strdup(MAPS_LAYER_NTH_LABEL(vml->maptype)));
+}
/****************************************/
/******** CACHE DIR STUFF ***************/
static guint map_index_to_uniq_id (guint8 index)
{
g_assert ( index < NUM_MAP_TYPES );
- return __map_types[index].uniq_id;
+ return MAPS_LAYER_NTH_TYPE(index)->uniq_id;
}
static guint map_uniq_id_to_index ( guint uniq_id )
{
gint i;
for ( i = 0; i < NUM_MAP_TYPES; i++ )
- if ( __map_types[i].uniq_id == uniq_id )
+ if ( MAPS_LAYER_NTH_TYPE(i)->uniq_id == uniq_id )
return i;
return NUM_MAP_TYPES; /* no such thing */
}
vml->dl_tool_x = vml->dl_tool_y = -1;
maps_layer_set_cache_dir ( vml, NULL );
vml->autodownload = FALSE;
+ vml->last_center = NULL;
+ vml->last_xmpp = 0.0;
+ vml->last_ympp = 0.0;
vml->dl_right_click_menu = NULL;
g_free ( vml->cache_dir );
if ( vml->dl_right_click_menu )
gtk_object_sink ( GTK_OBJECT(vml->dl_right_click_menu) );
+ if (vml->last_center)
+ g_free(vml->last_center);
}
static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp )
return rv;
}
+static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len )
+{
+ vik_layer_marshall_params ( VIK_LAYER(vml), data, len );
+}
+
+static VikMapsLayer *maps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
+{
+ VikMapsLayer *rv = maps_layer_new ( vvp );
+ vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
+ return rv;
+}
+
/*********************/
/****** DRAWING ******/
/*********************/
pixbuf = pixbuf_shrink ( pixbuf, xshrinkfactor, yshrinkfactor );
a_mapcache_add ( pixbuf, mapcoord->x, mapcoord->y,
- mapcoord->z, __map_types[vml->maptype].uniq_id,
+ mapcoord->z, MAPS_LAYER_NTH_TYPE(vml->maptype)->uniq_id,
mapcoord->scale, vml->alpha, xshrinkfactor, yshrinkfactor );
}
}
return pixbuf;
}
+gboolean should_start_autodownload(VikMapsLayer *vml, VikViewport *vvp)
+{
+ const VikCoord *center = vik_viewport_get_center ( vvp );
+
+ if (vml->last_center == NULL) {
+ VikCoord *new_center = g_malloc(sizeof(VikCoord));
+ *new_center = *center;
+ vml->last_center = new_center;
+ vml->last_xmpp = vik_viewport_get_xmpp(vvp);
+ vml->last_ympp = vik_viewport_get_ympp(vvp);
+ return TRUE;
+ }
+
+ /* TODO: perhaps vik_coord_diff() */
+ if (vik_coord_equals(vml->last_center, center)
+ && (vml->last_xmpp == vik_viewport_get_xmpp(vvp))
+ && (vml->last_ympp == vik_viewport_get_ympp(vvp)))
+ return FALSE;
+
+ *(vml->last_center) = *center;
+ vml->last_xmpp = vik_viewport_get_xmpp(vvp);
+ vml->last_ympp = vik_viewport_get_ympp(vvp);
+ return TRUE;
+}
+
static void maps_layer_draw_section ( VikMapsLayer *vml, VikViewport *vvp, VikCoord *ul, VikCoord *br )
{
MapCoord ulm, brm;
}
/* coord -> ID */
- if ( __map_types[vml->maptype].coord_to_mapcoord ( ul, xzoom, yzoom, &ulm ) &&
- __map_types[vml->maptype].coord_to_mapcoord ( br, xzoom, yzoom, &brm ) ) {
+ VikMapsLayer_MapType *map_type = MAPS_LAYER_NTH_TYPE(vml->maptype);
+ if ( map_type->coord_to_mapcoord ( ul, xzoom, yzoom, &ulm ) &&
+ map_type->coord_to_mapcoord ( br, xzoom, yzoom, &brm ) ) {
/* loop & draw */
gint x, y;
gint xmin = MIN(ulm.x, brm.x), xmax = MAX(ulm.x, brm.x);
gint ymin = MIN(ulm.y, brm.y), ymax = MAX(ulm.y, brm.y);
- gint mode = __map_types[vml->maptype].uniq_id;
+ gint mode = map_type->uniq_id;
VikCoord coord;
gint xx, yy, width, height;
guint max_path_len = strlen(vml->cache_dir) + 40;
gchar *path_buf = g_malloc ( max_path_len * sizeof(char) );
- if ( vml->autodownload )
+ if ( vml->autodownload && should_start_autodownload(vml, vvp)) {
+ fprintf(stderr, "DEBUG: Starting autodownload\n");
start_download_thread ( vml, vvp, ul, br, REDOWNLOAD_NONE );
+ }
- if ( __map_types[vml->maptype].tilesize_x == 0 ) {
+ if ( map_type->tilesize_x == 0 ) {
for ( x = xmin; x <= xmax; x++ ) {
for ( y = ymin; y <= ymax; y++ ) {
ulm.x = x;
width = gdk_pixbuf_get_width ( pixbuf );
height = gdk_pixbuf_get_height ( pixbuf );
- __map_types[vml->maptype].mapcoord_to_center_coord ( &ulm, &coord );
+ map_type->mapcoord_to_center_coord ( &ulm, &coord );
vik_viewport_coord_to_screen ( vvp, &coord, &xx, &yy );
xx -= (width/2);
yy -= (height/2);
}
}
} else { /* tilesize is known, don't have to keep converting coords */
- gdouble tilesize_x = __map_types[vml->maptype].tilesize_x * xshrinkfactor;
- gdouble tilesize_y = __map_types[vml->maptype].tilesize_y * yshrinkfactor;
+ gdouble tilesize_x = map_type->tilesize_x * xshrinkfactor;
+ gdouble tilesize_y = map_type->tilesize_y * yshrinkfactor;
/* ceiled so tiles will be maximum size in the case of funky shrinkfactor */
gint tilesize_x_ceil = ceil ( tilesize_x );
gint tilesize_y_ceil = ceil ( tilesize_y );
xend = (xinc == 1) ? (xmax+1) : (xmin-1);
yend = (yinc == 1) ? (ymax+1) : (ymin-1);
- __map_types[vml->maptype].mapcoord_to_center_coord ( &ulm, &coord );
+ map_type->mapcoord_to_center_coord ( &ulm, &coord );
vik_viewport_coord_to_screen ( vvp, &coord, &xx_tmp, &yy_tmp );
xx = xx_tmp; yy = yy_tmp;
/* above trick so xx,yy doubles. this is so shrinkfactors aren't rounded off
static void maps_layer_draw ( VikMapsLayer *vml, VikViewport *vvp )
{
- if ( __map_types[vml->maptype].drawmode == vik_viewport_get_drawmode ( vvp ) )
+ if ( MAPS_LAYER_NTH_TYPE(vml->maptype)->drawmode == vik_viewport_get_drawmode ( vvp ) )
{
VikCoord ul, br;
gint maxlen;
gint mapstoget;
gint redownload;
+ gboolean refresh_display;
+ VikMapsLayer *vml;
+ VikViewport *vvp;
+ gboolean map_layer_alive;
+ GMutex *mutex;
} MapDownloadInfo;
static void mdi_free ( MapDownloadInfo *mdi )
{
+ g_mutex_free(mdi->mutex);
g_free ( mdi->cache_dir );
g_free ( mdi->filename_buf );
g_free ( mdi );
}
+static void weak_ref_cb(gpointer ptr, GObject * dead_vml)
+{
+ MapDownloadInfo *mdi = ptr;
+ g_mutex_lock(mdi->mutex);
+ mdi->map_layer_alive = FALSE;
+ g_mutex_unlock(mdi->mutex);
+}
+
static void map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata )
{
guint donemaps = 0;
{
for ( y = mdi->y0; y <= mdi->yf; y++ )
{
+ gboolean remove_mem_cache = FALSE;
+ gboolean need_download = FALSE;
g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE,
- mdi->cache_dir, __map_types[mdi->maptype].uniq_id,
+ mdi->cache_dir, MAPS_LAYER_NTH_TYPE(mdi->maptype)->uniq_id,
mdi->mapcoord.scale, mdi->mapcoord.z, x, y );
+ donemaps++;
+ a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */
+
if ( mdi->redownload == REDOWNLOAD_ALL)
remove ( mdi->filename_buf );
- else if ( mdi->redownload == REDOWNLOAD_BAD && access ( mdi->filename_buf, F_OK ) == 0 )
+
+ else if ( (mdi->redownload == REDOWNLOAD_BAD) && (access ( mdi->filename_buf, F_OK ) == 0) )
{
/* see if this one is bad or what */
GError *gx = NULL;
if ( access ( mdi->filename_buf, F_OK ) != 0 )
{
- mdi->mapcoord.x = x; mdi->mapcoord.y = y;
- __map_types[mdi->maptype].download ( &(mdi->mapcoord), mdi->filename_buf );
- mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between downloads */
-
- if ( mdi->redownload !=- REDOWNLOAD_NONE )
- a_mapcache_remove_all_shrinkfactors ( x, y, mdi->mapcoord.z, mdi->maptype, mdi->mapcoord.scale );
-
+ need_download = TRUE;
+ if (( mdi->redownload != REDOWNLOAD_NONE ) &&
+ ( mdi->redownload != DOWNLOAD_OR_REFRESH ))
+ remove_mem_cache = TRUE;
+ } else if ( mdi->redownload == DOWNLOAD_OR_REFRESH ) {
+ remove_mem_cache = TRUE;
+ } else
+ continue;
+
+ mdi->mapcoord.x = x; mdi->mapcoord.y = y;
+
+ if (need_download) {
+ if ( MAPS_LAYER_NTH_TYPE(mdi->maptype)->download ( &(mdi->mapcoord), mdi->filename_buf ))
+ continue;
+ }
- donemaps++;
- a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */
+ gdk_threads_enter();
+ g_mutex_lock(mdi->mutex);
+ if (remove_mem_cache)
+ a_mapcache_remove_all_shrinkfactors ( x, y, mdi->mapcoord.z, MAPS_LAYER_NTH_TYPE(mdi->maptype)->uniq_id, mdi->mapcoord.scale );
+ if (mdi->refresh_display && mdi->map_layer_alive) {
+ /* TODO: check if it's on visible area */
+ vik_layer_emit_update ( VIK_LAYER(mdi->vml) );
}
+ g_mutex_unlock(mdi->mutex);
+ gdk_threads_leave();
+ mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between downloads */
+
}
}
+ g_mutex_lock(mdi->mutex);
+ if (mdi->map_layer_alive)
+ g_object_weak_unref(G_OBJECT(mdi->vml), weak_ref_cb, mdi);
+ g_mutex_unlock(mdi->mutex);
}
static void mdi_cancel_cleanup ( MapDownloadInfo *mdi )
if ( mdi->mapcoord.x || mdi->mapcoord.y )
{
g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE,
- mdi->cache_dir, __map_types[mdi->maptype].uniq_id,
+ mdi->cache_dir, MAPS_LAYER_NTH_TYPE(mdi->maptype)->uniq_id,
mdi->mapcoord.scale, mdi->mapcoord.z, mdi->mapcoord.x, mdi->mapcoord.y );
if ( access ( mdi->filename_buf, F_OK ) == 0)
{
gdouble xzoom = vml->xmapzoom ? vml->xmapzoom : vik_viewport_get_xmpp ( vvp );
gdouble yzoom = vml->ymapzoom ? vml->ymapzoom : vik_viewport_get_ympp ( vvp );
MapCoord ulm, brm;
- if ( __map_types[vml->maptype].coord_to_mapcoord ( ul, xzoom, yzoom, &ulm )
- && __map_types[vml->maptype].coord_to_mapcoord ( br, xzoom, yzoom, &brm ) )
+ VikMapsLayer_MapType *map_type = MAPS_LAYER_NTH_TYPE(vml->maptype);
+ if ( map_type->coord_to_mapcoord ( ul, xzoom, yzoom, &ulm )
+ && map_type->coord_to_mapcoord ( br, xzoom, yzoom, &brm ) )
{
MapDownloadInfo *mdi = g_malloc ( sizeof(MapDownloadInfo) );
gint a, b;
+ mdi->vml = vml;
+ mdi->vvp = vvp;
+ mdi->map_layer_alive = TRUE;
+ mdi->mutex = g_mutex_new();
+ mdi->refresh_display = TRUE;
+
/* cache_dir and buffer for dest filename */
mdi->cache_dir = g_strdup ( vml->cache_dir );
mdi->maxlen = strlen ( vml->cache_dir ) + 40;
for ( b = mdi->y0; b <= mdi->yf; b++ )
{
g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE,
- vml->cache_dir, __map_types[vml->maptype].uniq_id, ulm.scale,
+ vml->cache_dir, map_type->uniq_id, ulm.scale,
ulm.z, a, b );
if ( access ( mdi->filename_buf, F_OK ) != 0)
mdi->mapstoget++;
if ( mdi->mapstoget )
{
- gchar *tmp = g_strdup_printf ( "%s %s%d %s %s...", redownload ? "Redownloading" : "Downloading", redownload == REDOWNLOAD_BAD ? "up to " : "", mdi->mapstoget, params_maptypes[vml->maptype], (mdi->mapstoget == 1) ? "map" : "maps" );
+ gchar *tmp = g_strdup_printf ( "%s %s%d %s %s...", redownload ? "Redownloading" : "Downloading", redownload == REDOWNLOAD_BAD ? "up to " : "", mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype), (mdi->mapstoget == 1) ? "map" : "maps" );
+ g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi);
/* launch the thread */
a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
tmp, /* description string */
}
}
+void maps_layer_download_section_without_redraw( VikMapsLayer *vml, VikViewport *vvp, VikCoord *ul, VikCoord *br, gdouble zoom)
+{
+ MapCoord ulm, brm;
+ VikMapsLayer_MapType *map_type = MAPS_LAYER_NTH_TYPE(vml->maptype);
+
+ if (!map_type->coord_to_mapcoord(ul, zoom, zoom, &ulm)
+ || !map_type->coord_to_mapcoord(br, zoom, zoom, &brm)) {
+ fprintf(stderr, "%s() coord_to_mapcoord() failed\n", __PRETTY_FUNCTION__);
+ return;
+ }
+
+ MapDownloadInfo *mdi = g_malloc(sizeof(MapDownloadInfo));
+ gint i, j;
+
+ mdi->vml = vml;
+ mdi->vvp = vvp;
+ mdi->map_layer_alive = TRUE;
+ mdi->mutex = g_mutex_new();
+ mdi->refresh_display = FALSE;
+
+ mdi->cache_dir = g_strdup ( vml->cache_dir );
+ mdi->maxlen = strlen ( vml->cache_dir ) + 40;
+ mdi->filename_buf = g_malloc ( mdi->maxlen * sizeof(gchar) );
+ mdi->maptype = vml->maptype;
+
+ mdi->mapcoord = ulm;
+
+ mdi->redownload = REDOWNLOAD_NONE;
+
+ mdi->x0 = MIN(ulm.x, brm.x);
+ mdi->xf = MAX(ulm.x, brm.x);
+ mdi->y0 = MIN(ulm.y, brm.y);
+ mdi->yf = MAX(ulm.y, brm.y);
+
+ mdi->mapstoget = 0;
+
+ for (i = mdi->x0; i <= mdi->xf; i++) {
+ for (j = mdi->y0; j <= mdi->yf; j++) {
+ g_snprintf ( mdi->filename_buf, mdi->maxlen, DIRSTRUCTURE,
+ vml->cache_dir, map_type->uniq_id, ulm.scale,
+ ulm.z, i, j );
+ if ( access ( mdi->filename_buf, F_OK ) != 0)
+ mdi->mapstoget++;
+ }
+ }
+
+ mdi->mapcoord.x = mdi->mapcoord.y = 0; /* for cleanup -- no current map */
+
+ if (mdi->mapstoget) {
+ gchar *tmp = g_strdup_printf ( "%s %d %s %s...", "Downloading", mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype), (mdi->mapstoget == 1) ? "map" : "maps" );
+
+ g_object_weak_ref(G_OBJECT(mdi->vml), weak_ref_cb, mdi);
+ /* launch the thread */
+ a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml), /* parent window */
+ tmp, /* description string */
+ (vik_thr_func) map_download_thread, /* function to call within thread */
+ mdi, /* pass along data */
+ (vik_thr_free_func) mdi_free, /* function to free pass along data */
+ (vik_thr_free_func) mdi_cancel_cleanup,
+ mdi->mapstoget );
+ g_free ( tmp );
+ }
+ else
+ mdi_free ( mdi );
+}
+
static void maps_layer_redownload_bad ( VikMapsLayer *vml )
{
start_download_thread ( vml, vml->redownload_vvp, &(vml->redownload_ul), &(vml->redownload_br), REDOWNLOAD_BAD );
static gboolean maps_layer_download_release ( VikMapsLayer *vml, GdkEventButton *event, VikViewport *vvp )
{
-
+ if (!vml || vml->vl.type != VIK_LAYER_MAPS)
+ return FALSE;
if ( vml->dl_tool_x != -1 && vml->dl_tool_y != -1 )
{
if ( event->button == 1 )
VikCoord ul, br;
vik_viewport_screen_to_coord ( vvp, MAX(0, MIN(event->x, vml->dl_tool_x)), MAX(0, MIN(event->y, vml->dl_tool_y)), &ul );
vik_viewport_screen_to_coord ( vvp, MIN(vik_viewport_get_width(vvp), MAX(event->x, vml->dl_tool_x)), MIN(vik_viewport_get_height(vvp), MAX ( event->y, vml->dl_tool_y ) ), &br );
- start_download_thread ( vml, vvp, &ul, &br, REDOWNLOAD_NONE );
+ start_download_thread ( vml, vvp, &ul, &br, DOWNLOAD_OR_REFRESH );
vml->dl_tool_x = vml->dl_tool_y = -1;
return TRUE;
}
return FALSE;
}
+static gpointer maps_layer_download_create ( VikWindow *vw, VikViewport *vvp)
+{
+ return vvp;
+}
+
static gboolean maps_layer_download_click ( VikMapsLayer *vml, GdkEventButton *event, VikViewport *vvp )
{
MapCoord tmp;
- if ( __map_types[vml->maptype].drawmode == vik_viewport_get_drawmode ( vvp ) &&
- __map_types[vml->maptype].coord_to_mapcoord ( vik_viewport_get_center ( vvp ),
+ if (!vml || vml->vl.type != VIK_LAYER_MAPS)
+ return FALSE;
+ VikMapsLayer_MapType *map_type = MAPS_LAYER_NTH_TYPE(vml->maptype);
+ if ( map_type->drawmode == vik_viewport_get_drawmode ( vvp ) &&
+ map_type->coord_to_mapcoord ( vik_viewport_get_center ( vvp ),
vml->xmapzoom ? vml->xmapzoom : vik_viewport_get_xmpp ( vvp ),
vml->ymapzoom ? vml->ymapzoom : vik_viewport_get_ympp ( vvp ),
&tmp ) ) {
#endif
}
-static void maps_layer_download_onscreen_maps ( gpointer vml_vvp[2] )
+static void download_onscreen_maps ( gpointer vml_vvp[2], gint redownload )
{
VikMapsLayer *vml = vml_vvp[0];
VikViewport *vvp = vml_vvp[1];
vik_viewport_screen_to_coord ( vvp, 0, 0, &ul );
vik_viewport_screen_to_coord ( vvp, vik_viewport_get_width(vvp), vik_viewport_get_height(vvp), &br );
- if ( __map_types[vml->maptype].drawmode == vik_viewport_get_drawmode ( vvp ) &&
- __map_types[vml->maptype].coord_to_mapcoord ( &ul, xzoom, yzoom, &ulm ) &&
- __map_types[vml->maptype].coord_to_mapcoord ( &br, xzoom, yzoom, &brm ) )
- start_download_thread ( vml, vvp, &ul, &br, REDOWNLOAD_NONE );
+ VikMapsLayer_MapType *map_type = MAPS_LAYER_NTH_TYPE(vml->maptype);
+ if ( map_type->drawmode == vik_viewport_get_drawmode ( vvp ) &&
+ map_type->coord_to_mapcoord ( &ul, xzoom, yzoom, &ulm ) &&
+ map_type->coord_to_mapcoord ( &br, xzoom, yzoom, &brm ) )
+ start_download_thread ( vml, vvp, &ul, &br, redownload );
else
a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), "Wrong drawmode / zoom level for this map." );
}
+static void maps_layer_download_onscreen_maps ( gpointer vml_vvp[2] )
+{
+ download_onscreen_maps( vml_vvp, REDOWNLOAD_NONE);
+}
+
+static void maps_layer_redownload_all_onscreen_maps ( gpointer vml_vvp[2] )
+{
+ download_onscreen_maps( vml_vvp, REDOWNLOAD_ALL);
+}
+
static void maps_layer_add_menu_items ( VikMapsLayer *vml, GtkMenu *menu, VikLayersPanel *vlp )
{
static gpointer pass_along[2];
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_download_onscreen_maps), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
+
+ 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 );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
}