Tile.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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/BaseTypes/Class.js
  7. * @requires OpenLayers/Util.js
  8. * @requires OpenLayers/Console.js
  9. * @requires OpenLayers/Lang.js
  10. */
  11. /*
  12. * Class: OpenLayers.Tile
  13. * This is a class designed to designate a single tile, however
  14. * it is explicitly designed to do relatively little. Tiles store
  15. * information about themselves -- such as the URL that they are related
  16. * to, and their size - but do not add themselves to the layer div
  17. * automatically, for example. Create a new tile with the
  18. * <OpenLayers.Tile> constructor, or a subclass.
  19. *
  20. * TBD 3.0 - remove reference to url in above paragraph
  21. *
  22. */
  23. OpenLayers.Tile = OpenLayers.Class({
  24. /**
  25. * Constant: EVENT_TYPES
  26. * {Array(String)} Supported application event types
  27. */
  28. EVENT_TYPES: [ "loadstart", "loadend", "reload", "unload"],
  29. /**
  30. * APIProperty: events
  31. * {<OpenLayers.Events>} An events object that handles all
  32. * events on the tile.
  33. */
  34. events: null,
  35. /**
  36. * Property: id
  37. * {String} null
  38. */
  39. id: null,
  40. /**
  41. * Property: layer
  42. * {<OpenLayers.Layer>} layer the tile is attached to
  43. */
  44. layer: null,
  45. /**
  46. * Property: url
  47. * {String} url of the request.
  48. *
  49. * TBD 3.0
  50. * Deprecated. The base tile class does not need an url. This should be
  51. * handled in subclasses. Does not belong here.
  52. */
  53. url: null,
  54. /**
  55. * APIProperty: bounds
  56. * {<OpenLayers.Bounds>} null
  57. */
  58. bounds: null,
  59. /**
  60. * Property: size
  61. * {<OpenLayers.Size>} null
  62. */
  63. size: null,
  64. /**
  65. * Property: position
  66. * {<OpenLayers.Pixel>} Top Left pixel of the tile
  67. */
  68. position: null,
  69. /**
  70. * Property: isLoading
  71. * {Boolean} Is the tile loading?
  72. */
  73. isLoading: false,
  74. /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
  75. * there is no need for the base tile class to have a url.
  76. *
  77. * Constructor: OpenLayers.Tile
  78. * Constructor for a new <OpenLayers.Tile> instance.
  79. *
  80. * Parameters:
  81. * layer - {<OpenLayers.Layer>} layer that the tile will go in.
  82. * position - {<OpenLayers.Pixel>}
  83. * bounds - {<OpenLayers.Bounds>}
  84. * url - {<String>}
  85. * size - {<OpenLayers.Size>}
  86. * options - {Object}
  87. */
  88. initialize: function(layer, position, bounds, url, size, options) {
  89. this.layer = layer;
  90. this.position = position.clone();
  91. this.bounds = bounds.clone();
  92. this.url = url;
  93. if (size) {
  94. this.size = size.clone();
  95. }
  96. //give the tile a unique id based on its BBOX.
  97. this.id = OpenLayers.Util.createUniqueID("Tile_");
  98. this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
  99. OpenLayers.Util.extend(this, options);
  100. },
  101. /**
  102. * Method: unload
  103. * Call immediately before destroying if you are listening to tile
  104. * events, so that counters are properly handled if tile is still
  105. * loading at destroy-time. Will only fire an event if the tile is
  106. * still loading.
  107. */
  108. unload: function() {
  109. if (this.isLoading) {
  110. this.isLoading = false;
  111. this.events.triggerEvent("unload");
  112. }
  113. },
  114. /**
  115. * APIMethod: destroy
  116. * Nullify references to prevent circular references and memory leaks.
  117. */
  118. destroy:function() {
  119. this.layer = null;
  120. this.bounds = null;
  121. this.size = null;
  122. this.position = null;
  123. this.events.destroy();
  124. this.events = null;
  125. },
  126. /**
  127. * Method: clone
  128. *
  129. * Parameters:
  130. * obj - {<OpenLayers.Tile>} The tile to be cloned
  131. *
  132. * Returns:
  133. * {<OpenLayers.Tile>} An exact clone of this <OpenLayers.Tile>
  134. */
  135. clone: function (obj) {
  136. if (obj == null) {
  137. obj = new OpenLayers.Tile(this.layer,
  138. this.position,
  139. this.bounds,
  140. this.url,
  141. this.size);
  142. }
  143. // catch any randomly tagged-on properties
  144. OpenLayers.Util.applyDefaults(obj, this);
  145. return obj;
  146. },
  147. /**
  148. * Method: draw
  149. * Clear whatever is currently in the tile, then return whether or not
  150. * it should actually be re-drawn.
  151. *
  152. * Returns:
  153. * {Boolean} Whether or not the tile should actually be drawn. Note that
  154. * this is not really the best way of doing things, but such is
  155. * the way the code has been developed. Subclasses call this and
  156. * depend on the return to know if they should draw or not.
  157. */
  158. draw: function() {
  159. var maxExtent = this.layer.maxExtent;
  160. var withinMaxExtent = (maxExtent &&
  161. this.bounds.intersectsBounds(maxExtent, false));
  162. // The only case where we *wouldn't* want to draw the tile is if the
  163. // tile is outside its layer's maxExtent.
  164. this.shouldDraw = (withinMaxExtent || this.layer.displayOutsideMaxExtent);
  165. //clear tile's contents and mark as not drawn
  166. this.clear();
  167. return this.shouldDraw;
  168. },
  169. /**
  170. * Method: moveTo
  171. * Reposition the tile.
  172. *
  173. * Parameters:
  174. * bounds - {<OpenLayers.Bounds>}
  175. * position - {<OpenLayers.Pixel>}
  176. * redraw - {Boolean} Call draw method on tile after moving.
  177. * Default is true
  178. */
  179. moveTo: function (bounds, position, redraw) {
  180. if (redraw == null) {
  181. redraw = true;
  182. }
  183. this.bounds = bounds.clone();
  184. this.position = position.clone();
  185. if (redraw) {
  186. this.draw();
  187. }
  188. },
  189. /**
  190. * Method: clear
  191. * Clear the tile of any bounds/position-related data so that it can
  192. * be reused in a new location. To be implemented by subclasses.
  193. */
  194. clear: function() {
  195. // to be implemented by subclasses
  196. },
  197. /**
  198. * Method: getBoundsFromBaseLayer
  199. * Take the pixel locations of the corner of the tile, and pass them to
  200. * the base layer and ask for the location of those pixels, so that
  201. * displaying tiles over Google works fine.
  202. *
  203. * Parameters:
  204. * position - {<OpenLayers.Pixel>}
  205. *
  206. * Returns:
  207. * bounds - {<OpenLayers.Bounds>}
  208. */
  209. getBoundsFromBaseLayer: function(position) {
  210. var msg = OpenLayers.i18n('reprojectDeprecated',
  211. {'layerName':this.layer.name});
  212. OpenLayers.Console.warn(msg);
  213. var topLeft = this.layer.map.getLonLatFromLayerPx(position);
  214. var bottomRightPx = position.clone();
  215. bottomRightPx.x += this.size.w;
  216. bottomRightPx.y += this.size.h;
  217. var bottomRight = this.layer.map.getLonLatFromLayerPx(bottomRightPx);
  218. // Handle the case where the base layer wraps around the date line.
  219. // Google does this, and it breaks WMS servers to request bounds in
  220. // that fashion.
  221. if (topLeft.lon > bottomRight.lon) {
  222. if (topLeft.lon < 0) {
  223. topLeft.lon = -180 - (topLeft.lon+180);
  224. } else {
  225. bottomRight.lon = 180+bottomRight.lon+180;
  226. }
  227. }
  228. var bounds = new OpenLayers.Bounds(topLeft.lon,
  229. bottomRight.lat,
  230. bottomRight.lon,
  231. topLeft.lat);
  232. return bounds;
  233. },
  234. /**
  235. * Method: showTile
  236. * Show the tile only if it should be drawn.
  237. */
  238. showTile: function() {
  239. if (this.shouldDraw) {
  240. this.show();
  241. }
  242. },
  243. /**
  244. * Method: show
  245. * Show the tile. To be implemented by subclasses.
  246. */
  247. show: function() { },
  248. /**
  249. * Method: hide
  250. * Hide the tile. To be implemented by subclasses.
  251. */
  252. hide: function() { },
  253. CLASS_NAME: "OpenLayers.Tile"
  254. });