John Stowers <[email protected]> writes: > > On Thu, 2010-11-04 at 12:48 -0400, Joshua Judson Rosen wrote: > > > > Did you have any thoughts on adding a `zoom offset' control > > to osm-gps-map? > > Sorry, I don't know what you mean by this, would you care to explain?
Something like this:
>From 2dcfc5e04117152a0bb97523aa32278c7e8fe537 Mon Sep 17 00:00:00 2001 From: Joshua Judson Rosen <[email protected]> Date: Fri, 24 Dec 2010 17:23:29 -0500 Subject: [PATCH] Use osm_gps_map_blit_tile() consistently (don't duplicate its code in osm_gps_map_load_tile()). --- src/osm-gps-map-widget.c | 8 +------- 1 files changed, 1 insertions(+), 7 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 06c0dd7..7ced161 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1062,13 +1062,7 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int * levels */ pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y); if (pixbuf) { - gdk_draw_pixbuf (priv->pixmap, - priv->gc_map, - pixbuf, - 0,0, - offset_x,offset_y, - TILESIZE,TILESIZE, - GDK_RGB_DITHER_NONE, 0, 0); + osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y); g_object_unref (pixbuf); } else { /* prevent some artifacts when drawing not yet loaded areas. */ -- 1.5.6.5 >From d17d86ae1aae53f373e240d9b7926f26af79af58 Mon Sep 17 00:00:00 2001 From: Joshua Judson Rosen <[email protected]> Date: Fri, 24 Dec 2010 17:25:14 -0500 Subject: [PATCH] Split the upscaling logic from osm_gps_map_render_missing_tile_upscaled() into osm_gps_map_render_tile_upscaled(). --- src/osm-gps-map-widget.c | 25 +++++++++++++++++++++---- 1 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 7ced161..79da9ed 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -319,6 +319,7 @@ static void osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, i static void osm_gps_map_fill_tiles_pixel (OsmGpsMap *map); static gboolean osm_gps_map_map_redraw (OsmGpsMap *map); static void osm_gps_map_map_redraw_idle (OsmGpsMap *map); +static GdkPixbuf* osm_gps_map_render_tile_upscaled (OsmGpsMap *map, GdkPixbuf *tile, int tile_zoom, int zoom, int x, int y); static void cached_tile_free (OsmCachedTile *tile) @@ -993,24 +994,40 @@ static GdkPixbuf * osm_gps_map_render_missing_tile_upscaled (OsmGpsMap *map, int zoom, int x, int y) { - GdkPixbuf *pixbuf, *big, *area; - int zoom_big, zoom_diff, area_size, area_x, area_y; - int modulo; + GdkPixbuf *pixbuf, *big; + int zoom_big; big = osm_gps_map_find_bigger_tile (map, zoom, x, y, &zoom_big); if (!big) return NULL; g_debug ("Found bigger tile (zoom = %d, wanted = %d)", zoom_big, zoom); + pixbuf = osm_gps_map_render_tile_upscaled (map, big, zoom_big, + zoom, x, y); + g_object_unref (big); + + return pixbuf; +} +static GdkPixbuf* +osm_gps_map_render_tile_upscaled (OsmGpsMap *map, GdkPixbuf *big, int zoom_big, + int zoom, int x, int y) +{ + GdkPixbuf *pixbuf, *area; + int area_size, area_x, area_y; + int modulo; + int zoom_diff; + /* get a Pixbuf for the area to magnify */ zoom_diff = zoom - zoom_big; + + g_debug ("Upscaling by %d levels into tile %d,%d", zoom_diff, x, y); + area_size = TILESIZE >> zoom_diff; modulo = 1 << zoom_diff; area_x = (x % modulo) * area_size; area_y = (y % modulo) * area_size; area = gdk_pixbuf_new_subpixbuf (big, area_x, area_y, area_size, area_size); - g_object_unref (big); pixbuf = gdk_pixbuf_scale_simple (area, TILESIZE, TILESIZE, GDK_INTERP_NEAREST); g_object_unref (area); -- 1.5.6.5 >From 0e30312daada1fa6924bed9ca1ac2e8cefef37e2 Mon Sep 17 00:00:00 2001 From: Joshua Judson Rosen <[email protected]> Date: Fri, 24 Dec 2010 17:28:47 -0500 Subject: [PATCH] Enable osm_gps_map_blit_tile() to handle tiles from lower zoom-levels, upscaling as necessary. Added tile_zoom, target_x, and target_y arguments to facilitate that. --- src/osm-gps-map-widget.c | 42 +++++++++++++++++++++++++++++------------- 1 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 79da9ed..d7f9591 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -308,7 +308,7 @@ G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); */ static gchar *replace_string(const gchar *src, const gchar *from, const gchar *to); static gchar *replace_map_uri(OsmGpsMap *map, const gchar *uri, int zoom, int x, int y); -static void osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y); +static void osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y, int tile_zoom, int target_x, int target_y); #if USE_LIBSOUP22 static void osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data); #else @@ -708,20 +708,33 @@ osm_gps_map_draw_gps_point (OsmGpsMap *map, GdkDrawable *drawable) } static void -osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y) +osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y, + int tile_zoom, int target_x, int target_y) { OsmGpsMapPrivate *priv = map->priv; + int target_zoom = priv->map_zoom; g_debug("Queing redraw @ %d,%d (w:%d h:%d)", offset_x,offset_y, TILESIZE,TILESIZE); - /* draw pixbuf onto pixmap */ - gdk_draw_pixbuf (priv->pixmap, - priv->gc_map, - pixbuf, - 0,0, - offset_x,offset_y, - TILESIZE,TILESIZE, - GDK_RGB_DITHER_NONE, 0, 0); + if (tile_zoom == target_zoom) { + /* draw pixbuf onto pixmap */ + gdk_draw_pixbuf (priv->pixmap, + priv->gc_map, + pixbuf, + 0,0, + offset_x,offset_y, + TILESIZE,TILESIZE, + GDK_RGB_DITHER_NONE, 0, 0); + } else { + /* get an upscaled version of the pixbuf, and then draw it */ + GdkPixbuf *pixmap_scaled = osm_gps_map_render_tile_upscaled + (map, pixbuf, tile_zoom, target_zoom, target_x, target_y); + + osm_gps_map_blit_tile (map, pixmap_scaled, offset_x, offset_y, + target_zoom, target_x, target_y); + + g_object_unref (pixmap_scaled); + } } /* libsoup-2.2 and libsoup-2.4 use different ways to store the body data */ @@ -1051,7 +1064,8 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int g_debug("Load tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); if (priv->map_source == OSM_GPS_MAP_SOURCE_NULL) { - osm_gps_map_blit_tile(map, priv->null_tile, offset_x,offset_y); + osm_gps_map_blit_tile(map, priv->null_tile, offset_x, offset_y, + priv->map_zoom, x, y); return; } @@ -1068,7 +1082,8 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int if(pixbuf) { g_debug("Found tile %s", filename); - osm_gps_map_blit_tile(map, pixbuf, offset_x,offset_y); + osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y, + zoom, x, y); g_object_unref (pixbuf); } else { if (priv->map_auto_download_enabled) { @@ -1079,7 +1094,8 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int * levels */ pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y); if (pixbuf) { - osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y); + osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y, + zoom, x, y); g_object_unref (pixbuf); } else { /* prevent some artifacts when drawing not yet loaded areas. */ -- 1.5.6.5 >From deffe10e177141a9e88f018bf8da74d7296e8c1c Mon Sep 17 00:00:00 2001 From: Joshua Judson Rosen <[email protected]> Date: Fri, 24 Dec 2010 17:34:56 -0500 Subject: [PATCH] Support a `tile zoom-offset' property on map-objects. This allows OsmGpsMap to be configured to always use upscaled tiles from lower zoom-levels, which is useful, for example, on displays with much higher resolution than expected my a tile-set's rasteriser, for displays viewed from greater distances, or for devices on slower networks. --- src/osm-gps-map-widget.c | 57 ++++++++++++++++++++++++++++++++++++++++++--- src/osm-gps-map-widget.h | 1 + src/private.h | 3 ++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index d7f9591..deac8f0 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -156,6 +156,9 @@ struct _OsmGpsMapPrivate int map_zoom; int max_zoom; int min_zoom; + + int tile_zoom_offset; + int map_x; int map_y; @@ -283,6 +286,7 @@ enum PROP_TILE_CACHE_DIR, PROP_TILE_CACHE_BASE_DIR, PROP_TILE_CACHE_DIR_IS_FULL_PATH, + PROP_TILE_ZOOM_OFFSET, PROP_ZOOM, PROP_MAX_ZOOM, PROP_MIN_ZOOM, @@ -1060,12 +1064,22 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int OsmGpsMapPrivate *priv = map->priv; gchar *filename; GdkPixbuf *pixbuf; + int zoom_offset = priv->tile_zoom_offset; + int target_x, target_y; - g_debug("Load tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); + g_debug("Load virtual tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); + + if (zoom > MIN_ZOOM) { + zoom -= zoom_offset; + target_x = x; x >>= zoom_offset; + target_y = y; y >>= zoom_offset; + } + + g_debug("Load actual tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); if (priv->map_source == OSM_GPS_MAP_SOURCE_NULL) { osm_gps_map_blit_tile(map, priv->null_tile, offset_x, offset_y, - priv->map_zoom, x, y); + priv->map_zoom, target_x, target_y); return; } @@ -1083,7 +1097,7 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int if(pixbuf) { g_debug("Found tile %s", filename); osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y, - zoom, x, y); + zoom, target_x, target_y); g_object_unref (pixbuf); } else { if (priv->map_auto_download_enabled) { @@ -1095,7 +1109,7 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y); if (pixbuf) { osm_gps_map_blit_tile(map, pixbuf, offset_x, offset_y, - zoom, x, y); + zoom, target_x, target_y); g_object_unref (pixbuf); } else { /* prevent some artifacts when drawing not yet loaded areas. */ @@ -1800,6 +1814,9 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G break; case PROP_TILE_CACHE_DIR_IS_FULL_PATH: break; + case PROP_TILE_ZOOM_OFFSET: + priv->tile_zoom_offset = g_value_get_int (value); + break; case PROP_ZOOM: priv->map_zoom = g_value_get_int (value); break; @@ -1897,6 +1914,9 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS case PROP_TILE_CACHE_DIR_IS_FULL_PATH: g_value_set_boolean(value, FALSE); break; + case PROP_TILE_ZOOM_OFFSET: + g_value_set_int(value, priv->tile_zoom_offset); + break; case PROP_ZOOM: g_value_set_int(value, priv->map_zoom); break; @@ -2485,6 +2505,16 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, + PROP_TILE_ZOOM_OFFSET, + g_param_spec_int ("tile-zoom-offset", + "tile zoom-offset", + "Number of zoom-levels to upsample tiles", + MIN_TILE_ZOOM_OFFSET, /* minimum propery value */ + MAX_TILE_ZOOM_OFFSET, /* maximum propery value */ + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_MAX_ZOOM, g_param_spec_int ("max-zoom", "max zoom", @@ -2794,6 +2824,25 @@ osm_gps_map_set_center (OsmGpsMap *map, float latitude, float longitude) } /** + * osm_gps_map_set_zoom_offset: + * + **/ +void +osm_gps_map_set_zoom_offset (OsmGpsMap *map, int zoom_offset) +{ + OsmGpsMapPrivate *priv; + + g_return_if_fail (OSM_GPS_MAP (map)); + priv = map->priv; + + if (zoom_offset != priv->tile_zoom_offset) + { + priv->tile_zoom_offset = zoom_offset; + osm_gps_map_map_redraw_idle (map); + } +} + +/** * osm_gps_map_set_zoom: * **/ diff --git a/src/osm-gps-map-widget.h b/src/osm-gps-map-widget.h index da76529..29be13b 100644 --- a/src/osm-gps-map-widget.h +++ b/src/osm-gps-map-widget.h @@ -89,6 +89,7 @@ void osm_gps_map_get_bbox (OsmGpsMap *map, OsmGpsM void osm_gps_map_set_center_and_zoom (OsmGpsMap *map, float latitude, float longitude, int zoom); void osm_gps_map_set_center (OsmGpsMap *map, float latitude, float longitude); int osm_gps_map_set_zoom (OsmGpsMap *map, int zoom); +void osm_gps_map_set_zoom_offset (OsmGpsMap *map, int zoom_offset); int osm_gps_map_zoom_in (OsmGpsMap *map); int osm_gps_map_zoom_out (OsmGpsMap *map); void osm_gps_map_scroll (OsmGpsMap *map, gint dx, gint dy); diff --git a/src/private.h b/src/private.h index 637338f..33c89f9 100644 --- a/src/private.h +++ b/src/private.h @@ -34,6 +34,9 @@ #define MAX_ZOOM 20 #define MIN_ZOOM 0 +#define MAX_TILE_ZOOM_OFFSET 10 +#define MIN_TILE_ZOOM_OFFSET 0 + #define OSM_REPO_URI "http://tile.openstreetmap.org/#Z/#X/#Y.png" #define OSM_MIN_ZOOM 1 #define OSM_MAX_ZOOM 18 -- 1.5.6.5
-- "Don't be afraid to ask (λf.((λx.xx) (λr.f(rr))))."
_______________________________________________ This message is sent to you from [email protected] mailing list. Visit http://lists.osgeo.org/mailman/listinfo/foss-gps to manage your subscription For more information, check http://wiki.osgeo.org/wiki/FOSS-GPS
