[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