[OpenLayers-Commits] r7301 - in sandbox/klokan/openlayers: examples lib lib/OpenLayers/Layer lib/OpenLayers/Tile

commits at openlayers.org commits at openlayers.org
Tue Jun 3 02:25:01 EDT 2008


Author: klokan
Date: 2008-06-03 02:25:01 -0400 (Tue, 03 Jun 2008)
New Revision: 7301

Added:
   sandbox/klokan/openlayers/examples/zoomify.html
   sandbox/klokan/openlayers/lib/OpenLayers/Layer/Zoomify.js
Modified:
   sandbox/klokan/openlayers/lib/OpenLayers.js
   sandbox/klokan/openlayers/lib/OpenLayers/Tile/Image.js
Log:
OpenLayers Zoomify patch for #1285

Added: sandbox/klokan/openlayers/examples/zoomify.html
===================================================================
--- sandbox/klokan/openlayers/examples/zoomify.html	                        (rev 0)
+++ sandbox/klokan/openlayers/examples/zoomify.html	2008-06-03 06:25:01 UTC (rev 7301)
@@ -0,0 +1,70 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>OpenLayers Zoomify Example</title>
+    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="style.css" type="text/css" />
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+
+        var zoomify_width = 8001;
+		var zoomify_height = 6943;
+		var zoomify_url = "http://almor.mzk.cz/moll/AA22/0103/";
+
+        var map, zoomify;
+
+        function init(){
+	       /* First we initialize the zoomify pyramid (to get number of tiers) */
+	        var zoomify = new OpenLayers.Layer.Zoomify( "Zoomify", zoomify_url, 
+		  		new OpenLayers.Size( zoomify_width, zoomify_height ) );
+
+	       /* Map with raster coordinates (pixels) from Zoomify image */
+	        var options = {
+	            controls: [],
+	            maxExtent: new OpenLayers.Bounds(0, 0, zoomify_width, zoomify_height),
+	            maxResolution: Math.pow(2, zoomify.numberOfTiers-1 ),
+	            numZoomLevels: zoomify.numberOfTiers,
+	            units: 'pixels'
+	        };
+
+	        map = new OpenLayers.Map("map", options);
+	        map.addLayer(zoomify);
+
+	        map.addControl(new OpenLayers.Control.MousePosition());
+	        map.addControl(new OpenLayers.Control.PanZoomBar());
+	        map.addControl(new OpenLayers.Control.MouseDefaults());
+	        map.addControl(new OpenLayers.Control.KeyboardDefaults());
+
+            map.setBaseLayer(zoomify);
+	        map.zoomToMaxExtent();
+        };
+    </script>
+  </head>
+  <body onload="init()">
+      <h1 id="title">Zoomify Layer Example</h1>
+
+    <div id="tags"></div>
+
+    <p id="shortdesc">
+        Demo of a layer with Zoomify tiles.
+    </p>
+
+    <div id="map" class="smallmap"></div>
+
+    <div id="docs">
+	    <p>
+	    Demonstration of the Zoomify layer in OpenLayers.<br />
+	 	You can have a look at <a href="http://almor.mzk.cz/moll/AA22/103.html">Zoomify viewer for this picture</a>, which is using the same <a href="http://almor.mzk.cz/moll/AA22/0103/">tiles</a>.
+	    </p>
+		<p>
+		For change to our own image you have to specify 'url' (zoomifyImagePath in Zoomify terminology) and 'size' ('width' and 'height' from ImageProperty.xml file).<br />
+		Custom tiles can be easily generated with original <a href="http://www.zoomify.com/">Zoomify software</a> like with freely available <a href="http://www.zoomify.com/express.htm">ZoomifyerEZ</a> or with Adobe PhotoShop CS3 (it has built in support for export into Zoomify tiles).<br />
+		There is also a <a href="http://sourceforge.net/projects/zoomifyimage/">ZoomifyImage SourceForge Project</a>, a tile cutter available under GPL license.<br />
+		Zoomify tiles can be also served dynamically on the server side from JPEG2000 masters using <a href="http://dltj.org/article/introducing-j2ktilerenderer/">J2KTileRender</a> with available integration for DSpace and soon for Fedora Digital Repository.<br/>
+		<a href="http://iipimage.sourceforge.net/">IIPImage server</a> can serve Zoomify tiles dynamically from TIFF files.
+		</p>
+		<p>
+		Development of the Zoomify support for OpenLayers was supported from the grant <a href="http://www.oldmapsonline.org/">Old Maps Online</a>.
+        </p>
+    </div>
+  </body>
+</html>

