2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2005, Evan Battaglia <viking@greentorch.org>
5 * UTM multi-zone stuff by Kit Transue <notlostyet@didactek.com>
6 * Dynamic map type by Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define MAX_SHRINKFACTOR 8.0000001 /* zoom 1 viewing 8-tiles */
29 #define MIN_SHRINKFACTOR 0.0312499 /* zoom 32 viewing 1-tiles */
31 #define REAL_MIN_SHRINKFACTOR 0.0039062499 /* if shrinkfactor is between MAX and REAL_MAX, will only check for existence */
34 #include <gdk-pixbuf/gdk-pixdata.h>
36 #include <glib/gstdio.h>
37 #include <glib/gi18n.h>
49 #include "viktreeview.h"
50 #include "vikviewport.h"
52 #include "vikmapslayer.h"
59 /* only for dialog.h -- ugh */
60 #include "vikwaypoint.h"
63 #include "vikstatus.h"
64 #include "background.h"
66 #include "vikaggregatelayer.h"
67 #include "viklayerspanel.h"
70 #include "terraserver.h"
72 #include "icons/icons.h"
74 /****** MAP TYPES ******/
76 static GList
*__map_types
= NULL
;
78 #define NUM_MAP_TYPES g_list_length(__map_types)
80 /* List of label for each map type */
81 static GList
*params_maptypes
= NULL
;
83 /* Corresponding IDS. (Cf. field uniq_id in VikMapsLayer struct) */
84 static GList
*params_maptypes_ids
= NULL
;
86 /******** MAPZOOMS *********/
88 static gchar
*params_mapzooms
[] = { N_("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
};
89 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 };
90 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 };
92 #define NUM_MAPZOOMS (sizeof(params_mapzooms)/sizeof(params_mapzooms[0]) - 1)
94 /**************************/
97 static void maps_layer_post_read (VikLayer
*vl
, VikViewport
*vp
, gboolean from_file
);
98 static void maps_layer_marshall( VikMapsLayer
*vml
, guint8
**data
, gint
*len
);
99 static VikMapsLayer
*maps_layer_unmarshall( guint8
*data
, gint len
, VikViewport
*vvp
);
100 static gboolean
maps_layer_set_param ( VikMapsLayer
*vml
, guint16 id
, VikLayerParamData data
, VikViewport
*vvp
);
101 static VikLayerParamData
maps_layer_get_param ( VikMapsLayer
*vml
, guint16 id
);
102 static void maps_layer_draw ( VikMapsLayer
*vml
, VikViewport
*vvp
);
103 static VikMapsLayer
*maps_layer_new ( VikViewport
*vvp
);
104 static void maps_layer_free ( VikMapsLayer
*vml
);
105 static gboolean
maps_layer_download_release ( VikMapsLayer
*vml
, GdkEventButton
*event
, VikViewport
*vvp
);
106 static gboolean
maps_layer_download_click ( VikMapsLayer
*vml
, GdkEventButton
*event
, VikViewport
*vvp
);
107 static gpointer
maps_layer_download_create ( VikWindow
*vw
, VikViewport
*vvp
);
108 static void maps_layer_set_cache_dir ( VikMapsLayer
*vml
, const gchar
*dir
);
109 static void start_download_thread ( VikMapsLayer
*vml
, VikViewport
*vvp
, const VikCoord
*ul
, const VikCoord
*br
, gint redownload
);
110 static void maps_layer_add_menu_items ( VikMapsLayer
*vml
, GtkMenu
*menu
, VikLayersPanel
*vlp
);
113 static VikLayerParamScale params_scales
[] = {
114 /* min, max, step, digits (decimal places) */
115 { 0, 255, 3, 0 }, /* alpha */
118 VikLayerParam maps_layer_params
[] = {
119 { "mode", VIK_LAYER_PARAM_UINT
, VIK_LAYER_GROUP_NONE
, N_("Map Type:"), VIK_LAYER_WIDGET_RADIOGROUP
, NULL
, NULL
},
120 { "directory", VIK_LAYER_PARAM_STRING
, VIK_LAYER_GROUP_NONE
, N_("Maps Directory (Optional):"), VIK_LAYER_WIDGET_FILEENTRY
},
121 { "alpha", VIK_LAYER_PARAM_UINT
, VIK_LAYER_GROUP_NONE
, N_("Alpha:"), VIK_LAYER_WIDGET_HSCALE
, params_scales
},
122 { "autodownload", VIK_LAYER_PARAM_BOOLEAN
, VIK_LAYER_GROUP_NONE
, N_("Autodownload maps:"), VIK_LAYER_WIDGET_CHECKBUTTON
},
123 { "mapzoom", VIK_LAYER_PARAM_UINT
, VIK_LAYER_GROUP_NONE
, N_("Zoom Level:"), VIK_LAYER_WIDGET_COMBOBOX
, params_mapzooms
},
126 enum { PARAM_MAPTYPE
=0, PARAM_CACHE_DIR
, PARAM_ALPHA
, PARAM_AUTODOWNLOAD
, PARAM_MAPZOOM
, NUM_PARAMS
};
128 static VikToolInterface maps_tools
[] = {
129 { N_("Maps Download"), (VikToolConstructorFunc
) maps_layer_download_create
, NULL
, NULL
, NULL
,
130 (VikToolMouseFunc
) maps_layer_download_click
, NULL
, (VikToolMouseFunc
) maps_layer_download_release
,
131 (VikToolKeyFunc
) NULL
, GDK_CURSOR_IS_PIXMAP
, &cursor_mapdl_pixbuf
},
134 VikLayerInterface vik_maps_layer_interface
= {
136 &vikmapslayer_pixbuf
,
139 sizeof(maps_tools
) / sizeof(maps_tools
[0]),
148 (VikLayerFuncCreate
) maps_layer_new
,
149 (VikLayerFuncRealize
) NULL
,
150 (VikLayerFuncPostRead
) maps_layer_post_read
,
151 (VikLayerFuncFree
) maps_layer_free
,
153 (VikLayerFuncProperties
) NULL
,
154 (VikLayerFuncDraw
) maps_layer_draw
,
155 (VikLayerFuncChangeCoordMode
) NULL
,
157 (VikLayerFuncSetMenuItemsSelection
) NULL
,
158 (VikLayerFuncGetMenuItemsSelection
) NULL
,
160 (VikLayerFuncAddMenuItems
) maps_layer_add_menu_items
,
161 (VikLayerFuncSublayerAddMenuItems
) NULL
,
163 (VikLayerFuncSublayerRenameRequest
) NULL
,
164 (VikLayerFuncSublayerToggleVisible
) NULL
,
166 (VikLayerFuncMarshall
) maps_layer_marshall
,
167 (VikLayerFuncUnmarshall
) maps_layer_unmarshall
,
169 (VikLayerFuncSetParam
) maps_layer_set_param
,
170 (VikLayerFuncGetParam
) maps_layer_get_param
,
172 (VikLayerFuncReadFileData
) NULL
,
173 (VikLayerFuncWriteFileData
) NULL
,
175 (VikLayerFuncDeleteItem
) NULL
,
176 (VikLayerFuncCopyItem
) NULL
,
177 (VikLayerFuncPasteItem
) NULL
,
178 (VikLayerFuncFreeCopiedItem
) NULL
,
179 (VikLayerFuncDragDropRequest
) NULL
,
182 struct _VikMapsLayer
{
188 gdouble xmapzoom
, ymapzoom
;
190 gboolean autodownload
;
191 VikCoord
*last_center
;
195 gint dl_tool_x
, dl_tool_y
;
197 GtkMenu
*dl_right_click_menu
;
198 VikCoord redownload_ul
, redownload_br
; /* right click menu only */
199 VikViewport
*redownload_vvp
;
202 enum { REDOWNLOAD_NONE
= 0, /* download only missing maps */
203 REDOWNLOAD_BAD
, /* download missing and bad maps */
204 REDOWNLOAD_NEW
, /* download missing maps that are newer on server only */
205 REDOWNLOAD_ALL
, /* download all maps */
206 DOWNLOAD_OR_REFRESH
}; /* download missing maps and refresh cache */
209 /****************************************/
210 /******** MAPS LAYER TYPES **************/
211 /****************************************/
213 void maps_layer_register_type ( const char *label
, guint id
, VikMapsLayer_MapType
*map_type
)
215 g_assert(label
!= NULL
);
216 g_assert(map_type
!= NULL
);
217 g_assert(id
== map_type
->uniq_id
);
220 params_maptypes
= g_list_append(params_maptypes
, g_strdup(label
));
223 params_maptypes_ids
= g_list_append(params_maptypes_ids
, GUINT_TO_POINTER (id
));
225 /* We have to clone */
226 VikMapsLayer_MapType
*clone
= g_memdup(map_type
, sizeof(VikMapsLayer_MapType
));
227 /* Register the clone in the list */
228 __map_types
= g_list_append(__map_types
, clone
);
231 We have to ensure the mode LayerParam reference the up-to-date
235 memcpy(&maps_layer_params[0].widget_data, ¶ms_maptypes, sizeof(gpointer));
236 memcpy(&maps_layer_params[0].extra_widget_data, ¶ms_maptypes_ids, sizeof(gpointer));
238 maps_layer_params
[0].widget_data
= params_maptypes
;
239 maps_layer_params
[0].extra_widget_data
= params_maptypes_ids
;
242 #define MAPS_LAYER_NTH_LABEL(n) ((gchar*)g_list_nth_data(params_maptypes, (n)))
243 #define MAPS_LAYER_NTH_ID(n) ((guint)g_list_nth_data(params_maptypes_ids, (n)))
244 #define MAPS_LAYER_NTH_TYPE(n) ((VikMapsLayer_MapType*)g_list_nth_data(__map_types, (n)))
246 gint
vik_maps_layer_get_map_type(VikMapsLayer
*vml
)
248 return(vml
->maptype
);
251 gchar
*vik_maps_layer_get_map_label(VikMapsLayer
*vml
)
253 return(g_strdup(MAPS_LAYER_NTH_LABEL(vml
->maptype
)));
256 /****************************************/
257 /******** CACHE DIR STUFF ***************/
258 /****************************************/
260 #define DIRSTRUCTURE "%st%ds%dz%d" G_DIR_SEPARATOR_S "%d" G_DIR_SEPARATOR_S "%d"
261 #define MAPS_CACHE_DIR maps_layer_default_dir()
265 #define GLOBAL_MAPS_DIR "C:\\VIKING-MAPS\\"
266 #define LOCAL_MAPS_DIR "VIKING-MAPS"
269 #define GLOBAL_MAPS_DIR "/var/cache/maps/"
270 #define LOCAL_MAPS_DIR ".viking-maps"
273 gchar
*maps_layer_default_dir ()
275 static gchar
*defaultdir
= NULL
;
278 /* Thanks to Mike Davison for the $VIKING_MAPS usage */
279 const gchar
*mapdir
= g_getenv("VIKING_MAPS");
281 defaultdir
= g_strdup ( mapdir
);
282 } else if ( g_access ( GLOBAL_MAPS_DIR
, W_OK
) == 0 ) {
283 defaultdir
= g_strdup ( GLOBAL_MAPS_DIR
);
285 const gchar
*home
= g_get_home_dir();
286 if (!home
|| g_access(home
, W_OK
))
287 home
= g_get_home_dir ();
289 defaultdir
= g_build_filename ( home
, LOCAL_MAPS_DIR
, NULL
);
291 defaultdir
= g_strdup ( LOCAL_MAPS_DIR
);
293 if (defaultdir
&& (defaultdir
[strlen(defaultdir
)-1] != G_DIR_SEPARATOR
))
295 /* Add the separator at the end */
296 gchar
*tmp
= defaultdir
;
297 defaultdir
= g_strconcat(tmp
, G_DIR_SEPARATOR_S
, NULL
);
300 g_debug("%s: defaultdir=%s", __FUNCTION__
, defaultdir
);
305 static void maps_layer_mkdir_if_default_dir ( VikMapsLayer
*vml
)
307 if ( vml
->cache_dir
&& strcmp ( vml
->cache_dir
, MAPS_CACHE_DIR
) == 0 && g_file_test ( vml
->cache_dir
, G_FILE_TEST_EXISTS
) == FALSE
)
309 g_mkdir ( vml
->cache_dir
, 0777 );
313 static void maps_layer_set_cache_dir ( VikMapsLayer
*vml
, const gchar
*dir
)
316 g_assert ( vml
!= NULL
);
317 g_free ( vml
->cache_dir
);
318 vml
->cache_dir
= NULL
;
320 if ( dir
== NULL
|| dir
[0] == '\0' )
321 vml
->cache_dir
= g_strdup ( MAPS_CACHE_DIR
);
325 if ( dir
[len
-1] != G_DIR_SEPARATOR
)
327 vml
->cache_dir
= g_malloc ( len
+2 );
328 strncpy ( vml
->cache_dir
, dir
, len
);
329 vml
->cache_dir
[len
] = G_DIR_SEPARATOR
;
330 vml
->cache_dir
[len
+1] = '\0';
333 vml
->cache_dir
= g_strdup ( dir
);
335 maps_layer_mkdir_if_default_dir ( vml
);
338 /****************************************/
339 /******** GOBJECT STUFF *****************/
340 /****************************************/
342 GType
vik_maps_layer_get_type ()
344 static GType vml_type
= 0;
348 static const GTypeInfo vml_info
=
350 sizeof (VikMapsLayerClass
),
351 NULL
, /* base_init */
352 NULL
, /* base_finalize */
353 NULL
, /* class init */
354 NULL
, /* class_finalize */
355 NULL
, /* class_data */
356 sizeof (VikMapsLayer
),
358 NULL
/* instance init */
360 vml_type
= g_type_register_static ( VIK_LAYER_TYPE
, "VikMapsLayer", &vml_info
, 0 );
366 /****************************************/
367 /************** PARAMETERS **************/
368 /****************************************/
370 static guint
map_index_to_uniq_id (guint8 index
)
372 g_assert ( index
< NUM_MAP_TYPES
);
373 return MAPS_LAYER_NTH_TYPE(index
)->uniq_id
;
376 static guint
map_uniq_id_to_index ( guint uniq_id
)
379 for ( i
= 0; i
< NUM_MAP_TYPES
; i
++ )
380 if ( MAPS_LAYER_NTH_TYPE(i
)->uniq_id
== uniq_id
)
382 return NUM_MAP_TYPES
; /* no such thing */
385 static gboolean
maps_layer_set_param ( VikMapsLayer
*vml
, guint16 id
, VikLayerParamData data
, VikViewport
*vvp
)
389 case PARAM_CACHE_DIR
: maps_layer_set_cache_dir ( vml
, data
.s
); break;
390 case PARAM_MAPTYPE
: {
391 gint maptype
= map_uniq_id_to_index(data
.u
);
392 if ( maptype
== NUM_MAP_TYPES
) g_warning(_("Unknown map type"));
393 else vml
->maptype
= maptype
;
396 case PARAM_ALPHA
: if ( data
.u
<= 255 ) vml
->alpha
= data
.u
; break;
397 case PARAM_AUTODOWNLOAD
: vml
->autodownload
= data
.b
; break;
398 case PARAM_MAPZOOM
: if ( data
.u
< NUM_MAPZOOMS
) {
399 vml
->mapzoom_id
= data
.u
;
400 vml
->xmapzoom
= __mapzooms_x
[data
.u
];
401 vml
->ymapzoom
= __mapzooms_y
[data
.u
];
402 }else g_warning (_("Unknown Map Zoom")); break;
407 static VikLayerParamData
maps_layer_get_param ( VikMapsLayer
*vml
, guint16 id
)
409 VikLayerParamData rv
;
412 case PARAM_CACHE_DIR
: rv
.s
= (vml
->cache_dir
&& strcmp(vml
->cache_dir
, MAPS_CACHE_DIR
) != 0) ? vml
->cache_dir
: ""; break;
413 case PARAM_MAPTYPE
: rv
.u
= map_index_to_uniq_id ( vml
->maptype
); break;
414 case PARAM_ALPHA
: rv
.u
= vml
->alpha
; break;
415 case PARAM_AUTODOWNLOAD
: rv
.u
= vml
->autodownload
; break;
416 case PARAM_MAPZOOM
: rv
.u
= vml
->mapzoom_id
; break;
421 /****************************************/
422 /****** CREATING, COPYING, FREEING ******/
423 /****************************************/
425 static VikMapsLayer
*maps_layer_new ( VikViewport
*vvp
)
428 VikMapsLayer
*vml
= VIK_MAPS_LAYER ( g_object_new ( VIK_MAPS_LAYER_TYPE
, NULL
) );
429 vik_layer_init ( VIK_LAYER(vml
), VIK_LAYER_MAPS
);
430 idx
= map_uniq_id_to_index(7); /* 7 is id for google maps */
431 vml
->maptype
= (idx
< NUM_MAP_TYPES
) ? idx
: 0;
434 vml
->dl_tool_x
= vml
->dl_tool_y
= -1;
435 maps_layer_set_cache_dir ( vml
, NULL
);
436 vml
->autodownload
= FALSE
;
437 vml
->last_center
= NULL
;
438 vml
->last_xmpp
= 0.0;
439 vml
->last_ympp
= 0.0;
441 vml
->dl_right_click_menu
= NULL
;
446 static void maps_layer_free ( VikMapsLayer
*vml
)
448 g_free ( vml
->cache_dir
);
449 vml
->cache_dir
= NULL
;
450 if ( vml
->dl_right_click_menu
)
451 gtk_object_sink ( GTK_OBJECT(vml
->dl_right_click_menu
) );
452 g_free(vml
->last_center
);
453 vml
->last_center
= NULL
;
456 static void maps_layer_post_read (VikLayer
*vl
, VikViewport
*vp
, gboolean from_file
)
458 if (from_file
!= TRUE
)
460 /* If this method is not called in file reading context
461 * it is called in GUI context.
462 * So, we can check if we have to inform the user about inconsistency */
463 VikViewportDrawMode vp_drawmode
;
464 VikMapsLayer
*vml
= VIK_MAPS_LAYER(vl
);
465 VikMapsLayer_MapType
*map_type
= NULL
;
467 vp_drawmode
= vik_viewport_get_drawmode ( VIK_VIEWPORT(vp
) );
468 map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
469 if (map_type
->drawmode
!= vp_drawmode
) {
470 const gchar
*drawmode_name
= vik_viewport_get_drawmode_name (VIK_VIEWPORT(vp
), map_type
->drawmode
);
471 gchar
*msg
= g_strdup_printf(_("New map cannot be displayed in the current drawmode.\nSelect \"%s\" from View menu to view it."), drawmode_name
);
472 a_dialog_warning_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml
), msg
);
478 static void maps_layer_marshall( VikMapsLayer
*vml
, guint8
**data
, gint
*len
)
480 vik_layer_marshall_params ( VIK_LAYER(vml
), data
, len
);
483 static VikMapsLayer
*maps_layer_unmarshall( guint8
*data
, gint len
, VikViewport
*vvp
)
485 VikMapsLayer
*rv
= maps_layer_new ( vvp
);
486 vik_layer_unmarshall_params ( VIK_LAYER(rv
), data
, len
, vvp
);
490 /*********************/
491 /****** DRAWING ******/
492 /*********************/
494 static GdkPixbuf
*pixbuf_set_alpha ( GdkPixbuf
*pixbuf
, guint8 alpha
)
497 gint width
, height
, iii
, jjj
;
499 if ( ! gdk_pixbuf_get_has_alpha ( pixbuf
) )
501 GdkPixbuf
*tmp
= gdk_pixbuf_add_alpha(pixbuf
,FALSE
,0,0,0);
502 g_object_unref(G_OBJECT(pixbuf
));
506 pixels
= gdk_pixbuf_get_pixels(pixbuf
);
507 width
= gdk_pixbuf_get_width(pixbuf
);
508 height
= gdk_pixbuf_get_height(pixbuf
);
510 /* r,g,b,a,r,g,b,a.... */
511 for (iii
= 0; iii
< width
; iii
++) for (jjj
= 0; jjj
< height
; jjj
++)
519 static GdkPixbuf
*pixbuf_shrink ( GdkPixbuf
*pixbuf
, gdouble xshrinkfactor
, gdouble yshrinkfactor
)
522 guint16 width
= gdk_pixbuf_get_width(pixbuf
), height
= gdk_pixbuf_get_height(pixbuf
);
523 tmp
= gdk_pixbuf_scale_simple(pixbuf
, ceil(width
* xshrinkfactor
), ceil(height
* yshrinkfactor
), GDK_INTERP_NEAREST
);
524 g_object_unref ( G_OBJECT(pixbuf
) );
528 static GdkPixbuf
*get_pixbuf( VikMapsLayer
*vml
, gint mode
, MapCoord
*mapcoord
, gchar
*filename_buf
, gint buf_len
, gdouble xshrinkfactor
, gdouble yshrinkfactor
)
533 pixbuf
= a_mapcache_get ( mapcoord
->x
, mapcoord
->y
, mapcoord
->z
,
534 mode
, mapcoord
->scale
, vml
->alpha
, xshrinkfactor
, yshrinkfactor
);
537 g_snprintf ( filename_buf
, buf_len
, DIRSTRUCTURE
,
538 vml
->cache_dir
, mode
,
539 mapcoord
->scale
, mapcoord
->z
, mapcoord
->x
, mapcoord
->y
);
540 if ( g_file_test ( filename_buf
, G_FILE_TEST_EXISTS
) == TRUE
) {
543 pixbuf
= gdk_pixbuf_new_from_file ( filename_buf
, &gx
);
547 if ( gx
->domain
!= GDK_PIXBUF_ERROR
|| gx
->code
!= GDK_PIXBUF_ERROR_CORRUPT_IMAGE
)
548 g_warning ( _("Couldn't open image file: %s"), gx
->message
);
552 g_object_unref ( G_OBJECT(pixbuf
) );
555 if ( vml
->alpha
< 255 )
556 pixbuf
= pixbuf_set_alpha ( pixbuf
, vml
->alpha
);
557 if ( xshrinkfactor
!= 1.0 || yshrinkfactor
!= 1.0 )
558 pixbuf
= pixbuf_shrink ( pixbuf
, xshrinkfactor
, yshrinkfactor
);
560 a_mapcache_add ( pixbuf
, mapcoord
->x
, mapcoord
->y
,
561 mapcoord
->z
, MAPS_LAYER_NTH_TYPE(vml
->maptype
)->uniq_id
,
562 mapcoord
->scale
, vml
->alpha
, xshrinkfactor
, yshrinkfactor
);
570 gboolean
should_start_autodownload(VikMapsLayer
*vml
, VikViewport
*vvp
)
572 const VikCoord
*center
= vik_viewport_get_center ( vvp
);
574 if (vml
->last_center
== NULL
) {
575 VikCoord
*new_center
= g_malloc(sizeof(VikCoord
));
576 *new_center
= *center
;
577 vml
->last_center
= new_center
;
578 vml
->last_xmpp
= vik_viewport_get_xmpp(vvp
);
579 vml
->last_ympp
= vik_viewport_get_ympp(vvp
);
583 /* TODO: perhaps vik_coord_diff() */
584 if (vik_coord_equals(vml
->last_center
, center
)
585 && (vml
->last_xmpp
== vik_viewport_get_xmpp(vvp
))
586 && (vml
->last_ympp
== vik_viewport_get_ympp(vvp
)))
589 *(vml
->last_center
) = *center
;
590 vml
->last_xmpp
= vik_viewport_get_xmpp(vvp
);
591 vml
->last_ympp
= vik_viewport_get_ympp(vvp
);
595 static void maps_layer_draw_section ( VikMapsLayer
*vml
, VikViewport
*vvp
, VikCoord
*ul
, VikCoord
*br
)
598 gdouble xzoom
= vik_viewport_get_xmpp ( vvp
);
599 gdouble yzoom
= vik_viewport_get_ympp ( vvp
);
600 gdouble xshrinkfactor
= 1.0, yshrinkfactor
= 1.0;
601 gdouble existence_only
= FALSE
;
603 if ( vml
->xmapzoom
&& (vml
->xmapzoom
!= xzoom
|| vml
->ymapzoom
!= yzoom
) ) {
604 xshrinkfactor
= vml
->xmapzoom
/ xzoom
;
605 yshrinkfactor
= vml
->ymapzoom
/ yzoom
;
606 xzoom
= vml
->xmapzoom
;
607 yzoom
= vml
->xmapzoom
;
608 if ( ! (xshrinkfactor
> MIN_SHRINKFACTOR
&& xshrinkfactor
< MAX_SHRINKFACTOR
&&
609 yshrinkfactor
> MIN_SHRINKFACTOR
&& yshrinkfactor
< MAX_SHRINKFACTOR
) ) {
610 if ( xshrinkfactor
> REAL_MIN_SHRINKFACTOR
&& yshrinkfactor
> REAL_MIN_SHRINKFACTOR
)
611 existence_only
= TRUE
;
613 g_warning ( _("Cowardly refusing to draw tiles or existence of tiles beyond %d zoom out factor"), (int)( 1.0/REAL_MIN_SHRINKFACTOR
));
620 VikMapsLayer_MapType
*map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
621 if ( map_type
->coord_to_mapcoord ( ul
, xzoom
, yzoom
, &ulm
) &&
622 map_type
->coord_to_mapcoord ( br
, xzoom
, yzoom
, &brm
) ) {
626 gint xmin
= MIN(ulm
.x
, brm
.x
), xmax
= MAX(ulm
.x
, brm
.x
);
627 gint ymin
= MIN(ulm
.y
, brm
.y
), ymax
= MAX(ulm
.y
, brm
.y
);
628 gint mode
= map_type
->uniq_id
;
631 gint xx
, yy
, width
, height
;
634 guint max_path_len
= strlen(vml
->cache_dir
) + 40;
635 gchar
*path_buf
= g_malloc ( max_path_len
* sizeof(char) );
637 if ( (!existence_only
) && vml
->autodownload
&& should_start_autodownload(vml
, vvp
)) {
639 fputs(stderr
, "DEBUG: Starting autodownload\n");
641 start_download_thread ( vml
, vvp
, ul
, br
, REDOWNLOAD_NONE
);
644 if ( map_type
->tilesize_x
== 0 && !existence_only
) {
645 for ( x
= xmin
; x
<= xmax
; x
++ ) {
646 for ( y
= ymin
; y
<= ymax
; y
++ ) {
649 pixbuf
= get_pixbuf ( vml
, mode
, &ulm
, path_buf
, max_path_len
, xshrinkfactor
, yshrinkfactor
);
651 width
= gdk_pixbuf_get_width ( pixbuf
);
652 height
= gdk_pixbuf_get_height ( pixbuf
);
654 map_type
->mapcoord_to_center_coord ( &ulm
, &coord
);
655 vik_viewport_coord_to_screen ( vvp
, &coord
, &xx
, &yy
);
659 vik_viewport_draw_pixbuf ( vvp
, pixbuf
, 0, 0, xx
, yy
, width
, height
);
663 } else { /* tilesize is known, don't have to keep converting coords */
664 gdouble tilesize_x
= map_type
->tilesize_x
* xshrinkfactor
;
665 gdouble tilesize_y
= map_type
->tilesize_y
* yshrinkfactor
;
666 /* ceiled so tiles will be maximum size in the case of funky shrinkfactor */
667 gint tilesize_x_ceil
= ceil ( tilesize_x
);
668 gint tilesize_y_ceil
= ceil ( tilesize_y
);
669 gint8 xinc
= (ulm
.x
== xmin
) ? 1 : -1;
670 gint8 yinc
= (ulm
.y
== ymin
) ? 1 : -1;
671 gdouble xx
, yy
; gint xx_tmp
, yy_tmp
;
672 gint base_yy
, xend
, yend
;
674 GdkGC
*black_gc
= GTK_WIDGET(vvp
)->style
->black_gc
;
676 xend
= (xinc
== 1) ? (xmax
+1) : (xmin
-1);
677 yend
= (yinc
== 1) ? (ymax
+1) : (ymin
-1);
679 map_type
->mapcoord_to_center_coord ( &ulm
, &coord
);
680 vik_viewport_coord_to_screen ( vvp
, &coord
, &xx_tmp
, &yy_tmp
);
681 xx
= xx_tmp
; yy
= yy_tmp
;
682 /* above trick so xx,yy doubles. this is so shrinkfactors aren't rounded off
683 * eg if tile size 128, shrinkfactor 0.333 */
684 xx
-= (tilesize_x
/2);
685 base_yy
= yy
- (tilesize_y
/2);
687 for ( x
= ((xinc
== 1) ? xmin
: xmax
); x
!= xend
; x
+=xinc
) {
689 for ( y
= ((yinc
== 1) ? ymin
: ymax
); y
!= yend
; y
+=yinc
) {
693 if ( existence_only
) {
694 g_snprintf ( path_buf
, max_path_len
, DIRSTRUCTURE
,
695 vml
->cache_dir
, mode
,
696 ulm
.scale
, ulm
.z
, ulm
.x
, ulm
.y
);
697 if ( g_file_test ( path_buf
, G_FILE_TEST_EXISTS
) == TRUE
) {
698 vik_viewport_draw_line ( vvp
, black_gc
, xx
+tilesize_x_ceil
, yy
, xx
, yy
+tilesize_y_ceil
);
701 pixbuf
= get_pixbuf ( vml
, mode
, &ulm
, path_buf
, max_path_len
, xshrinkfactor
, yshrinkfactor
);
703 vik_viewport_draw_pixbuf ( vvp
, pixbuf
, 0, 0, xx
, yy
, tilesize_x_ceil
, tilesize_y_ceil
);
705 /* retry with bigger shrinkfactor */
707 for (scale_inc
= 1; scale_inc
< 4; scale_inc
++) {
708 int scale_factor
= 1 << scale_inc
; /* 2^scale_inc */
710 ulm2
.x
= ulm
.x
/ scale_factor
;
711 ulm2
.y
= ulm
.y
/ scale_factor
;
712 ulm2
.scale
= ulm
.scale
+ scale_inc
;
713 pixbuf
= get_pixbuf ( vml
, mode
, &ulm2
, path_buf
, max_path_len
, xshrinkfactor
* scale_factor
, yshrinkfactor
* scale_factor
);
715 gint src_x
= (ulm
.x
% scale_factor
) * tilesize_x_ceil
;
716 gint src_y
= (ulm
.y
% scale_factor
) * tilesize_y_ceil
;
717 vik_viewport_draw_pixbuf ( vvp
, pixbuf
, src_x
, src_y
, xx
, yy
, tilesize_x_ceil
, tilesize_y_ceil
);
734 static void maps_layer_draw ( VikMapsLayer
*vml
, VikViewport
*vvp
)
736 if ( MAPS_LAYER_NTH_TYPE(vml
->maptype
)->drawmode
== vik_viewport_get_drawmode ( vvp
) )
740 /* get corner coords */
741 if ( vik_viewport_get_coord_mode ( vvp
) == VIK_COORD_UTM
&& ! vik_viewport_is_one_zone ( vvp
) ) {
742 /* UTM multi-zone stuff by Kit Transue */
743 gchar leftmost_zone
, rightmost_zone
, i
;
744 leftmost_zone
= vik_viewport_leftmost_zone( vvp
);
745 rightmost_zone
= vik_viewport_rightmost_zone( vvp
);
746 for ( i
= leftmost_zone
; i
<= rightmost_zone
; ++i
) {
747 vik_viewport_corners_for_zonen ( vvp
, i
, &ul
, &br
);
748 maps_layer_draw_section ( vml
, vvp
, &ul
, &br
);
752 vik_viewport_screen_to_coord ( vvp
, 0, 0, &ul
);
753 vik_viewport_screen_to_coord ( vvp
, vik_viewport_get_width(vvp
), vik_viewport_get_height(vvp
), &br
);
755 maps_layer_draw_section ( vml
, vvp
, &ul
, &br
);
760 /*************************/
761 /****** DOWNLOADING ******/
762 /*************************/
764 /* pass along data to thread, exists even if layer is deleted. */
774 gboolean refresh_display
;
777 gboolean map_layer_alive
;
781 static void mdi_free ( MapDownloadInfo
*mdi
)
783 g_mutex_free(mdi
->mutex
);
784 g_free ( mdi
->cache_dir
);
785 mdi
->cache_dir
= NULL
;
786 g_free ( mdi
->filename_buf
);
787 mdi
->filename_buf
= NULL
;
791 static void weak_ref_cb(gpointer ptr
, GObject
* dead_vml
)
793 MapDownloadInfo
*mdi
= ptr
;
794 g_mutex_lock(mdi
->mutex
);
795 mdi
->map_layer_alive
= FALSE
;
796 g_mutex_unlock(mdi
->mutex
);
799 static int map_download_thread ( MapDownloadInfo
*mdi
, gpointer threaddata
)
803 for ( x
= mdi
->x0
; x
<= mdi
->xf
; x
++ )
805 for ( y
= mdi
->y0
; y
<= mdi
->yf
; y
++ )
807 gboolean remove_mem_cache
= FALSE
;
808 gboolean need_download
= FALSE
;
809 g_snprintf ( mdi
->filename_buf
, mdi
->maxlen
, DIRSTRUCTURE
,
810 mdi
->cache_dir
, MAPS_LAYER_NTH_TYPE(mdi
->maptype
)->uniq_id
,
811 mdi
->mapcoord
.scale
, mdi
->mapcoord
.z
, x
, y
);
814 int res
= a_background_thread_progress ( threaddata
, ((gdouble
)donemaps
) / mdi
->mapstoget
); /* this also calls testcancel */
818 if ( mdi
->redownload
== REDOWNLOAD_ALL
)
819 g_remove ( mdi
->filename_buf
);
821 else if ( (mdi
->redownload
== REDOWNLOAD_BAD
) && (g_file_test ( mdi
->filename_buf
, G_FILE_TEST_EXISTS
) == TRUE
) )
823 /* see if this one is bad or what */
825 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_file ( mdi
->filename_buf
, &gx
);
827 g_remove ( mdi
->filename_buf
);
829 g_object_unref ( pixbuf
);
834 if ( g_file_test ( mdi
->filename_buf
, G_FILE_TEST_EXISTS
) == FALSE
)
836 need_download
= TRUE
;
837 if (( mdi
->redownload
!= REDOWNLOAD_NONE
) &&
838 ( mdi
->redownload
!= DOWNLOAD_OR_REFRESH
))
839 remove_mem_cache
= TRUE
;
840 } else if ( mdi
->redownload
== DOWNLOAD_OR_REFRESH
) {
841 remove_mem_cache
= TRUE
;
842 } else if ( mdi
->redownload
== REDOWNLOAD_NEW
) {
843 need_download
= TRUE
;
844 remove_mem_cache
= TRUE
;
848 mdi
->mapcoord
.x
= x
; mdi
->mapcoord
.y
= y
;
851 if ( MAPS_LAYER_NTH_TYPE(mdi
->maptype
)->download ( &(mdi
->mapcoord
), mdi
->filename_buf
))
856 g_mutex_lock(mdi
->mutex
);
857 if (remove_mem_cache
)
858 a_mapcache_remove_all_shrinkfactors ( x
, y
, mdi
->mapcoord
.z
, MAPS_LAYER_NTH_TYPE(mdi
->maptype
)->uniq_id
, mdi
->mapcoord
.scale
);
859 if (mdi
->refresh_display
&& mdi
->map_layer_alive
) {
860 /* TODO: check if it's on visible area */
861 vik_layer_emit_update ( VIK_LAYER(mdi
->vml
) );
863 g_mutex_unlock(mdi
->mutex
);
865 mdi
->mapcoord
.x
= mdi
->mapcoord
.y
= 0; /* we're temporarily between downloads */
869 g_mutex_lock(mdi
->mutex
);
870 if (mdi
->map_layer_alive
)
871 g_object_weak_unref(G_OBJECT(mdi
->vml
), weak_ref_cb
, mdi
);
872 g_mutex_unlock(mdi
->mutex
);
876 static void mdi_cancel_cleanup ( MapDownloadInfo
*mdi
)
878 if ( mdi
->mapcoord
.x
|| mdi
->mapcoord
.y
)
880 g_snprintf ( mdi
->filename_buf
, mdi
->maxlen
, DIRSTRUCTURE
,
881 mdi
->cache_dir
, MAPS_LAYER_NTH_TYPE(mdi
->maptype
)->uniq_id
,
882 mdi
->mapcoord
.scale
, mdi
->mapcoord
.z
, mdi
->mapcoord
.x
, mdi
->mapcoord
.y
);
883 if ( g_file_test ( mdi
->filename_buf
, G_FILE_TEST_EXISTS
) == TRUE
)
885 g_remove ( mdi
->filename_buf
);
890 static void start_download_thread ( VikMapsLayer
*vml
, VikViewport
*vvp
, const VikCoord
*ul
, const VikCoord
*br
, gint redownload
)
892 gdouble xzoom
= vml
->xmapzoom
? vml
->xmapzoom
: vik_viewport_get_xmpp ( vvp
);
893 gdouble yzoom
= vml
->ymapzoom
? vml
->ymapzoom
: vik_viewport_get_ympp ( vvp
);
895 VikMapsLayer_MapType
*map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
896 if ( map_type
->coord_to_mapcoord ( ul
, xzoom
, yzoom
, &ulm
)
897 && map_type
->coord_to_mapcoord ( br
, xzoom
, yzoom
, &brm
) )
899 MapDownloadInfo
*mdi
= g_malloc ( sizeof(MapDownloadInfo
) );
904 mdi
->map_layer_alive
= TRUE
;
905 mdi
->mutex
= g_mutex_new();
906 mdi
->refresh_display
= TRUE
;
908 /* cache_dir and buffer for dest filename */
909 mdi
->cache_dir
= g_strdup ( vml
->cache_dir
);
910 mdi
->maxlen
= strlen ( vml
->cache_dir
) + 40;
911 mdi
->filename_buf
= g_malloc ( mdi
->maxlen
* sizeof(gchar
) );
912 mdi
->maptype
= vml
->maptype
;
916 mdi
->redownload
= redownload
;
918 mdi
->x0
= MIN(ulm
.x
, brm
.x
);
919 mdi
->xf
= MAX(ulm
.x
, brm
.x
);
920 mdi
->y0
= MIN(ulm
.y
, brm
.y
);
921 mdi
->yf
= MAX(ulm
.y
, brm
.y
);
925 if ( mdi
->redownload
) {
926 mdi
->mapstoget
= (mdi
->xf
- mdi
->x0
+ 1) * (mdi
->yf
- mdi
->y0
+ 1);
928 /* calculate how many we need */
929 for ( a
= mdi
->x0
; a
<= mdi
->xf
; a
++ )
931 for ( b
= mdi
->y0
; b
<= mdi
->yf
; b
++ )
933 g_snprintf ( mdi
->filename_buf
, mdi
->maxlen
, DIRSTRUCTURE
,
934 vml
->cache_dir
, map_type
->uniq_id
, ulm
.scale
,
936 if ( g_file_test ( mdi
->filename_buf
, G_FILE_TEST_EXISTS
) == FALSE
)
942 mdi
->mapcoord
.x
= mdi
->mapcoord
.y
= 0; /* for cleanup -- no current map */
944 if ( mdi
->mapstoget
)
946 const gchar
*tmp_str
;
951 if (redownload
== REDOWNLOAD_BAD
)
952 tmp_str
= ngettext("Redownloading up to %d %s map...", "Redownloading up to %d %s maps...", mdi
->mapstoget
);
954 tmp_str
= ngettext("Redownloading %d %s map...", "Redownloading %d %s maps...", mdi
->mapstoget
);
958 tmp_str
= ngettext("Downloading %d %s map...", "Downloading %d %s maps...", mdi
->mapstoget
);
960 tmp
= g_strdup_printf ( tmp_str
, mdi
->mapstoget
, MAPS_LAYER_NTH_LABEL(vml
->maptype
));
962 g_object_weak_ref(G_OBJECT(mdi
->vml
), weak_ref_cb
, mdi
);
963 /* launch the thread */
964 a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml
), /* parent window */
965 tmp
, /* description string */
966 (vik_thr_func
) map_download_thread
, /* function to call within thread */
967 mdi
, /* pass along data */
968 (vik_thr_free_func
) mdi_free
, /* function to free pass along data */
969 (vik_thr_free_func
) mdi_cancel_cleanup
,
978 void maps_layer_download_section_without_redraw( VikMapsLayer
*vml
, VikViewport
*vvp
, VikCoord
*ul
, VikCoord
*br
, gdouble zoom
)
981 VikMapsLayer_MapType
*map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
983 if (!map_type
->coord_to_mapcoord(ul
, zoom
, zoom
, &ulm
)
984 || !map_type
->coord_to_mapcoord(br
, zoom
, zoom
, &brm
)) {
985 g_warning("%s() coord_to_mapcoord() failed", __PRETTY_FUNCTION__
);
989 MapDownloadInfo
*mdi
= g_malloc(sizeof(MapDownloadInfo
));
994 mdi
->map_layer_alive
= TRUE
;
995 mdi
->mutex
= g_mutex_new();
996 mdi
->refresh_display
= FALSE
;
998 mdi
->cache_dir
= g_strdup ( vml
->cache_dir
);
999 mdi
->maxlen
= strlen ( vml
->cache_dir
) + 40;
1000 mdi
->filename_buf
= g_malloc ( mdi
->maxlen
* sizeof(gchar
) );
1001 mdi
->maptype
= vml
->maptype
;
1003 mdi
->mapcoord
= ulm
;
1005 mdi
->redownload
= REDOWNLOAD_NONE
;
1007 mdi
->x0
= MIN(ulm
.x
, brm
.x
);
1008 mdi
->xf
= MAX(ulm
.x
, brm
.x
);
1009 mdi
->y0
= MIN(ulm
.y
, brm
.y
);
1010 mdi
->yf
= MAX(ulm
.y
, brm
.y
);
1014 for (i
= mdi
->x0
; i
<= mdi
->xf
; i
++) {
1015 for (j
= mdi
->y0
; j
<= mdi
->yf
; j
++) {
1016 g_snprintf ( mdi
->filename_buf
, mdi
->maxlen
, DIRSTRUCTURE
,
1017 vml
->cache_dir
, map_type
->uniq_id
, ulm
.scale
,
1019 if ( g_file_test ( mdi
->filename_buf
, G_FILE_TEST_EXISTS
) == FALSE
)
1024 mdi
->mapcoord
.x
= mdi
->mapcoord
.y
= 0; /* for cleanup -- no current map */
1026 if (mdi
->mapstoget
) {
1029 fmt
= ngettext("Downloading %d %s map...",
1030 "Downloading %d %s maps...",
1032 tmp
= g_strdup_printf ( fmt
, mdi
->mapstoget
, MAPS_LAYER_NTH_LABEL(vml
->maptype
) );
1034 g_object_weak_ref(G_OBJECT(mdi
->vml
), weak_ref_cb
, mdi
);
1035 /* launch the thread */
1036 a_background_thread ( VIK_GTK_WINDOW_FROM_LAYER(vml
), /* parent window */
1037 tmp
, /* description string */
1038 (vik_thr_func
) map_download_thread
, /* function to call within thread */
1039 mdi
, /* pass along data */
1040 (vik_thr_free_func
) mdi_free
, /* function to free pass along data */
1041 (vik_thr_free_func
) mdi_cancel_cleanup
,
1049 static void maps_layer_redownload_bad ( VikMapsLayer
*vml
)
1051 start_download_thread ( vml
, vml
->redownload_vvp
, &(vml
->redownload_ul
), &(vml
->redownload_br
), REDOWNLOAD_BAD
);
1053 static void maps_layer_redownload_all ( VikMapsLayer
*vml
)
1055 start_download_thread ( vml
, vml
->redownload_vvp
, &(vml
->redownload_ul
), &(vml
->redownload_br
), REDOWNLOAD_ALL
);
1058 static gboolean
maps_layer_download_release ( VikMapsLayer
*vml
, GdkEventButton
*event
, VikViewport
*vvp
)
1060 if (!vml
|| vml
->vl
.type
!= VIK_LAYER_MAPS
)
1062 if ( vml
->dl_tool_x
!= -1 && vml
->dl_tool_y
!= -1 )
1064 if ( event
->button
== 1 )
1067 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
);
1068 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
);
1069 start_download_thread ( vml
, vvp
, &ul
, &br
, DOWNLOAD_OR_REFRESH
);
1070 vml
->dl_tool_x
= vml
->dl_tool_y
= -1;
1075 vik_viewport_screen_to_coord ( vvp
, MAX(0, MIN(event
->x
, vml
->dl_tool_x
)), MAX(0, MIN(event
->y
, vml
->dl_tool_y
)), &(vml
->redownload_ul
) );
1076 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
) ), &(vml
->redownload_br
) );
1078 vml
->redownload_vvp
= vvp
;
1080 vml
->dl_tool_x
= vml
->dl_tool_y
= -1;
1082 if ( ! vml
->dl_right_click_menu
) {
1084 vml
->dl_right_click_menu
= GTK_MENU ( gtk_menu_new () );
1086 item
= gtk_menu_item_new_with_label ( _("Redownload bad map(s)") );
1087 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(maps_layer_redownload_bad
), vml
);
1088 gtk_menu_shell_append ( GTK_MENU_SHELL(vml
->dl_right_click_menu
), item
);
1090 item
= gtk_menu_item_new_with_label ( _("Redownload all map(s)") );
1091 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(maps_layer_redownload_all
), vml
);
1092 gtk_menu_shell_append ( GTK_MENU_SHELL(vml
->dl_right_click_menu
), item
);
1095 gtk_menu_popup ( vml
->dl_right_click_menu
, NULL
, NULL
, NULL
, NULL
, event
->button
, event
->time
);
1096 gtk_widget_show_all ( GTK_WIDGET(vml
->dl_right_click_menu
) );
1102 static gpointer
maps_layer_download_create ( VikWindow
*vw
, VikViewport
*vvp
)
1107 static gboolean
maps_layer_download_click ( VikMapsLayer
*vml
, GdkEventButton
*event
, VikViewport
*vvp
)
1110 if (!vml
|| vml
->vl
.type
!= VIK_LAYER_MAPS
)
1112 VikMapsLayer_MapType
*map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
1113 if ( map_type
->drawmode
== vik_viewport_get_drawmode ( vvp
) &&
1114 map_type
->coord_to_mapcoord ( vik_viewport_get_center ( vvp
),
1115 vml
->xmapzoom
? vml
->xmapzoom
: vik_viewport_get_xmpp ( vvp
),
1116 vml
->ymapzoom
? vml
->ymapzoom
: vik_viewport_get_ympp ( vvp
),
1118 vml
->dl_tool_x
= event
->x
, vml
->dl_tool_y
= event
->y
;
1125 if ( __map_types
[vml
->maptype
].drawmode
== vik_viewport_get_drawmode ( vvp
) )
1129 vik_viewport_screen_to_coord ( vvp
, event
->x
, event
->y
, &coord
);
1130 if ( __map_types
[vml
->maptype
].coord_to_mapcoord ( &coord
,
1131 vml
->xmapzoom
? vml
->xmapzoom
: vik_viewport_get_xmpp ( vvp
),
1132 vml
->ymapzoom
? vml
->ymapzoom
: vik_viewport_get_ympp ( vvp
),
1134 gchar
*filename_buf
= g_strdup_printf ( DIRSTRUCTURE
,
1135 vml
->cache_dir
, __map_types
[vml
->maptype
].uniq_id
,
1136 mapcoord
.scale
, mapcoord
.z
, mapcoord
.x
, mapcoord
.y
);
1138 __map_types
[vml
->maptype
].download ( &mapcoord
, filename_buf
);
1139 g_free ( filename_buf
);
1140 vik_layer_emit_update ( VIK_LAYER(vml
) );
1148 static void download_onscreen_maps ( gpointer vml_vvp
[2], gint redownload
)
1150 VikMapsLayer
*vml
= vml_vvp
[0];
1151 VikViewport
*vvp
= vml_vvp
[1];
1152 VikViewportDrawMode vp_drawmode
= vik_viewport_get_drawmode ( vvp
);
1154 gdouble xzoom
= vml
->xmapzoom
? vml
->xmapzoom
: vik_viewport_get_xmpp ( vvp
);
1155 gdouble yzoom
= vml
->ymapzoom
? vml
->ymapzoom
: vik_viewport_get_ympp ( vvp
);
1160 vik_viewport_screen_to_coord ( vvp
, 0, 0, &ul
);
1161 vik_viewport_screen_to_coord ( vvp
, vik_viewport_get_width(vvp
), vik_viewport_get_height(vvp
), &br
);
1163 VikMapsLayer_MapType
*map_type
= MAPS_LAYER_NTH_TYPE(vml
->maptype
);
1164 if ( map_type
->drawmode
== vp_drawmode
&&
1165 map_type
->coord_to_mapcoord ( &ul
, xzoom
, yzoom
, &ulm
) &&
1166 map_type
->coord_to_mapcoord ( &br
, xzoom
, yzoom
, &brm
) )
1167 start_download_thread ( vml
, vvp
, &ul
, &br
, redownload
);
1168 else if (map_type
->drawmode
!= vp_drawmode
) {
1169 const gchar
*drawmode_name
= vik_viewport_get_drawmode_name (vvp
, map_type
->drawmode
);
1170 gchar
*err
= g_strdup_printf(_("Wrong drawmode for this map.\nSelect \"%s\" from View menu and try again."), _(drawmode_name
));
1171 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml
), err
);
1175 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vml
), _("Wrong zoom level for this map.") );
1179 static void maps_layer_download_missing_onscreen_maps ( gpointer vml_vvp
[2] )
1181 download_onscreen_maps( vml_vvp
, REDOWNLOAD_NONE
);
1184 static void maps_layer_download_new_onscreen_maps ( gpointer vml_vvp
[2] )
1186 download_onscreen_maps( vml_vvp
, REDOWNLOAD_NEW
);
1189 static void maps_layer_redownload_all_onscreen_maps ( gpointer vml_vvp
[2] )
1191 download_onscreen_maps( vml_vvp
, REDOWNLOAD_ALL
);
1194 static void maps_layer_add_menu_items ( VikMapsLayer
*vml
, GtkMenu
*menu
, VikLayersPanel
*vlp
)
1196 static gpointer pass_along
[2];
1198 pass_along
[0] = vml
;
1199 pass_along
[1] = vik_layers_panel_get_viewport( VIK_LAYERS_PANEL(vlp
) );
1201 item
= gtk_menu_item_new();
1202 gtk_menu_shell_append ( GTK_MENU_SHELL(menu
), item
);
1203 gtk_widget_show ( item
);
1205 item
= gtk_menu_item_new_with_label ( _("Download missing Onscreen Maps") );
1206 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(maps_layer_download_missing_onscreen_maps
), pass_along
);
1207 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1208 gtk_widget_show ( item
);
1210 if ( MAPS_LAYER_NTH_TYPE(vml
->maptype
)->options
!= NULL
&&
1211 MAPS_LAYER_NTH_TYPE(vml
->maptype
)->options
->check_file_server_time
) {
1212 item
= gtk_menu_item_new_with_label ( _("Download new Onscreen Maps from server") );
1213 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(maps_layer_download_new_onscreen_maps
), pass_along
);
1214 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1215 gtk_widget_show ( item
);
1218 /* TODO Add GTK_STOCK_REFRESH icon */
1219 item
= gtk_menu_item_new_with_label ( _("Refresh Onscreen Tiles") );
1220 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(maps_layer_redownload_all_onscreen_maps
), pass_along
);
1221 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1222 gtk_widget_show ( item
);