Image.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the Clear BSD license.
  3. * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/Layer.js
  7. * @requires OpenLayers/Tile/Image.js
  8. */
  9. /**
  10. * Class: OpenLayers.Layer.Image
  11. * Instances of OpenLayers.Layer.Image are used to display data from a web
  12. * accessible image as a map layer. Create a new image layer with the
  13. * <OpenLayers.Layer.Image> constructor. Inherits from <OpenLayers.Layer>.
  14. */
  15. OpenLayers.Layer.Image = OpenLayers.Class(OpenLayers.Layer, {
  16. /**
  17. * Property: isBaseLayer
  18. * {Boolean} The layer is a base layer. Default is true. Set this property
  19. * in the layer options
  20. */
  21. isBaseLayer: true,
  22. /**
  23. * Property: url
  24. * {String} URL of the image to use
  25. */
  26. url: null,
  27. /**
  28. * Property: extent
  29. * {<OpenLayers.Bounds>} The image bounds in map units. This extent will
  30. * also be used as the default maxExtent for the layer. If you wish
  31. * to have a maxExtent that is different than the image extent, set the
  32. * maxExtent property of the options argument (as with any other layer).
  33. */
  34. extent: null,
  35. /**
  36. * Property: size
  37. * {<OpenLayers.Size>} The image size in pixels
  38. */
  39. size: null,
  40. /**
  41. * Property: tile
  42. * {<OpenLayers.Tile.Image>}
  43. */
  44. tile: null,
  45. /**
  46. * Property: aspectRatio
  47. * {Float} The ratio of height/width represented by a single pixel in the
  48. * graphic
  49. */
  50. aspectRatio: null,
  51. /**
  52. * Constructor: OpenLayers.Layer.Image
  53. * Create a new image layer
  54. *
  55. * Parameters:
  56. * name - {String} A name for the layer.
  57. * url - {String} Relative or absolute path to the image
  58. * extent - {<OpenLayers.Bounds>} The extent represented by the image
  59. * size - {<OpenLayers.Size>} The size (in pixels) of the image
  60. * options - {Object} Hashtable of extra options to tag onto the layer
  61. */
  62. initialize: function(name, url, extent, size, options) {
  63. this.url = url;
  64. this.extent = extent;
  65. this.maxExtent = extent;
  66. this.size = size;
  67. OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);
  68. this.aspectRatio = (this.extent.getHeight() / this.size.h) /
  69. (this.extent.getWidth() / this.size.w);
  70. },
  71. /**
  72. * Method: destroy
  73. * Destroy this layer
  74. */
  75. destroy: function() {
  76. if (this.tile) {
  77. this.removeTileMonitoringHooks(this.tile);
  78. this.tile.destroy();
  79. this.tile = null;
  80. }
  81. OpenLayers.Layer.prototype.destroy.apply(this, arguments);
  82. },
  83. /**
  84. * Method: clone
  85. * Create a clone of this layer
  86. *
  87. * Paramters:
  88. * obj - {Object} An optional layer (is this ever used?)
  89. *
  90. * Returns:
  91. * {<OpenLayers.Layer.Image>} An exact copy of this layer
  92. */
  93. clone: function(obj) {
  94. if(obj == null) {
  95. obj = new OpenLayers.Layer.Image(this.name,
  96. this.url,
  97. this.extent,
  98. this.size,
  99. this.getOptions());
  100. }
  101. //get all additions from superclasses
  102. obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
  103. // copy/set any non-init, non-simple values here
  104. return obj;
  105. },
  106. /**
  107. * APIMethod: setMap
  108. *
  109. * Parameters:
  110. * map - {<OpenLayers.Map>}
  111. */
  112. setMap: function(map) {
  113. /**
  114. * If nothing to do with resolutions has been set, assume a single
  115. * resolution determined by ratio*extent/size - if an image has a
  116. * pixel aspect ratio different than one (as calculated above), the
  117. * image will be stretched in one dimension only.
  118. */
  119. if( this.options.maxResolution == null ) {
  120. this.options.maxResolution = this.aspectRatio *
  121. this.extent.getWidth() /
  122. this.size.w;
  123. }
  124. OpenLayers.Layer.prototype.setMap.apply(this, arguments);
  125. },
  126. /**
  127. * Method: moveTo
  128. * Create the tile for the image or resize it for the new resolution
  129. *
  130. * Parameters:
  131. * bounds - {<OpenLayers.Bounds>}
  132. * zoomChanged - {Boolean}
  133. * dragging - {Boolean}
  134. */
  135. moveTo:function(bounds, zoomChanged, dragging) {
  136. OpenLayers.Layer.prototype.moveTo.apply(this, arguments);
  137. var firstRendering = (this.tile == null);
  138. if(zoomChanged || firstRendering) {
  139. //determine new tile size
  140. this.setTileSize();
  141. //determine new position (upper left corner of new bounds)
  142. var ul = new OpenLayers.LonLat(this.extent.left, this.extent.top);
  143. var ulPx = this.map.getLayerPxFromLonLat(ul);
  144. if(firstRendering) {
  145. //create the new tile
  146. this.tile = new OpenLayers.Tile.Image(this, ulPx, this.extent,
  147. null, this.tileSize);
  148. this.addTileMonitoringHooks(this.tile);
  149. } else {
  150. //just resize the tile and set it's new position
  151. this.tile.size = this.tileSize.clone();
  152. this.tile.position = ulPx.clone();
  153. }
  154. this.tile.draw();
  155. }
  156. },
  157. /**
  158. * Set the tile size based on the map size.
  159. */
  160. setTileSize: function() {
  161. var tileWidth = this.extent.getWidth() / this.map.getResolution();
  162. var tileHeight = this.extent.getHeight() / this.map.getResolution();
  163. this.tileSize = new OpenLayers.Size(tileWidth, tileHeight);
  164. },
  165. /**
  166. * Method: addTileMonitoringHooks
  167. * This function takes a tile as input and adds the appropriate hooks to
  168. * the tile so that the layer can keep track of the loading tiles.
  169. *
  170. * Parameters:
  171. * tile - {<OpenLayers.Tile>}
  172. */
  173. addTileMonitoringHooks: function(tile) {
  174. tile.onLoadStart = function() {
  175. this.events.triggerEvent("loadstart");
  176. };
  177. tile.events.register("loadstart", this, tile.onLoadStart);
  178. tile.onLoadEnd = function() {
  179. this.events.triggerEvent("loadend");
  180. };
  181. tile.events.register("loadend", this, tile.onLoadEnd);
  182. tile.events.register("unload", this, tile.onLoadEnd);
  183. },
  184. /**
  185. * Method: removeTileMonitoringHooks
  186. * This function takes a tile as input and removes the tile hooks
  187. * that were added in <addTileMonitoringHooks>.
  188. *
  189. * Parameters:
  190. * tile - {<OpenLayers.Tile>}
  191. */
  192. removeTileMonitoringHooks: function(tile) {
  193. tile.unload();
  194. tile.events.un({
  195. "loadstart": tile.onLoadStart,
  196. "loadend": tile.onLoadEnd,
  197. "unload": tile.onLoadEnd,
  198. scope: this
  199. });
  200. },
  201. /**
  202. * APIMethod: setUrl
  203. *
  204. * Parameters:
  205. * newUrl - {String}
  206. */
  207. setUrl: function(newUrl) {
  208. this.url = newUrl;
  209. this.tile.draw();
  210. },
  211. /**
  212. * APIMethod: getURL
  213. * The url we return is always the same (the image itself never changes)
  214. * so we can ignore the bounds parameter (it will always be the same,
  215. * anyways)
  216. *
  217. * Parameters:
  218. * bounds - {<OpenLayers.Bounds>}
  219. */
  220. getURL: function(bounds) {
  221. return this.url;
  222. },
  223. CLASS_NAME: "OpenLayers.Layer.Image"
  224. });