Added: sandbox/klokan/openlayers/lib/OpenLayers/Layer/Zoomify.js
===================================================================
--- sandbox/klokan/openlayers/lib/OpenLayers/Layer/Zoomify.js	                        (rev 0)
+++ sandbox/klokan/openlayers/lib/OpenLayers/Layer/Zoomify.js	2008-06-03 06:25:01 UTC (rev 7301)
@@ -0,0 +1,306 @@
+/* Copyright (c) 2008 Klokan Petr Pridal, published under the Clear BSD
+ * licence.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license.
+ *
+ * Development supported by a R&D grant DC08P02OUK006 - Old Maps Online
+ * (www.oldmapsonline.org) from Ministry of Culture of the Czech Republic.  
+ */
+
+
+/**
+ * @requires OpenLayers/Layer/Grid.js
+ */
+
+/**
+ * Class: OpenLayers.Layer.Zoomify
+ * 
+ * Inherits from:
+ *  - <OpenLayers.Layer.Grid>
+ */
+OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, {
+
+    /**
+     * Property: url
+     * {String} URL for root directory with TileGroupX subdirectories.
+     */
+    url: null,
+
+    /**
+     * Property: size
+     * {<OpenLayers.Size>} The Zoomify image size in pixels.
+     */
+    size: null,
+
+    /**
+     * APIProperty: isBaseLayer
+     * {Boolean}
+     */
+    isBaseLayer: true,
+
+    /**
+     * Property: standardTileSize
+     * {Integer} The size of a standard (non-border) square tile in pixels.
+     */
+    standardTileSize: 256,
+
+    /**
+     * Property: numberOfTiers
+     * {Integer} Depth of the Zoomify pyramid, number of tiers (zoom levels)
+     *            				- filled during Zoomify pyramid initialization.
+     */
+	numberOfTiers: 0,
+
+    /**
+     * Property: tileCountUpToTier
+     * {Array(Integer)} Number of tiles up to the given tier of pyramid.
+     *            				- filled during Zoomify pyramid initialization.
+     */
+	tileCountUpToTier: new Array(),
+
+    /**
+     * Property: tierSizeInTiles
+     * {Array(<OpenLayers.Size>)} Size (in tiles) for each tier of pyramid.
+     *            				- filled during Zoomify pyramid initialization.
+     */
+	tierSizeInTiles: new Array(),
+
+    /**
+     * Property: tierImageSize
+     * {Array(<OpenLayers.Size>)} Image size in pixels for each pyramid tier.
+     *            				- filled during Zoomify pyramid initialization.
+     */
+	tierImageSize: new Array(),
+
+    /**
+     * Constructor: OpenLayers.Layer.Zoomify
+     * 
+     * Parameters:
+     * name - {String} A name for the layer.
+     * url - {String} - Relative or absolute path to the image or more
+     *        precisly to the TileGroup[X] directories root.
+     *        Flash plugin use the variable name "zoomifyImagePath" for this.
+     * size - {<OpenLayers.Size>} The size (in pixels) of the image.
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, url, size, options) {
+		
+		// initilize the Zoomify pyramid for given size
+		this.initializeZoomify( size );
+
+        var newArguments = [];
+        newArguments.push(name, url, size, {}, options);
+
+        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
+    },    
+
+    /**
+     * Method: initializeZoomify
+     * It generates constants for all tiers of the Zoomify pyramid
+     * 
+     * Parameters:
+     * size - {<OpenLayers.Size>} The size of the image in pixels
+     * 
+     */
+	initializeZoomify: function( size ) {
+		
+		var imageSize = size.clone()
+		var tiles = new OpenLayers.Size(
+			Math.ceil( imageSize.w / this.standardTileSize ),
+			Math.ceil( imageSize.h / this.standardTileSize )
+			);
+
+		this.tierSizeInTiles.push( tiles );
+		this.tierImageSize.push( imageSize );
+		
+	    while (imageSize.w > this.standardTileSize ||
+			   imageSize.h > this.standardTileSize ) {
+										
+			imageSize = new OpenLayers.Size(
+				Math.floor( imageSize.w / 2 ),
+				Math.floor( imageSize.h / 2 )
+				);
+			tiles = new OpenLayers.Size(
+				Math.ceil( imageSize.w / this.standardTileSize ),
+				Math.ceil( imageSize.h / this.standardTileSize )
+				);
+			this.tierSizeInTiles.push( tiles );
+			this.tierImageSize.push( imageSize );
+	    }
+
+	    this.tierSizeInTiles.reverse();
+	    this.tierImageSize.reverse();
+	
+		this.numberOfTiers = this.tierSizeInTiles.length;
+						
+		this.tileCountUpToTier[0] = 0;		
+		for (var i = 1; i < this.numberOfTiers; i++) {
+			this.tileCountUpToTier.push(
+				this.tierSizeInTiles[i-1].w * this.tierSizeInTiles[i-1].h +
+				this.tileCountUpToTier[i-1]
+				);
+		}
+	},
+
+    /**
+     * APIMethod:destroy
+     */
+    destroy: function() {
+        // for now, nothing special to do here. 
+        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
+
+		// Remove from memory the Zoomify pyramid - is that enough?
+		this.tileCountUpToTier.length = 0
+		this.tierSizeInTiles.length = 0
+		this.tierImageSize.length = 0
+
+    },
+    
+    /**
+     * APIMethod: clone
+     * 
+     * Parameters:
+     * obj - {Object}
+     * 
+     * Returns:
+     * {<OpenLayers.Layer.Zoomify>} An exact clone of this <OpenLayers.Layer.Zoomify>
+     */
+    clone: function (obj) {
+        
+        if (obj == null) {
+            obj = new OpenLayers.Layer.Zoomify(this.name,
+                                           this.url,
+										   this.size,
+                                           this.options);
+        }
+
+        //get all additions from superclasses
+        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
+
+        // copy/set any non-init, non-simple values here
+
+        return obj;
+    },    
+    
+    /**
+     * Method: getURL
+     * 
+     * Parameters:
+     * bounds - {<OpenLayers.Bounds>}
+     * 
+     * Returns:
+     * {String} A string with the layer's url and parameters and also the 
+     *          passed-in bounds and appropriate tile size specified as 
+     *          parameters
+     */
+    getURL: function (bounds) {
+        bounds = this.adjustBounds(bounds);
+        var res = this.map.getResolution();
+        var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));
+        var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));
+        var z = this.map.getZoom();
+
+		var tileIndex = x + y * this.tierSizeInTiles[z].w + this.tileCountUpToTier[z];
+		var path = "TileGroup" + Math.floor( (tileIndex) / 256 ) +
+			"/" + z + "-" + x + "-" + y + ".jpg";
+        var url = this.url;
+        if (url instanceof Array) {
+            url = this.selectUrl(path, url);
+        }
+        return url + path;
+    },
+
+    /**
+     * Method: getImageSize
+     * getImageSize returns size for a particular tile. If bounds are given as
+     * first argument, size is calculated (bottom-right tiles are non square).
+     * 
+     */
+    getImageSize: function() {
+		if (arguments.length > 0) {
+	        bounds = this.adjustBounds(arguments[0]);
+	        var res = this.map.getResolution();
+	        var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));
+	        var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));
+	        var z = this.map.getZoom();
+			var w = this.standardTileSize;
+			var h = this.standardTileSize;
+			if (x == this.tierSizeInTiles[z].w -1 ) {
+				var w = this.tierImageSize[z].w % this.standardTileSize;
+			};
+			if (y == this.tierSizeInTiles[z].h -1 ) {
+				var h = this.tierImageSize[z].h % this.standardTileSize;
+			};
+	        return (new OpenLayers.Size(w, h));
+		} else {
+			return this.tileSize;
+		}
+    },
+
+    /**
+     * Method: addTile
+     * addTile creates a tile, initializes it, and adds it to the layer div. 
+     * 
+     * Parameters:
+     * bounds - {<OpenLayers.Bounds>}
+     * position - {<OpenLayers.Pixel>}
+     * 
+     * Returns:
+     * {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
+     */
+    addTile:function(bounds,position) {
+        return new OpenLayers.Tile.Image(this, position, bounds, 
+                                         null, this.tileSize);
+    },
+
+    /** 
+     * APIMethod: setMap
+     * When the layer is added to a map, then we can fetch our origin 
+     *    (if we don't have one.) 
+     * 
+     * Parameters:
+     * map - {<OpenLayers.Map>}
+     */
+    setMap: function(map) {
+        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
+        this.tileOrigin = new OpenLayers.LonLat(this.map.maxExtent.left,
+                                                this.map.maxExtent.top);
+    },
+
+    /** 
+     * Method: calculateGridLayout
+     * Generate parameters for the grid layout. This  
+     *
+     * Parameters:
+     * bounds - {<OpenLayers.Bound>}
+     * extent - {<OpenLayers.Bounds>}
+     * resolution - {Number}
+     *
+     * Returns:
+     * Object containing properties tilelon, tilelat, tileoffsetlat,
+     * tileoffsetlat, tileoffsetx, tileoffsety
+     */
+    calculateGridLayout: function(bounds, extent, resolution) {
+        var tilelon = resolution * this.tileSize.w;
+        var tilelat = resolution * this.tileSize.h;
+        
+        var offsetlon = bounds.left - extent.left;
+        var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
+        var tilecolremain = offsetlon/tilelon - tilecol;
+        var tileoffsetx = -tilecolremain * this.tileSize.w;
+        var tileoffsetlon = extent.left + tilecol * tilelon;
+        
+        var offsetlat = extent.top - bounds.top + tilelat; 
+        var tilerow = Math.floor(offsetlat/tilelat) - this.buffer;
+        var tilerowremain = tilerow - offsetlat/tilelat;
+        var tileoffsety = tilerowremain * this.tileSize.h;
+        var tileoffsetlat = extent.top - tilelat*tilerow;
+        
+        return { 
+          tilelon: tilelon, tilelat: tilelat,
+          tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
+          tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
+        };
+    },	
+
+    CLASS_NAME: "OpenLayers.Layer.Zoomify"
+});
\ No newline at end of file

