#include "icons/icons.h"
#include "metatile.h"
#include "ui_util.h"
+#include "map_ids.h"
#ifdef HAVE_SQLITE3_H
#include "sqlite3.h"
#define VIK_SETTINGS_MAP_REAL_MIN_SHRINKFACTOR "maps_real_min_shrinkfactor"
static gdouble REAL_MIN_SHRINKFACTOR = 0.0039062499; /* if shrinkfactor is between MAX and REAL_MAX, will only check for existence */
+#define VIK_SETTINGS_MAP_SCALE_INC_UP "maps_scale_inc_up"
+static guint SCALE_INC_UP = 2;
+#define VIK_SETTINGS_MAP_SCALE_INC_DOWN "maps_scale_inc_down"
+static guint SCALE_INC_DOWN = 4;
+#define VIK_SETTINGS_MAP_SCALE_SMALLER_ZOOM_FIRST "maps_scale_smaller_zoom_first"
+static gboolean SCALE_SMALLER_ZOOM_FIRST = TRUE;
+
/****** MAP TYPES ******/
static GList *__map_types = NULL;
{ 0, 255, 3, 0 }, /* alpha */
};
-static VikLayerParamData id_default ( void ) { return VIK_LPD_UINT ( 19 ); } // OSM MapQuest maps
+static VikLayerParamData id_default ( void ) { return VIK_LPD_UINT ( MAP_ID_MAPQUEST_OSM ); }
static VikLayerParamData directory_default ( void )
{
VikLayerParamData data;
if ( a_settings_get_double ( VIK_SETTINGS_MAP_REAL_MIN_SHRINKFACTOR, &gdtmp ) )
REAL_MIN_SHRINKFACTOR = gdtmp;
+
+ gint gitmp = 0;
+ if ( a_settings_get_integer ( VIK_SETTINGS_MAP_SCALE_INC_UP, &gitmp ) )
+ SCALE_INC_UP = gitmp;
+
+ if ( a_settings_get_integer ( VIK_SETTINGS_MAP_SCALE_INC_DOWN, &gitmp ) )
+ SCALE_INC_DOWN = gitmp;
+
+ gboolean gbtmp = TRUE;
+ if ( a_settings_get_boolean ( VIK_SETTINGS_MAP_SCALE_SMALLER_ZOOM_FIRST, &gbtmp ) )
+ SCALE_SMALLER_ZOOM_FIRST = gbtmp;
+
}
/****************************************/
#define MAPS_LAYER_NTH_ID(n) (params_maptypes_ids[n])
#define MAPS_LAYER_NTH_TYPE(n) (VIK_MAP_SOURCE(g_list_nth_data(__map_types, (n))))
-gint vik_maps_layer_get_map_type(VikMapsLayer *vml)
+/**
+ * vik_maps_layer_get_map_type:
+ *
+ * Returns the actual map id (rather than the internal type index value)
+ */
+guint vik_maps_layer_get_map_type(VikMapsLayer *vml)
+{
+ return MAPS_LAYER_NTH_ID(vml->maptype);
+}
+
+/**
+ * vik_maps_layer_set_map_type:
+ *
+ */
+void vik_maps_layer_set_map_type(VikMapsLayer *vml, guint map_type)
+{
+ gint maptype = map_uniq_id_to_index(map_type);
+ if ( maptype == NUM_MAP_TYPES )
+ g_warning(_("Unknown map type"));
+ else
+ vml->maptype = maptype;
+}
+
+/**
+ * vik_maps_layer_get_default_map_type:
+ *
+ */
+guint vik_maps_layer_get_default_map_type ()
{
- return(vml->maptype);
+ VikLayerInterface *vli = vik_layer_get_interface ( VIK_LAYER_MAPS );
+ VikLayerParamData vlpd = a_layer_defaults_get ( vli->fixed_layer_name, "mode", VIK_LAYER_PARAM_UINT );
+ if ( vlpd.u == 0 )
+ vlpd = id_default();
+ return vlpd.u;
}
gchar *vik_maps_layer_get_map_label(VikMapsLayer *vml)
VikMapsLayer *vml = VIK_MAPS_LAYER(vl);
VikMapSource *map = MAPS_LAYER_NTH_TYPE(vml->maptype);
- if (from_file != TRUE)
+ if (!from_file)
{
/* If this method is not called in file reading context
* it is called in GUI context.
{
VikMapsLayer *rv = maps_layer_new ( vvp );
vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
+ maps_layer_post_read ( VIK_LAYER(rv), vvp, FALSE );
return rv;
}
return TRUE;
}
+/**
+ *
+ */
+gboolean try_draw_scale_down (VikMapsLayer *vml, VikViewport *vvp, MapCoord ulm, gint xx, gint yy, gint tilesize_x_ceil, gint tilesize_y_ceil,
+ gdouble xshrinkfactor, gdouble yshrinkfactor, guint id, const gchar *mapname, gchar *path_buf, guint max_path_len)
+{
+ GdkPixbuf *pixbuf;
+ int scale_inc;
+ for (scale_inc = 1; scale_inc < SCALE_INC_DOWN; scale_inc ++) {
+ // Try with smaller zooms
+ int scale_factor = 1 << scale_inc; /* 2^scale_inc */
+ MapCoord ulm2 = ulm;
+ ulm2.x = ulm.x / scale_factor;
+ ulm2.y = ulm.y / scale_factor;
+ ulm2.scale = ulm.scale + scale_inc;
+ pixbuf = get_pixbuf ( vml, id, mapname, &ulm2, path_buf, max_path_len, xshrinkfactor * scale_factor, yshrinkfactor * scale_factor );
+ if ( pixbuf ) {
+ gint src_x = (ulm.x % scale_factor) * tilesize_x_ceil;
+ gint src_y = (ulm.y % scale_factor) * tilesize_y_ceil;
+ vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, xx, yy, tilesize_x_ceil, tilesize_y_ceil );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ *
+ */
+gboolean try_draw_scale_up (VikMapsLayer *vml, VikViewport *vvp, MapCoord ulm, gint xx, gint yy, gint tilesize_x_ceil, gint tilesize_y_ceil,
+ gdouble xshrinkfactor, gdouble yshrinkfactor, guint id, const gchar *mapname, gchar *path_buf, guint max_path_len)
+{
+ GdkPixbuf *pixbuf;
+ // Try with bigger zooms
+ int scale_dec;
+ for (scale_dec = 1; scale_dec < SCALE_INC_UP; scale_dec ++) {
+ int pict_x, pict_y;
+ int scale_factor = 1 << scale_dec; /* 2^scale_dec */
+ MapCoord ulm2 = ulm;
+ ulm2.x = ulm.x * scale_factor;
+ ulm2.y = ulm.y * scale_factor;
+ ulm2.scale = ulm.scale - scale_dec;
+ for (pict_x = 0; pict_x < scale_factor; pict_x ++) {
+ for (pict_y = 0; pict_y < scale_factor; pict_y ++) {
+ MapCoord ulm3 = ulm2;
+ ulm3.x += pict_x;
+ ulm3.y += pict_y;
+ pixbuf = get_pixbuf ( vml, id, mapname, &ulm3, path_buf, max_path_len, xshrinkfactor / scale_factor, yshrinkfactor / scale_factor );
+ if ( pixbuf ) {
+ gint src_x = 0;
+ gint src_y = 0;
+ gint dest_x = xx + pict_x * (tilesize_x_ceil / scale_factor);
+ gint dest_y = yy + pict_y * (tilesize_y_ceil / scale_factor);
+ vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, dest_x, dest_y, tilesize_x_ceil / scale_factor, tilesize_y_ceil / scale_factor );
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
static void maps_layer_draw_section ( VikMapsLayer *vml, VikViewport *vvp, VikCoord *ul, VikCoord *br )
{
MapCoord ulm, brm;
vik_viewport_draw_line ( vvp, black_gc, xx+tilesize_x_ceil, yy, xx, yy+tilesize_y_ceil );
}
} else {
- int scale_inc;
- for (scale_inc = 0; scale_inc < 4; scale_inc ++) {
- /* try with correct then smaller zooms */
- int scale_factor = 1 << scale_inc; /* 2^scale_inc */
- MapCoord ulm2 = ulm;
- ulm2.x = ulm.x / scale_factor;
- ulm2.y = ulm.y / scale_factor;
- ulm2.scale = ulm.scale + scale_inc;
- pixbuf = get_pixbuf ( vml, id, mapname, &ulm2, path_buf, max_path_len, xshrinkfactor * scale_factor, yshrinkfactor * scale_factor );
- if ( pixbuf ) {
- gint src_x = (ulm.x % scale_factor) * tilesize_x_ceil;
- gint src_y = (ulm.y % scale_factor) * tilesize_y_ceil;
-#ifdef DEBUG
- printf("maps_layer_draw_section - x=%d, y=%d, z=%d, src_x=%d, src_y=%d, xx=%d, yy=%d - %x\n", ulm.x, ulm.y, ulm.scale, src_x, src_y, (int)xx, (int)yy, vvp);
-#endif
- vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, xx, yy, tilesize_x_ceil, tilesize_y_ceil );
- break;
- }
+ // Try correct scale first
+ int scale_factor = 1;
+ pixbuf = get_pixbuf ( vml, id, mapname, &ulm, path_buf, max_path_len, xshrinkfactor * scale_factor, yshrinkfactor * scale_factor );
+ if ( pixbuf ) {
+ gint src_x = (ulm.x % scale_factor) * tilesize_x_ceil;
+ gint src_y = (ulm.y % scale_factor) * tilesize_y_ceil;
+ vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, xx, yy, tilesize_x_ceil, tilesize_y_ceil );
}
- if ( !pixbuf ) {
- /* retry with bigger zooms */
- int scale_dec;
- for (scale_dec = 1; scale_dec < 2; scale_dec ++) {
- int pict_x, pict_y;
- int scale_factor = 1 << scale_dec; /* 2^scale_dec */
- MapCoord ulm2 = ulm;
- ulm2.x = ulm.x * scale_factor;
- ulm2.y = ulm.y * scale_factor;
- ulm2.scale = ulm.scale - scale_dec;
- for (pict_x = 0; pict_x < scale_factor; pict_x ++) {
- for (pict_y = 0; pict_y < scale_factor; pict_y ++) {
- MapCoord ulm3 = ulm2;
- ulm3.x += pict_x;
- ulm3.y += pict_y;
- pixbuf = get_pixbuf ( vml, id, mapname, &ulm3, path_buf, max_path_len, xshrinkfactor / scale_factor, yshrinkfactor / scale_factor );
- if ( pixbuf ) {
- gint src_x = 0;
- gint src_y = 0;
- gint dest_x = xx + pict_x * (tilesize_x_ceil / scale_factor);
- gint dest_y = yy + pict_y * (tilesize_y_ceil / scale_factor);
- vik_viewport_draw_pixbuf ( vvp, pixbuf, src_x, src_y, dest_x, dest_y, tilesize_x_ceil / scale_factor, tilesize_y_ceil / scale_factor );
- }
- }
+ else {
+ // Otherwise try different scales
+ if ( SCALE_SMALLER_ZOOM_FIRST ) {
+ if ( !try_draw_scale_down(vml,vvp,ulm,xx,yy,tilesize_x_ceil,tilesize_y_ceil,xshrinkfactor,yshrinkfactor,id,mapname,path_buf,max_path_len) ) {
+ try_draw_scale_up(vml,vvp,ulm,xx,yy,tilesize_x_ceil,tilesize_y_ceil,xshrinkfactor,yshrinkfactor,id,mapname,path_buf,max_path_len);
+ }
+ }
+ else {
+ if ( !try_draw_scale_up(vml,vvp,ulm,xx,yy,tilesize_x_ceil,tilesize_y_ceil,xshrinkfactor,yshrinkfactor,id,mapname,path_buf,max_path_len) ) {
+ try_draw_scale_down(vml,vvp,ulm,xx,yy,tilesize_x_ceil,tilesize_y_ceil,xshrinkfactor,yshrinkfactor,id,mapname,path_buf,max_path_len);
}
}
}
}
xx += tilesize_x;
}
- }
+ // ATM Only show tile grid lines in extreme debug mode
+ if ( vik_debug && vik_verbose ) {
+ /* Grid drawing here so it gets drawn on top of the map */
+ /* Thus loop around x & y again, but this time separately */
+ /* Only showing grid for the current scale */
+ GdkGC *black_gc = GTK_WIDGET(vvp)->style->black_gc;
+ /* Draw single grid lines across the whole screen */
+ gint width = vik_viewport_get_width(vvp);
+ gint height = vik_viewport_get_height(vvp);
+ xx = xx_tmp; yy = yy_tmp;
+ gint base_xx = xx - (tilesize_x/2);
+ base_yy = yy - (tilesize_y/2);
+
+ xx = base_xx;
+ for ( x = ((xinc == 1) ? xmin : xmax); x != xend; x+=xinc ) {
+ vik_viewport_draw_line ( vvp, black_gc, xx, base_yy, xx, height );
+ xx += tilesize_x;
+ }
+
+ yy = base_yy;
+ for ( y = ((yinc == 1) ? ymin : ymax); y != yend; y+=yinc ) {
+ vik_viewport_draw_line ( vvp, black_gc, base_xx, yy, width, yy );
+ yy += tilesize_y;
+ }
+ }
+
+ }
g_free ( path_buf );
}
}
static void mdi_free ( MapDownloadInfo *mdi )
{
- g_mutex_free(mdi->mutex);
+ vik_mutex_free(mdi->mutex);
g_free ( mdi->cache_dir );
mdi->cache_dir = NULL;
g_free ( mdi->filename_buf );
mdi->vml = vml;
mdi->vvp = vvp;
mdi->map_layer_alive = TRUE;
- mdi->mutex = g_mutex_new();
+ mdi->mutex = vik_mutex_new();
mdi->refresh_display = TRUE;
/* cache_dir and buffer for dest filename */
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 */
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ 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 */
mdi->vml = vml;
mdi->vvp = vvp;
mdi->map_layer_alive = TRUE;
- mdi->mutex = g_mutex_new();
+ mdi->mutex = vik_mutex_new();
mdi->refresh_display = TRUE;
mdi->cache_dir = g_strdup ( vml->cache_dir );
tmp = g_strdup_printf ( fmt, mdi->mapstoget, MAPS_LAYER_NTH_LABEL(vml->maptype) );
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 );
+
+ // launch the thread
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ 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
return;
gchar *filename = NULL;
- gchar *message = NULL;
gchar *source = NULL;
if ( vik_map_source_is_direct_file_access ( map ) ) {
exists = g_strdup ( _("NO") );
gint flip_y = (gint) pow(2, zoom)-1 - ulm.y;
// NB Also handles .jpg automatically due to pixbuf_new_from () support - although just print png for now.
- source = g_strdup_printf ( "%s (%d%s%d%s%d.%s %s)", filename, zoom, G_DIR_SEPARATOR_S, ulm.x, G_DIR_SEPARATOR_S, flip_y, "png", exists );
+ source = g_strdup_printf ( "Source: %s (%d%s%d%s%d.%s %s)", filename, zoom, G_DIR_SEPARATOR_S, ulm.x, G_DIR_SEPARATOR_S, flip_y, "png", exists );
g_free ( exists );
#else
- source = g_strdup ( _("Not available") );
+ source = g_strdup ( _("Source: Not available") );
#endif
}
else if ( vik_map_source_is_osm_meta_tiles ( map ) ) {
NULL,
ulm.scale, ulm.z, ulm.x, ulm.y, filename, max_path_len,
vik_map_source_get_file_extension(map) );
- source = g_strconcat ( "file://", filename, NULL );
+ source = g_strconcat ( "Source: file://", filename, NULL );
}
}
else {
vik_map_source_get_name(map),
ulm.scale, ulm.z, ulm.x, ulm.y, filename, max_path_len,
vik_map_source_get_file_extension(map) );
- source = g_strdup_printf ( "http://%s%s",
+ source = g_strdup_printf ( "Source: http://%s%s",
vik_map_source_default_get_hostname ( VIK_MAP_SOURCE_DEFAULT(map) ),
vik_map_source_default_get_uri ( VIK_MAP_SOURCE_DEFAULT(map), &ulm ) );
}
- if ( g_file_test ( filename, G_FILE_TEST_EXISTS ) ) {
+ GArray *array = g_array_new (FALSE, TRUE, sizeof(gchar*));
+ g_array_append_val ( array, source );
+ gchar *filemsg = NULL;
+ gchar *timemsg = NULL;
+
+ if ( g_file_test ( filename, G_FILE_TEST_EXISTS ) ) {
+ filemsg = g_strconcat ( "Tile File: ", filename, NULL );
// Get some timestamp information of the tile
struct stat stat_buf;
if ( g_stat ( filename, &stat_buf ) == 0 ) {
gchar time_buf[64];
strftime ( time_buf, sizeof(time_buf), "%c", gmtime((const time_t *)&stat_buf.st_mtime) );
- message = g_strdup_printf ( _("\nSource: %s\n\nTile File: %s\nTile File Timestamp: %s"), source, filename, time_buf );
+ timemsg = g_strdup_printf ( _("Tile File Timestamp: %s"), time_buf );
}
else {
- message = g_strdup_printf ( _("\nSource: %s\n\nTile File: %s\nTile File Timestamp: Not Available"), source, filename );
+ timemsg = g_strdup ( _("Tile File Timestamp: Not Available") );
}
- // Show the info
- a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), message );
+ g_array_append_val ( array, filemsg );
+ g_array_append_val ( array, timemsg );
}
else {
- message = g_strdup_printf ( _("\nSource: %s\n\nTile File: %s [Not Available]"), source, filename );
- a_dialog_warning_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml), message );
+ filemsg = g_strdup_printf ( "Tile File: %s [Not Available]", filename );
+ g_array_append_val ( array, filemsg );
}
- g_free ( message );
+ a_dialog_list ( VIK_GTK_WINDOW_FROM_LAYER(vml), _("Tile Information"), array, 5 );
+ g_array_free ( array, FALSE );
+
+ g_free ( timemsg );
+ g_free ( filemsg );
g_free ( source );
g_free ( filename );
}
download_onscreen_maps( values, REDOWNLOAD_ALL);
}
-static void maps_layers_about ( gpointer vml_vvp[2] )
+static void maps_layer_about ( gpointer vml_vvp[2] )
{
VikMapsLayer *vml = vml_vvp[0];
VikMapSource *map = MAPS_LAYER_NTH_TYPE(vml->maptype);
mdi->vml = vml;
mdi->vvp = vvp;
mdi->map_layer_alive = TRUE;
- mdi->mutex = g_mutex_new();
+ mdi->mutex = vik_mutex_new();
mdi->refresh_display = FALSE;
mdi->cache_dir = g_strdup ( vml->cache_dir );
}
}
+/**
+ *
+ */
+static void maps_layer_flush ( menu_array_values values )
+{
+ VikMapsLayer *vml = VIK_MAPS_LAYER(values[MA_VML]);
+ a_mapcache_flush_type ( vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(vml->maptype)) );
+}
+
static void maps_layer_add_menu_items ( VikMapsLayer *vml, GtkMenu *menu, VikLayersPanel *vlp )
{
GtkWidget *item;
gtk_widget_show ( item );
item = gtk_image_menu_item_new_from_stock ( GTK_STOCK_ABOUT, NULL );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layers_about), values );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_about), values );
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
+
+ // Typical users shouldn't need to use this functionality - so debug only ATM
+ if ( vik_debug ) {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Flush Map Cache") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(maps_layer_flush), values );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ }
}
/**