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