[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