Image.js 7.6 KB

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