g_mutex_unlock(mdi->mutex);
}
+static gboolean is_in_area (VikMapSource *map, MapCoord mc)
+{
+ VikCoord vc;
+ vik_map_source_mapcoord_to_center_coord ( map, &mc, &vc );
+
+ struct LatLon tl;
+ tl.lat = vik_map_source_get_lat_max(map);
+ tl.lon = vik_map_source_get_lon_min(map);
+ struct LatLon br;
+ br.lat = vik_map_source_get_lat_min(map);
+ br.lon = vik_map_source_get_lon_max(map);
+ VikCoord vctl;
+ vik_coord_load_from_latlon (&vctl, VIK_COORD_LATLON, &tl);
+ VikCoord vcbr;
+ vik_coord_load_from_latlon (&vcbr, VIK_COORD_LATLON, &br);
+
+ return vik_coord_inside ( &vc, &vctl, &vcbr );
+}
+
static int map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata )
{
void *handle = vik_map_source_download_handle_init(MAPS_LAYER_NTH_TYPE(mdi->maptype));
guint donemaps = 0;
+ MapCoord mcoord = mdi->mapcoord;
gint x, y;
for ( x = mdi->x0; x <= mdi->xf; x++ )
{
+ mcoord.x = x;
for ( y = mdi->y0; y <= mdi->yf; y++ )
{
- gboolean remove_mem_cache = FALSE;
- gboolean need_download = FALSE;
-
- get_filename ( mdi->cache_dir, mdi->cache_layout,
- vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(mdi->maptype)),
- vik_map_source_get_name(MAPS_LAYER_NTH_TYPE(mdi->maptype)),
- mdi->mapcoord.scale, mdi->mapcoord.z, x, y, mdi->filename_buf, mdi->maxlen,
- vik_map_source_get_file_extension(MAPS_LAYER_NTH_TYPE(mdi->maptype)) );
-
- donemaps++;
- int res = a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */
- if (res != 0) {
- vik_map_source_download_handle_cleanup(MAPS_LAYER_NTH_TYPE(mdi->maptype), handle);
- return -1;
- }
+ mcoord.y = y;
+ // Only attempt to download a tile from supported areas
+ if ( is_in_area ( MAPS_LAYER_NTH_TYPE(mdi->maptype), mcoord ) )
+ {
+ gboolean remove_mem_cache = FALSE;
+ gboolean need_download = FALSE;
- if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) {
- need_download = TRUE;
- remove_mem_cache = TRUE;
+ get_filename ( mdi->cache_dir, mdi->cache_layout,
+ vik_map_source_get_uniq_id(MAPS_LAYER_NTH_TYPE(mdi->maptype)),
+ vik_map_source_get_name(MAPS_LAYER_NTH_TYPE(mdi->maptype)),
+ mdi->mapcoord.scale, mdi->mapcoord.z, x, y, mdi->filename_buf, mdi->maxlen,
+ vik_map_source_get_file_extension(MAPS_LAYER_NTH_TYPE(mdi->maptype)) );
+
+ donemaps++;
+ int res = a_background_thread_progress ( threaddata, ((gdouble)donemaps) / mdi->mapstoget ); /* this also calls testcancel */
+ if (res != 0) {
+ vik_map_source_download_handle_cleanup(MAPS_LAYER_NTH_TYPE(mdi->maptype), handle);
+ return -1;
+ }
- } else { /* in case map file already exists */
- switch (mdi->redownload) {
- case REDOWNLOAD_NONE:
- continue;
+ if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) {
+ need_download = TRUE;
+ remove_mem_cache = TRUE;
- case REDOWNLOAD_BAD:
- {
- /* see if this one is bad or what */
- GError *gx = NULL;
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx );
- if (gx || (!pixbuf)) {
- g_remove ( mdi->filename_buf );
- need_download = TRUE;
- remove_mem_cache = TRUE;
- g_error_free ( gx );
+ } else { /* in case map file already exists */
+ switch (mdi->redownload) {
+ case REDOWNLOAD_NONE:
+ continue;
+
+ case REDOWNLOAD_BAD:
+ {
+ /* see if this one is bad or what */
+ GError *gx = NULL;
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx );
+ if (gx || (!pixbuf)) {
+ g_remove ( mdi->filename_buf );
+ need_download = TRUE;
+ remove_mem_cache = TRUE;
+ g_error_free ( gx );
- } else {
- g_object_unref ( pixbuf );
+ } else {
+ g_object_unref ( pixbuf );
+ }
+ break;
}
- break;
- }
- case REDOWNLOAD_NEW:
- need_download = TRUE;
- remove_mem_cache = TRUE;
- break;
+ case REDOWNLOAD_NEW:
+ need_download = TRUE;
+ remove_mem_cache = TRUE;
+ break;
- case REDOWNLOAD_ALL:
- /* FIXME: need a better way than to erase file in case of server/network problem */
- g_remove ( mdi->filename_buf );
- need_download = TRUE;
- remove_mem_cache = TRUE;
- break;
+ case REDOWNLOAD_ALL:
+ /* FIXME: need a better way than to erase file in case of server/network problem */
+ g_remove ( mdi->filename_buf );
+ need_download = TRUE;
+ remove_mem_cache = TRUE;
+ break;
- case DOWNLOAD_OR_REFRESH:
- remove_mem_cache = TRUE;
- break;
+ case DOWNLOAD_OR_REFRESH:
+ remove_mem_cache = TRUE;
+ break;
- default:
- g_warning ( "redownload state %d unknown\n", mdi->redownload);
+ default:
+ g_warning ( "redownload state %d unknown\n", mdi->redownload);
+ }
}
- }
- mdi->mapcoord.x = x; mdi->mapcoord.y = y;
-
- if (need_download) {
- DownloadResult_t dr = vik_map_source_download( MAPS_LAYER_NTH_TYPE(mdi->maptype), &(mdi->mapcoord), mdi->filename_buf, handle);
- switch ( dr ) {
- case DOWNLOAD_HTTP_ERROR:
- case DOWNLOAD_CONTENT_ERROR: {
- // TODO: ?? count up the number of download errors somehow...
- gchar* msg = g_strdup_printf ( "%s: %s", vik_maps_layer_get_map_label (mdi->vml), _("Failed to download tile") );
- vik_window_statusbar_update ( (VikWindow*)VIK_GTK_WINDOW_FROM_LAYER(mdi->vml), msg, VIK_STATUSBAR_INFO );
- g_free (msg);
- break;
- }
- case DOWNLOAD_FILE_WRITE_ERROR: {
- gchar* msg = g_strdup_printf ( "%s: %s", vik_maps_layer_get_map_label (mdi->vml), _("Unable to save tile") );
- vik_window_statusbar_update ( (VikWindow*)VIK_GTK_WINDOW_FROM_LAYER(mdi->vml), msg, VIK_STATUSBAR_INFO );
- g_free (msg);
- break;
+ mdi->mapcoord.x = x; mdi->mapcoord.y = y;
+
+ if (need_download) {
+ DownloadResult_t dr = vik_map_source_download( MAPS_LAYER_NTH_TYPE(mdi->maptype), &(mdi->mapcoord), mdi->filename_buf, handle);
+ switch ( dr ) {
+ case DOWNLOAD_HTTP_ERROR:
+ case DOWNLOAD_CONTENT_ERROR: {
+ // TODO: ?? count up the number of download errors somehow...
+ gchar* msg = g_strdup_printf ( "%s: %s", vik_maps_layer_get_map_label (mdi->vml), _("Failed to download tile") );
+ vik_window_statusbar_update ( (VikWindow*)VIK_GTK_WINDOW_FROM_LAYER(mdi->vml), msg, VIK_STATUSBAR_INFO );
+ g_free (msg);
+ break;
+ }
+ case DOWNLOAD_FILE_WRITE_ERROR: {
+ gchar* msg = g_strdup_printf ( "%s: %s", vik_maps_layer_get_map_label (mdi->vml), _("Unable to save tile") );
+ vik_window_statusbar_update ( (VikWindow*)VIK_GTK_WINDOW_FROM_LAYER(mdi->vml), msg, VIK_STATUSBAR_INFO );
+ g_free (msg);
+ break;
+ }
+ case DOWNLOAD_SUCCESS:
+ case DOWNLOAD_NOT_REQUIRED:
+ default:
+ break;
}
- case DOWNLOAD_SUCCESS:
- case DOWNLOAD_NOT_REQUIRED:
- default:
- 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 );
- 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
+ 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 );
+ 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
+ }
+ g_mutex_unlock(mdi->mutex);
+ mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between downloads */
}
- g_mutex_unlock(mdi->mutex);
- mdi->mapcoord.x = mdi->mapcoord.y = 0; /* we're temporarily between downloads */
-
}
}
vik_map_source_download_handle_cleanup(MAPS_LAYER_NTH_TYPE(mdi->maptype), handle);
mdi->mapstoget = 0;
+ MapCoord mcoord = mdi->mapcoord;
+
if ( mdi->redownload ) {
mdi->mapstoget = (mdi->xf - mdi->x0 + 1) * (mdi->yf - mdi->y0 + 1);
} else {
/* calculate how many we need */
for ( a = mdi->x0; a <= mdi->xf; a++ )
{
+ mcoord.x = a;
for ( b = mdi->y0; b <= mdi->yf; b++ )
{
- get_filename ( mdi->cache_dir, mdi->cache_layout,
- vik_map_source_get_uniq_id(map),
- vik_map_source_get_name(map),
- ulm.scale, ulm.z, a, b, mdi->filename_buf, mdi->maxlen,
- vik_map_source_get_file_extension(map) );
- if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE )
- mdi->mapstoget++;
+ mcoord.y = b;
+ // Only count tiles from supported areas
+ if ( is_in_area (map, mcoord) )
+ {
+ get_filename ( mdi->cache_dir, mdi->cache_layout,
+ vik_map_source_get_uniq_id(map),
+ vik_map_source_get_name(map),
+ ulm.scale, ulm.z, a, b, mdi->filename_buf, mdi->maxlen,
+ vik_map_source_get_file_extension(map) );
+ if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE )
+ mdi->mapstoget++;
+ }
}
}
}
mdi->mapstoget = 0;
+ MapCoord mcoord = mdi->mapcoord;
+
for (i = mdi->x0; i <= mdi->xf; i++) {
+ mcoord.x = i;
for (j = mdi->y0; j <= mdi->yf; j++) {
- get_filename ( mdi->cache_dir, mdi->cache_layout,
- vik_map_source_get_uniq_id(map),
- vik_map_source_get_name(map),
- ulm.scale, ulm.z, i, j, mdi->filename_buf, mdi->maxlen,
- vik_map_source_get_file_extension(map) );
- if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE )
- mdi->mapstoget++;
+ mcoord.y = j;
+ // Only count tiles from supported areas
+ if ( is_in_area (map, mcoord) ) {
+ get_filename ( mdi->cache_dir, mdi->cache_layout,
+ vik_map_source_get_uniq_id(map),
+ vik_map_source_get_name(map),
+ ulm.scale, ulm.z, i, j, mdi->filename_buf, mdi->maxlen,
+ vik_map_source_get_file_extension(map) );
+ if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE )
+ mdi->mapstoget++;
+ }
}
}
}
else {
/* calculate how many we need */
+ MapCoord mcoord = mdi->mapcoord;
for (i = mdi->x0; i <= mdi->xf; i++) {
+ mcoord.x = i;
for (j = mdi->y0; j <= mdi->yf; j++) {
- get_filename ( mdi->cache_dir, mdi->cache_layout,
- vik_map_source_get_uniq_id(map),
- vik_map_source_get_name(map),
- ulm.scale, ulm.z, i, j, mdi->filename_buf, mdi->maxlen,
- vik_map_source_get_file_extension(map) );
- if ( mdi->redownload == REDOWNLOAD_NEW ) {
- // Assume the worst - always a new file
- // Absolute value would requires server lookup - but that is too slow
- mdi->mapstoget++;
- }
- else {
- if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) {
- // Missing
+ mcoord.y = j;
+ // Only count tiles from supported areas
+ if ( is_in_area ( map, mcoord ) ) {
+ get_filename ( mdi->cache_dir, mdi->cache_layout,
+ vik_map_source_get_uniq_id(map),
+ vik_map_source_get_name(map),
+ ulm.scale, ulm.z, i, j, mdi->filename_buf, mdi->maxlen,
+ vik_map_source_get_file_extension(map) );
+ if ( mdi->redownload == REDOWNLOAD_NEW ) {
+ // Assume the worst - always a new file
+ // Absolute value would require a server lookup - but that is too slow
mdi->mapstoget++;
}
else {
- if ( mdi->redownload == REDOWNLOAD_BAD ) {
- /* see if this one is bad or what */
- GError *gx = NULL;
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx );
- if (gx || (!pixbuf)) {
- mdi->mapstoget++;
+ if ( g_file_test ( mdi->filename_buf, G_FILE_TEST_EXISTS ) == FALSE ) {
+ // Missing
+ mdi->mapstoget++;
+ }
+ else {
+ if ( mdi->redownload == REDOWNLOAD_BAD ) {
+ /* see if this one is bad or what */
+ GError *gx = NULL;
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( mdi->filename_buf, &gx );
+ if (gx || (!pixbuf)) {
+ mdi->mapstoget++;
+ }
+ break;
+ // Other download cases already considered or just ignored
}
- break;
- // Other download cases already considered or just ignored
}
}
}
static gboolean _supports_download_only_new (VikMapSource *self );
static guint8 _get_zoom_min(VikMapSource *self );
static guint8 _get_zoom_max(VikMapSource *self );
+static gdouble _get_lat_min(VikMapSource *self );
+static gdouble _get_lat_max(VikMapSource *self );
+static gdouble _get_lon_min(VikMapSource *self );
+static gdouble _get_lon_max(VikMapSource *self );
static gchar *_get_uri( VikMapSourceDefault *self, MapCoord *src );
static gchar *_get_hostname( VikMapSourceDefault *self );
// NB Probably best to keep the above fields in same order to be common across Slippy, TMS & WMS map definitions
guint zoom_min; // TMS Zoom level: 0 = Whole World // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
guint zoom_max; // TMS Zoom level: Often 18 for zoomed in.
+ gdouble lat_min; // Degrees
+ gdouble lat_max; // Degrees
+ gdouble lon_min; // Degrees
+ gdouble lon_max; // Degrees
gboolean is_direct_file_access;
gboolean is_mbtiles;
gboolean is_osm_meta_tiles; // http://wiki.openstreetmap.org/wiki/Meta_tiles as used by tirex or renderd
PROP_URL,
PROP_ZOOM_MIN,
PROP_ZOOM_MAX,
+ PROP_LAT_MIN,
+ PROP_LAT_MAX,
+ PROP_LON_MIN,
+ PROP_LON_MAX,
PROP_REFERER,
PROP_FOLLOW_LOCATION,
PROP_CHECK_FILE_SERVER_TIME,
priv->url = NULL;
priv->zoom_min = 0;
priv->zoom_max = 18;
+ priv->lat_min = -90.0;
+ priv->lat_max = 90.0;
+ priv->lon_min = -180.0;
+ priv->lon_max = 180.0;
priv->options.referer = NULL;
priv->options.follow_location = 0;
priv->options.check_file = a_check_map_file;
priv->zoom_max = g_value_get_uint (value);
break;
+ case PROP_LAT_MIN:
+ priv->lat_min = g_value_get_double (value);
+ break;
+
+ case PROP_LAT_MAX:
+ priv->lat_max = g_value_get_double (value);
+ break;
+
+ case PROP_LON_MIN:
+ priv->lon_min = g_value_get_double (value);
+ break;
+
+ case PROP_LON_MAX:
+ priv->lon_max = g_value_get_double (value);
+ break;
+
case PROP_REFERER:
g_free (priv->options.referer);
priv->options.referer = g_value_dup_string (value);
g_value_set_uint (value, priv->zoom_max);
break;
+ case PROP_LON_MIN:
+ g_value_set_double (value, priv->lon_min);
+ break;
+
+ case PROP_LON_MAX:
+ g_value_set_double (value, priv->lon_max);
+ break;
+
+ case PROP_LAT_MIN:
+ g_value_set_double (value, priv->lat_min);
+ break;
+
+ case PROP_LAT_MAX:
+ g_value_set_double (value, priv->lat_max);
+ break;
+
case PROP_REFERER:
g_value_set_string (value, priv->options.referer);
break;
grandparent_class->supports_download_only_new = _supports_download_only_new;
grandparent_class->get_zoom_min = _get_zoom_min;
grandparent_class->get_zoom_max = _get_zoom_max;
+ grandparent_class->get_lat_min = _get_lat_min;
+ grandparent_class->get_lat_max = _get_lat_max;
+ grandparent_class->get_lon_min = _get_lon_min;
+ grandparent_class->get_lon_max = _get_lon_max;
parent_class->get_uri = _get_uri;
parent_class->get_hostname = _get_hostname;
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_ZOOM_MAX, pspec);
+ pspec = g_param_spec_double ("lat-min",
+ "Minimum latitude",
+ "Minimum latitude in degrees supported by the map provider",
+ -90.0, // minimum value
+ 90.0, // maximum value
+ -90.0, // default value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_LAT_MIN, pspec);
+
+ pspec = g_param_spec_double ("lat-max",
+ "Maximum latitude",
+ "Maximum latitude in degrees supported by the map provider",
+ -90.0, // minimum value
+ 90.0, // maximum value
+ 90.0, // default value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_LAT_MAX, pspec);
+
+ pspec = g_param_spec_double ("lon-min",
+ "Minimum longitude",
+ "Minimum longitude in degrees supported by the map provider",
+ -180.0, // minimum value
+ 180.0, // maximum value
+ -180.0, // default value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_LON_MIN, pspec);
+
+ pspec = g_param_spec_double ("lon-max",
+ "Maximum longitude",
+ "Maximum longitude in degrees supported by the map provider",
+ -180.0, // minimum value
+ 180.0, // maximum value
+ 180.0, // default value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_LON_MAX, pspec);
+
pspec = g_param_spec_string ("referer",
"Referer",
"The REFERER string to use in HTTP request",
return priv->zoom_max;
}
+/**
+ *
+ */
+static gdouble
+_get_lat_min (VikMapSource *self)
+{
+ g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
+ VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
+ return priv->lat_min;
+}
+
+/**
+ *
+ */
+static gdouble
+_get_lat_max (VikMapSource *self)
+{
+ g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
+ VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
+ return priv->lat_max;
+}
+
+/**
+ *
+ */
+static gdouble
+_get_lon_min (VikMapSource *self)
+{
+ g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
+ VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
+ return priv->lon_min;
+}
+
+/**
+ *
+ */
+static gdouble
+_get_lon_max (VikMapSource *self)
+{
+ g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
+ VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
+ return priv->lon_max;
+}
+
static gboolean
_coord_to_mapcoord ( VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
{