More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Layer / Zoomify.js
blob:a/labs/openlayers/lib/OpenLayers/Layer/Zoomify.js -> blob:b/labs/openlayers/lib/OpenLayers/Layer/Zoomify.js
  /* 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.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"
  });