add link-to-image feature
authorTero Marttila <terom@fixme.fi>
Wed, 06 Jan 2010 17:45:29 +0200
changeset 40 5454d2e2f633
parent 39 eeedb6c2f7c0
child 41 941090e3d094
child 43 fcd818eb5a71
add link-to-image feature
pngtile/wsgi.py
static/style.css
static/tiles2.js
--- a/pngtile/wsgi.py	Wed Jan 06 17:07:24 2010 +0200
+++ b/pngtile/wsgi.py	Wed Jan 06 17:45:29 2010 +0200
@@ -64,6 +64,7 @@
                 <div class="overlay">
                     <input type="button" id="btn-zoom-in" value="Zoom In" />
                     <input type="button" id="btn-zoom-out" value="Zoom Out" />
+                    <a class="link" id="lnk-image" href="#"></a>
                 </div>
 
                 <div class="substrate"></div>
@@ -94,13 +95,23 @@
     else :
         return val
 
-def render_tile (image, x, y, zoom) :
+def render_tile (image, x, y, zoom, width=TILE_WIDTH, height=TILE_HEIGHT) :
     return image.tile_mem(
-        TILE_WIDTH, TILE_HEIGHT, 
+        width, height, 
         scale_by_zoom(x, -zoom), scale_by_zoom(y, -zoom), 
         zoom
     )
 
+def render_image (image, cx, cy, zoom, width, height) :
+    x = scale_by_zoom(cx - width / 2, -zoom)
+    y = scale_by_zoom(cy - height / 2, -zoom)
+
+    return image.tile_mem(
+        width, height,
+        x, y,
+        zoom
+   )
+
 def handle_main (req) :
     # path to image
     image_name = req.path.lstrip('/')
@@ -144,11 +155,22 @@
         # viewport
         return Response(image_view(req, image_path, image), content_type="text/html")
 
+    elif 'w' in req.args and 'h' in req.args and 'cx' in req.args and 'cy' in req.args :
+        # specific image
+        width = int(req.args['w'])
+        height = int(req.args['h'])
+        cx = int(req.args['cx'])
+        cy = int(req.args['cy'])
+        zoom = int(req.args.get('zl', "0"))
+
+        # yay full render
+        return Response(render_image(image, cx, cy, zoom, width, height), content_type="image/png")
+
     elif 'x' in req.args and 'y' in req.args :
         # tile
         x = int(req.args['x'])
         y = int(req.args['y'])
-        zoom = int(req.args.get('zoom', "0"))
+        zoom = int(req.args.get('zl', "0"))
         
         # yay render
         return Response(render_tile(image, x, y, zoom), content_type="image/png")
--- a/static/style.css	Wed Jan 06 17:07:24 2010 +0200
+++ b/static/style.css	Wed Jan 06 17:45:29 2010 +0200
@@ -38,3 +38,10 @@
     z-index: 1000;
 }
 
+.link {
+    color: #000000;
+
+    padding: 2px;
+
+    background-color: #FFFFFF;
+}
--- a/static/tiles2.js	Wed Jan 06 17:07:24 2010 +0200
+++ b/static/tiles2.js	Wed Jan 06 17:45:29 2010 +0200
@@ -26,7 +26,7 @@
         var x = col * this.tile_width;
         var y = row * this.tile_height;
 
-        var url = this.path + "?x=" + x + "&y=" + y + "&zoom=" + zl + "&sw=" + sw + "&sh=" + sh;
+        var url = this.path + "?x=" + x + "&y=" + y + "&zl=" + zl; // + "&sw=" + sw + "&sh=" + sh;
 
         if (this.refresh)
             url += "&ts=" + new Date().getTime();
@@ -36,6 +36,11 @@
 
         return url;
     },
+
+    // build an URL for a full image
+    build_image_url: function (cx, cy, w, h, zl) {
+        return (this.path + "?cx=" + cx + "&cy=" + cy + "&w=" + w + "&h=" + h + "&zl=" + zl);
+    }
 });
 
 // a viewport that contains a substrate which contains several zoom layers which contain many tiles
@@ -84,6 +89,9 @@
         // set viewport size
         this.update_size();
         
+        // this comes after update_size, since it must be updated once we have the size and zoom layer...
+        this.image_link = $("lnk-image");
+        
         // initial location?    
         if (document.location.hash) {
             // x:y:z tuple
@@ -282,6 +290,8 @@
 
         this.center_offset_x = Math.floor(this.view_width / 2);
         this.center_offset_y = Math.floor(this.view_height / 2);
+
+        this.update_image_link();
     },
     
     // figure out the scroll offset as absolute pixel co-ordinates at the top left
@@ -354,6 +364,8 @@
         
         if (this.btn_zoom_out)
             (this.zoom_layer.level <= this.source.zoom_min) ? this.btn_zoom_out.disable() : this.btn_zoom_out.enable();
+        
+        this.update_image_link();
     },
     
     // ensure that all tiles that are currently visible are loaded
@@ -414,10 +426,33 @@
                 }
             }
         }
+        
+        this.update_scroll_ui();
+    }, 
+    
+    // update scroll-dependant UI elements
+    update_scroll_ui: function () {
+        // update link-to-image
+        this.update_image_link();
 
         // update the link-to-this-page thing
         document.location.hash = "#" + (this.scroll_x + this.center_offset_x) + ":" + (this.scroll_y + this.center_offset_y) + ":" + this.zoom_layer.level;
-    }, 
+    },
+    
+    // update image link with size, zoom, pos
+    update_image_link: function () {
+        if (!this.image_link)
+            return;
+
+        this.image_link.href = this.source.build_image_url(
+            this.scroll_x + this.center_offset_x,
+            this.scroll_y + this.center_offset_y,
+            this.view_width, this.view_height,
+            this.zoom_layer.level
+        );
+
+        this.image_link.innerHTML = this.view_width + "x" + this.view_height + "@" + this.zoom_layer.level;
+    },
 
     // do update_tiles after 100ms, unless we are called again
     update_after_timeout: function () {