From 2113a507ea6e188bf41f8c5b5a63ab8890c40555 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Mon, 15 Sep 2014 21:04:05 +0100 Subject: [PATCH] Add and use capability of defined area by min/max lat/lons for map types. Various tile servers have differing coverage extents by area. Thus don't need to generate download requests that we know are going to fail. The area levels can be customized for new maps. NB this only caters for a simple rectangular bounding box, rather then bounding polygon. All built in maps have world wide coverage. Only the extension configured map CalTopo is effected limited area to the US. --- data/maps.xml | 4 + doc/examples/maps.xml | 17 +++ help/C/viking.xml | 16 +++ help/viking.xml | 16 +++ src/vikmapslayer.c | 284 +++++++++++++++++++++++---------------- src/vikmapsource.c | 59 ++++++++ src/vikmapsource.h | 8 ++ src/vikslippymapsource.c | 132 ++++++++++++++++++ 8 files changed, 417 insertions(+), 119 deletions(-) diff --git a/data/maps.xml b/data/maps.xml index 0a2a5ebc..944a7e0f 100644 --- a/data/maps.xml +++ b/data/maps.xml @@ -37,6 +37,10 @@ /caltopo/topo/%d/%d/%d.png?v=1 0 16 + 18.76 + 71.56 + -178.0 + -66.95 CalTopo Terms of Use CalTopo Terms of Use http://caltopo.com/ diff --git a/doc/examples/maps.xml b/doc/examples/maps.xml index 3605c4d4..0d6f9d76 100644 --- a/doc/examples/maps.xml +++ b/doc/examples/maps.xml @@ -48,4 +48,21 @@ ArcGIS Specific http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer + + + + + OS NPE + ooc.openstreetmap.org + /npe/%d/%d/%d.png + 245 + NPE + .png + 7 + 18 + 49.8 + 55.8 + -5.8 + 1.9 + diff --git a/help/C/viking.xml b/help/C/viking.xml index 3e04a9d8..9a62f2f9 100644 --- a/help/C/viking.xml +++ b/help/C/viking.xml @@ -2885,6 +2885,22 @@ Accept: */* See Zoom Levels + + lat-min (optional) + The minimum latitude value in degrees supported by the tile server. The Default is -90 degrees if not specified. + + + lat-max (optional) + The maximum latitude value in degrees supported by the tile server. The Default is 90 degrees if not specified. + + + lon-min (optional) + The minimum longitude value in degrees supported by the tile server. The Default is -180 degrees if not specified. + + + lon-max (optional) + The maximum longitude value in degrees supported by the tile server. The Default is 180 degrees if not specified. + file-extension (optional) diff --git a/help/viking.xml b/help/viking.xml index ecd7e817..106280a4 100644 --- a/help/viking.xml +++ b/help/viking.xml @@ -222,6 +222,22 @@ and docbook-xsl in your Build-Depends control field. See Zoom Levels + + lat-min (optional) + The minimum latitude value in degrees supported by the tile server. The Default is -90 degrees if not specified. + + + lat-max (optional) + The maximum latitude value in degrees supported by the tile server. The Default is 90 degrees if not specified. + + + lon-min (optional) + The minimum longitude value in degrees supported by the tile server. The Default is -180 degrees if not specified. + + + lon-max (optional) + The maximum longitude value in degrees supported by the tile server. The Default is 180 degrees if not specified. + file-extension (optional) diff --git a/src/vikmapslayer.c b/src/vikmapslayer.c index f566521e..a352102a 100644 --- a/src/vikmapslayer.c +++ b/src/vikmapslayer.c @@ -1419,114 +1419,139 @@ static void weak_ref_cb(gpointer ptr, GObject * dead_vml) 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); @@ -1593,21 +1618,29 @@ static void start_download_thread ( VikMapsLayer *vml, VikViewport *vvp, const V 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++; + } } } } @@ -1688,15 +1721,22 @@ static void maps_layer_download_section ( VikMapsLayer *vml, VikViewport *vvp, V 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++; + } } } @@ -2046,33 +2086,39 @@ static gint maps_layer_how_many_maps ( VikMapsLayer *vml, VikViewport *vvp, VikC } 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 } } } diff --git a/src/vikmapsource.c b/src/vikmapsource.c index 23acbb0e..d59b4163 100644 --- a/src/vikmapsource.c +++ b/src/vikmapsource.c @@ -76,6 +76,10 @@ vik_map_source_class_init (VikMapSourceClass *klass) klass->supports_download_only_new = _supports_download_only_new; klass->get_zoom_min = NULL; klass->get_zoom_max = NULL; + klass->get_lat_min = NULL; + klass->get_lat_max = NULL; + klass->get_lon_min = NULL; + klass->get_lon_max = NULL; klass->coord_to_mapcoord = NULL; klass->mapcoord_to_center_coord = NULL; klass->download = NULL; @@ -333,6 +337,61 @@ vik_map_source_get_zoom_max (VikMapSource * self) return (*klass->get_zoom_max)(self); } +/** + * + */ +gdouble +vik_map_source_get_lat_max (VikMapSource * self) +{ + VikMapSourceClass *klass; + g_return_val_if_fail (self != NULL, 90.0); + g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), 90.0); + klass = VIK_MAP_SOURCE_GET_CLASS(self); + g_return_val_if_fail (klass->get_lat_max != NULL, 90.0); + return (*klass->get_lat_max)(self); +} + +/** + * + */ +gdouble +vik_map_source_get_lat_min (VikMapSource * self) +{ + VikMapSourceClass *klass; + g_return_val_if_fail (self != NULL, -90.0); + g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), -90.0); + klass = VIK_MAP_SOURCE_GET_CLASS(self); + g_return_val_if_fail (klass->get_lat_min != NULL, -90.0); + return (*klass->get_lat_min)(self); +} + +/** + * + */ +gdouble +vik_map_source_get_lon_max (VikMapSource * self) +{ + VikMapSourceClass *klass; + g_return_val_if_fail (self != NULL, 180.0); + g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), 180.0); + klass = VIK_MAP_SOURCE_GET_CLASS(self); + g_return_val_if_fail (klass->get_lon_max != NULL, 180.0); + return (*klass->get_lon_max)(self); +} + +/** + * + */ +gdouble +vik_map_source_get_lon_min (VikMapSource * self) +{ + VikMapSourceClass *klass; + g_return_val_if_fail (self != NULL, -180.0); + g_return_val_if_fail (VIK_IS_MAP_SOURCE (self), -180.0); + klass = VIK_MAP_SOURCE_GET_CLASS(self); + g_return_val_if_fail (klass->get_lon_min != NULL, -180.0); + return (*klass->get_lon_min)(self); +} /** * vik_map_source_get_file_extension: diff --git a/src/vikmapsource.h b/src/vikmapsource.h index 2b11ec16..44a811e6 100644 --- a/src/vikmapsource.h +++ b/src/vikmapsource.h @@ -61,6 +61,10 @@ struct _VikMapSourceClass gboolean (* supports_download_only_new) (VikMapSource * self); guint8 (* get_zoom_min) (VikMapSource * self); guint8 (* get_zoom_max) (VikMapSource * self); + gdouble (* get_lat_min) (VikMapSource * self); + gdouble (* get_lat_max) (VikMapSource * self); + gdouble (* get_lon_min) (VikMapSource * self); + gdouble (* get_lon_max) (VikMapSource * self); const gchar * (* get_file_extension) (VikMapSource * self); gboolean (* coord_to_mapcoord) (VikMapSource * self, const VikCoord * src, gdouble xzoom, gdouble yzoom, MapCoord * dest); void (* mapcoord_to_center_coord) (VikMapSource * self, MapCoord * src, VikCoord * dest); @@ -93,6 +97,10 @@ gboolean vik_map_source_is_osm_meta_tiles (VikMapSource * self); gboolean vik_map_source_supports_download_only_new (VikMapSource * self); guint8 vik_map_source_get_zoom_min (VikMapSource * self); guint8 vik_map_source_get_zoom_max (VikMapSource * self); +gdouble vik_map_source_get_lat_min (VikMapSource * self); +gdouble vik_map_source_get_lat_max (VikMapSource * self); +gdouble vik_map_source_get_lon_min (VikMapSource * self); +gdouble vik_map_source_get_lon_max (VikMapSource * self); const gchar * vik_map_source_get_file_extension (VikMapSource * self); gboolean vik_map_source_coord_to_mapcoord (VikMapSource * self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest ); void vik_map_source_mapcoord_to_center_coord (VikMapSource * self, MapCoord *src, VikCoord *dest); diff --git a/src/vikslippymapsource.c b/src/vikslippymapsource.c index 53f3c849..54cffc8d 100644 --- a/src/vikslippymapsource.c +++ b/src/vikslippymapsource.c @@ -62,6 +62,10 @@ static gboolean _is_osm_meta_tiles (VikMapSource *self ); 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 ); @@ -76,6 +80,10 @@ struct _VikSlippyMapSourcePrivate // 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 @@ -94,6 +102,10 @@ enum 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, @@ -116,6 +128,10 @@ vik_slippy_map_source_init (VikSlippyMapSource *self) 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; @@ -178,6 +194,22 @@ vik_slippy_map_source_set_property (GObject *object, 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); @@ -245,6 +277,22 @@ vik_slippy_map_source_get_property (GObject *object, 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; @@ -304,6 +352,10 @@ vik_slippy_map_source_class_init (VikSlippyMapSourceClass *klass) 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; @@ -341,6 +393,42 @@ vik_slippy_map_source_class_init (VikSlippyMapSourceClass *klass) 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", @@ -467,6 +555,50 @@ _get_zoom_max (VikMapSource *self) 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 ) { -- 2.39.5