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