#include "icons/icons.h"
#include "metatile.h"
#include "ui_util.h"
+#include "map_ids.h"
#ifdef HAVE_SQLITE3_H
#include "sqlite3.h"
{ 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;
(VikLayerFuncDraw) maps_layer_draw,
(VikLayerFuncChangeCoordMode) NULL,
+ (VikLayerFuncGetTimestamp) NULL,
+
(VikLayerFuncSetMenuItemsSelection) NULL,
(VikLayerFuncGetMenuItemsSelection) NULL,
#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)
{
if ( vml->cache_dir && strcmp ( vml->cache_dir, MAPS_CACHE_DIR ) == 0 && g_file_test ( vml->cache_dir, G_FILE_TEST_EXISTS ) == FALSE )
{
- g_mkdir ( vml->cache_dir, 0777 );
+ if ( g_mkdir ( vml->cache_dir, 0777 ) != 0 )
+ g_warning ( "%s: Failed to create directory %s", __FUNCTION__, vml->cache_dir );
}
}
// Ensure cache_dir always ends with a separator
guint len = strlen(canonical_dir);
- if ( canonical_dir[len-1] != G_DIR_SEPARATOR )
+ // Unless the dir is not valid
+ if ( len > 0 )
{
- vml->cache_dir = g_strconcat ( canonical_dir, G_DIR_SEPARATOR_S, NULL );
- g_free ( canonical_dir );
- }
- else {
- vml->cache_dir = canonical_dir;
- }
+ if ( canonical_dir[len-1] != G_DIR_SEPARATOR )
+ {
+ vml->cache_dir = g_strconcat ( canonical_dir, G_DIR_SEPARATOR_S, NULL );
+ g_free ( canonical_dir );
+ }
+ else {
+ vml->cache_dir = canonical_dir;
+ }
- maps_layer_mkdir_if_default_dir ( vml );
+ maps_layer_mkdir_if_default_dir ( vml );
+ }
}
static void maps_layer_set_file ( VikMapsLayer *vml, const gchar *name )
rv.s = "";
set = TRUE;
}
- else if ( is_file_operation ) {
+ else if ( is_file_operation && vml->cache_dir ) {
if ( a_vik_get_file_ref_format() == VIK_FILE_REF_FORMAT_RELATIVE ) {
gchar *cwd = g_get_current_dir();
if ( cwd ) {
rv.s = file_GetRelativeFilename ( cwd, vml->cache_dir );
if ( !rv.s ) rv.s = "";
set = TRUE;
- }
- }
+ }
+ }
}
if ( !set )
rv.s = vml->cache_dir ? vml->cache_dir : "";
// Get new value
VikLayerParamData vlpd = a_uibuilder_widget_get_value ( widget, values[UI_CHG_PARAM] );
// Is it *not* the OSM On Disk Tile Layout or the MBTiles type or the OSM Metatiles type
- gboolean sensitive = ( 21 != vlpd.u && 23 != vlpd.u && 24 != vlpd.u );
+ gboolean sensitive = ( MAP_ID_OSM_ON_DISK != vlpd.u &&
+ MAP_ID_MBTILES != vlpd.u &&
+ MAP_ID_OSM_METATILES != vlpd.u );
GtkWidget **ww1 = values[UI_CHG_WIDGETS];
GtkWidget **ww2 = values[UI_CHG_LABELS];
GtkWidget *w1 = ww1[PARAM_ONLYMISSING];
// File only applicable for MBTiles type
// Directory for all other types
- sensitive = ( 23 == vlpd.u);
+ sensitive = ( MAP_ID_MBTILES == vlpd.u);
GtkWidget *w5 = ww1[PARAM_FILE];
GtkWidget *w6 = ww2[PARAM_FILE];
GtkWidget *w7 = ww1[PARAM_CACHE_DIR];
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.
#endif
// If the on Disk OSM Tile Layout type
- if ( vml->maptype == 21 )
+ if ( vik_map_source_get_uniq_id(map) == MAP_ID_OSM_ON_DISK ) {
// Copy the directory into filename
// thus the mapcache look up will be unique when using more than one of these map types
+ g_free ( vml->filename );
vml->filename = g_strdup (vml->cache_dir);
+ }
}
static const gchar* maps_layer_tooltip ( VikMapsLayer *vml )
{
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;
}
GInputStream *stream = g_memory_input_stream_new_from_data ( data, bytes, NULL );
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_stream ( stream, NULL, &error );
- if (error || (!pixbuf)) {
+ if ( error ) {
g_warning ( "%s: %s", __FUNCTION__, error->message );
g_error_free ( error );
}
break;
}
}
- ans = sqlite3_finalize ( sql_stmt );
+ (void)sqlite3_finalize ( sql_stmt );
g_free ( statement );
int len;
int compressed;
- buf = malloc(tile_max);
+ buf = g_malloc(tile_max);
if (!buf) {
return NULL;
}
if (compressed) {
// Not handled yet - I don't think this is used often - so implement later if necessary
g_warning ( "Compressed metatiles not implemented:%s\n", __FUNCTION__);
+ g_free(buf);
return NULL;
}
GInputStream *stream = g_memory_input_stream_new_from_data ( buf, len, NULL );
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_stream ( stream, NULL, &error );
- if (error || (!pixbuf)) {
+ if (error) {
g_warning ( "%s: %s", __FUNCTION__, error->message );
g_error_free ( error );
}
g_input_stream_close ( stream, NULL, NULL );
- free(buf);
+ g_free(buf);
return pixbuf;
}
else {
+ g_free(buf);
g_warning ( "FAILED:%s %s", __FUNCTION__, err_msg);
return NULL;
}
}
-
+/**
+ * Caller has to decrease reference counter of returned
+ * GdkPixbuf, when buffer is no longer needed.
+ */
static GdkPixbuf *pixbuf_apply_settings ( GdkPixbuf *pixbuf, VikMapsLayer *vml, MapCoord *mapcoord, gdouble xshrinkfactor, gdouble yshrinkfactor )
{
// Apply alpha setting
pixbuf = pixbuf_shrink ( pixbuf, xshrinkfactor, yshrinkfactor );
if ( pixbuf )
- a_mapcache_add ( pixbuf, mapcoord->x, mapcoord->y,
+ a_mapcache_add ( pixbuf, (mapcache_extra_t) {0.0}, mapcoord->x, mapcoord->y,
mapcoord->z, vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(vml->maptype)),
mapcoord->scale, vml->alpha, xshrinkfactor, yshrinkfactor, vml->filename );
}
}
+/**
+ * Caller has to decrease reference counter of returned
+ * GdkPixbuf, when buffer is no longer needed.
+ */
static GdkPixbuf *get_pixbuf( VikMapsLayer *vml, guint16 id, const gchar* mapname, MapCoord *mapcoord, gchar *filename_buf, gint buf_len, gdouble xshrinkfactor, gdouble yshrinkfactor )
{
GdkPixbuf *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 );
+ g_object_unref(pixbuf);
return TRUE;
}
}
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 );
+ g_object_unref(pixbuf);
return TRUE;
}
}
yy -= (height/2);
vik_viewport_draw_pixbuf ( vvp, pixbuf, 0, 0, xx, yy, width, height );
+ g_object_unref(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 );
+ g_object_unref(pixbuf);
}
else {
// Otherwise try different scales
GError *gx = NULL;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx );
if (gx || (!pixbuf)) {
- g_remove ( mdi->filename_buf );
+ if ( g_remove ( mdi->filename_buf ) )
+ g_warning ( "REDOWNLOAD failed to remove: %s", mdi->filename_buf );
need_download = TRUE;
remove_mem_cache = TRUE;
g_error_free ( gx );
case REDOWNLOAD_ALL:
/* FIXME: need a better way than to erase file in case of server/network problem */
- g_remove ( mdi->filename_buf );
+ if ( g_remove ( mdi->filename_buf ) )
+ g_warning ( "REDOWNLOAD failed to remove: %s", mdi->filename_buf );
need_download = TRUE;
remove_mem_cache = TRUE;
break;
g_mutex_lock(mdi->mutex);
if (remove_mem_cache)
- a_mapcache_remove_all_shrinkfactors ( x, y, mdi->mapcoord.z, vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(mdi->maptype)), mdi->mapcoord.scale );
+ a_mapcache_remove_all_shrinkfactors ( x, y, mdi->mapcoord.z, vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(mdi->maptype)), mdi->mapcoord.scale, mdi->vml->filename );
if (mdi->refresh_display && mdi->map_layer_alive) {
/* TODO: check if it's on visible area */
vik_layer_emit_update ( VIK_LAYER(mdi->vml) ); // NB update display from background
vik_map_source_get_file_extension(MAPS_LAYER_NTH_TYPE(mdi->maptype)) );
if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == TRUE)
{
- g_remove ( mdi->filename_buf );
+ if ( g_remove ( mdi->filename_buf ) )
+ g_warning ( "Cleanup failed to remove: %s", mdi->filename_buf );
}
}
}
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 */
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
start_download_thread ( vml, vml->redownload_vvp, &(vml->redownload_ul), &(vml->redownload_br), REDOWNLOAD_NEW );
}
+#if !GLIB_CHECK_VERSION(2,26,0)
+typedef struct stat GStatBuf;
+#endif
+
/**
* Display a simple dialog with information about this particular map tile
*/
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",
- vik_map_source_default_get_hostname ( VIK_MAP_SOURCE_DEFAULT(map) ),
- vik_map_source_default_get_uri ( VIK_MAP_SOURCE_DEFAULT(map), &ulm ) );
+ source = g_markup_printf_escaped ( "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;
+ GStatBuf 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 );
}
}
}
+/**
+ *
+ */
+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;
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 );
+ }
}
/**