Zoomify.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository for the
  4. * full text of the license. */
  5. /*
  6. * Development supported by a R&D grant DC08P02OUK006 - Old Maps Online
  7. * (www.oldmapsonline.org) from Ministry of Culture of the Czech Republic.
  8. */
  9. /**
  10. * @requires OpenLayers/Layer/Grid.js
  11. */
  12. /**
  13. * Class: OpenLayers.Layer.Zoomify
  14. *
  15. * Inherits from:
  16. * - <OpenLayers.Layer.Grid>
  17. */
  18. OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, {
  19. /**
  20. * Property: size
  21. * {<OpenLayers.Size>} The Zoomify image size in pixels.
  22. */
  23. size: null,
  24. /**
  25. * APIProperty: isBaseLayer
  26. * {Boolean}
  27. */
  28. isBaseLayer: true,
  29. /**
  30. * Property: standardTileSize
  31. * {Integer} The size of a standard (non-border) square tile in pixels.
  32. */
  33. standardTileSize: 256,
  34. /**
  35. * Property: tileOriginCorner
  36. * {String} This layer uses top-left as tile origin
  37. **/
  38. tileOriginCorner: "tl",
  39. /**
  40. * Property: numberOfTiers
  41. * {Integer} Depth of the Zoomify pyramid, number of tiers (zoom levels)
  42. * - filled during Zoomify pyramid initialization.
  43. */
  44. numberOfTiers: 0,
  45. /**
  46. * Property: tileCountUpToTier
  47. * {Array(Integer)} Number of tiles up to the given tier of pyramid.
  48. * - filled during Zoomify pyramid initialization.
  49. */
  50. tileCountUpToTier: null,
  51. /**
  52. * Property: tierSizeInTiles
  53. * {Array(<OpenLayers.Size>)} Size (in tiles) for each tier of pyramid.
  54. * - filled during Zoomify pyramid initialization.
  55. */
  56. tierSizeInTiles: null,
  57. /**
  58. * Property: tierImageSize
  59. * {Array(<OpenLayers.Size>)} Image size in pixels for each pyramid tier.
  60. * - filled during Zoomify pyramid initialization.
  61. */
  62. tierImageSize: null,
  63. /**
  64. * Constructor: OpenLayers.Layer.Zoomify
  65. *
  66. * Parameters:
  67. * name - {String} A name for the layer.
  68. * url - {String} - Relative or absolute path to the image or more
  69. * precisly to the TileGroup[X] directories root.
  70. * Flash plugin use the variable name "zoomifyImagePath" for this.
  71. * size - {<OpenLayers.Size>} The size (in pixels) of the image.
  72. * options - {Object} Hashtable of extra options to tag onto the layer
  73. */
  74. initialize: function(name, url, size, options) {
  75. // initilize the Zoomify pyramid for given size
  76. this.initializeZoomify(size);
  77. OpenLayers.Layer.Grid.prototype.initialize.apply(this, [
  78. name, url, size, {}, options
  79. ]);
  80. },
  81. /**
  82. * Method: initializeZoomify
  83. * It generates constants for all tiers of the Zoomify pyramid
  84. *
  85. * Parameters:
  86. * size - {<OpenLayers.Size>} The size of the image in pixels
  87. *
  88. */
  89. initializeZoomify: function( size ) {
  90. var imageSize = size.clone();
  91. this.size = size.clone();
  92. var tiles = new OpenLayers.Size(
  93. Math.ceil( imageSize.w / this.standardTileSize ),
  94. Math.ceil( imageSize.h / this.standardTileSize )
  95. );
  96. this.tierSizeInTiles = [tiles];
  97. this.tierImageSize = [imageSize];
  98. while (imageSize.w > this.standardTileSize ||
  99. imageSize.h > this.standardTileSize ) {
  100. imageSize = new OpenLayers.Size(
  101. Math.floor( imageSize.w / 2 ),
  102. Math.floor( imageSize.h / 2 )
  103. );
  104. tiles = new OpenLayers.Size(
  105. Math.ceil( imageSize.w / this.standardTileSize ),
  106. Math.ceil( imageSize.h / this.standardTileSize )
  107. );
  108. this.tierSizeInTiles.push( tiles );
  109. this.tierImageSize.push( imageSize );
  110. }
  111. this.tierSizeInTiles.reverse();
  112. this.tierImageSize.reverse();
  113. this.numberOfTiers = this.tierSizeInTiles.length;
  114. var resolutions = [1];
  115. this.tileCountUpToTier = [0];
  116. for (var i = 1; i < this.numberOfTiers; i++) {
  117. resolutions.unshift(Math.pow(2, i));
  118. this.tileCountUpToTier.push(
  119. this.tierSizeInTiles[i-1].w * this.tierSizeInTiles[i-1].h +
  120. this.tileCountUpToTier[i-1]
  121. );
  122. }
  123. if (!this.serverResolutions) {
  124. this.serverResolutions = resolutions;
  125. }
  126. },
  127. /**
  128. * APIMethod:destroy
  129. */
  130. destroy: function() {
  131. // for now, nothing special to do here.
  132. OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
  133. // Remove from memory the Zoomify pyramid - is that enough?
  134. this.tileCountUpToTier.length = 0;
  135. this.tierSizeInTiles.length = 0;
  136. this.tierImageSize.length = 0;
  137. },
  138. /**
  139. * APIMethod: clone
  140. *
  141. * Parameters:
  142. * obj - {Object}
  143. *
  144. * Returns:
  145. * {<OpenLayers.Layer.Zoomify>} An exact clone of this <OpenLayers.Layer.Zoomify>
  146. */
  147. clone: function (obj) {
  148. if (obj == null) {
  149. obj = new OpenLayers.Layer.Zoomify(this.name,
  150. this.url,
  151. this.size,
  152. this.options);
  153. }
  154. //get all additions from superclasses
  155. obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
  156. // copy/set any non-init, non-simple values here
  157. return obj;
  158. },
  159. /**
  160. * Method: getURL
  161. *
  162. * Parameters:
  163. * bounds - {<OpenLayers.Bounds>}
  164. *
  165. * Returns:
  166. * {String} A string with the layer's url and parameters and also the
  167. * passed-in bounds and appropriate tile size specified as
  168. * parameters
  169. */
  170. getURL: function (bounds) {
  171. bounds = this.adjustBounds(bounds);
  172. var res = this.getServerResolution();
  173. var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));
  174. var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));
  175. var z = this.getZoomForResolution( res );
  176. var tileIndex = x + y * this.tierSizeInTiles[z].w + this.tileCountUpToTier[z];
  177. var path = "TileGroup" + Math.floor( (tileIndex) / 256 ) +
  178. "/" + z + "-" + x + "-" + y + ".jpg";
  179. var url = this.url;
  180. if (OpenLayers.Util.isArray(url)) {
  181. url = this.selectUrl(path, url);
  182. }
  183. return url + path;
  184. },
  185. /**
  186. * Method: getImageSize
  187. * getImageSize returns size for a particular tile. If bounds are given as
  188. * first argument, size is calculated (bottom-right tiles are non square).
  189. *
  190. */
  191. getImageSize: function() {
  192. if (arguments.length > 0) {
  193. var bounds = this.adjustBounds(arguments[0]);
  194. var res = this.getServerResolution();
  195. var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));
  196. var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));
  197. var z = this.getZoomForResolution( res );
  198. var w = this.standardTileSize;
  199. var h = this.standardTileSize;
  200. if (x == this.tierSizeInTiles[z].w -1 ) {
  201. var w = this.tierImageSize[z].w % this.standardTileSize;
  202. }
  203. if (y == this.tierSizeInTiles[z].h -1 ) {
  204. var h = this.tierImageSize[z].h % this.standardTileSize;
  205. }
  206. return (new OpenLayers.Size(w, h));
  207. } else {
  208. return this.tileSize;
  209. }
  210. },
  211. /**
  212. * APIMethod: setMap
  213. * When the layer is added to a map, then we can fetch our origin
  214. * (if we don't have one.)
  215. *
  216. * Parameters:
  217. * map - {<OpenLayers.Map>}
  218. */
  219. setMap: function(map) {
  220. OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
  221. this.tileOrigin = new OpenLayers.LonLat(this.map.maxExtent.left,
  222. this.map.maxExtent.top);
  223. },
  224. CLASS_NAME: "OpenLayers.Layer.Zoomify"
  225. });