/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the Clear BSD license. * 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.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { /** * Property: url * {String} URL for root directory with TileGroupX subdirectories. */ url: null, /** * Property: 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()} Size (in tiles) for each tier of pyramid. * - filled during Zoomify pyramid initialization. */ tierSizeInTiles: new Array(), /** * Property: tierImageSize * {Array()} 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 - {} 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 - {} 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: * {} An exact clone of this */ 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 - {} * * 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 - {} * position - {} * * Returns: * {} 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 - {} */ 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 - {} * extent - {} * 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" });