[FOSS-GPS] Whats up with FoxtrotGPS?
Joshua Judson Rosen
rozzin at geekspace.com
Sat Dec 25 09:30:28 EST 2010
John Stowers <john.stowers.lists at gmail.com> 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:
-------------- next part --------------
>From 2dcfc5e04117152a0bb97523aa32278c7e8fe537 Mon Sep 17 00:00:00 2001
From: Joshua Judson Rosen <rozzin at geekspace.com>
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 <rozzin at geekspace.com>
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 <rozzin at geekspace.com>
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 <rozzin at geekspace.com>
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
-------------- next part --------------
--
"Don't be afraid to ask (?f.((?x.xx) (?r.f(rr))))."
More information about the FOSS-GPS
mailing list