Modified: sandbox/klokan/openlayers/lib/OpenLayers/Tile/Image.js
===================================================================
--- sandbox/klokan/openlayers/lib/OpenLayers/Tile/Image.js	2008-05-31 17:19:48 UTC (rev 7300)
+++ sandbox/klokan/openlayers/lib/OpenLayers/Tile/Image.js	2008-06-03 06:25:01 UTC (rev 7301)
@@ -166,7 +166,7 @@
         OpenLayers.Util.modifyDOMElement(this.frame, 
                                          null, this.position, this.size);   
 
-        var imageSize = this.layer.getImageSize(); 
+        var imageSize = this.layer.getImageSize( this.bounds ); 
         if (this.layerAlphaHack) {
             OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,
                     null, null, imageSize, this.url);
@@ -199,7 +199,7 @@
     initImgDiv: function() {
         
         var offset = this.layer.imageOffset; 
-        var size = this.layer.getImageSize(); 
+        var size = this.layer.getImageSize( this.bounds );
      
         if (this.layerAlphaHack) {
             this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null,

Modified: sandbox/klokan/openlayers/lib/OpenLayers.js
===================================================================
--- sandbox/klokan/openlayers/lib/OpenLayers.js	2008-05-31 17:19:48 UTC (rev 7300)
+++ sandbox/klokan/openlayers/lib/OpenLayers.js	2008-06-03 06:25:01 UTC (rev 7301)
@@ -118,6 +118,7 @@
             "OpenLayers/Layer/Boxes.js",
             "OpenLayers/Layer/TMS.js",
             "OpenLayers/Layer/TileCache.js",
+            "OpenLayers/Layer/Zoomify.js",
             "OpenLayers/Popup/Anchored.js",
             "OpenLayers/Popup/AnchoredBubble.js",
             "OpenLayers/Popup/Framed.js",



More information about the Commits mailing list