Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/OpenLayers/lib/OpenLayers/Layer/Grid.js @ 76

Revision 76, 24.9 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
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/Layer/HTTPRequest.js
9 * @requires OpenLayers/Console.js
10 */
11
12/**
13 * Class: OpenLayers.Layer.Grid
14 * Base class for layers that use a lattice of tiles.  Create a new grid
15 * layer with the <OpenLayers.Layer.Grid> constructor.
16 *
17 * Inherits from:
18 *  - <OpenLayers.Layer.HTTPRequest>
19 */
20OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
21   
22    /**
23     * APIProperty: tileSize
24     * {<OpenLayers.Size>}
25     */
26    tileSize: null,
27   
28    /**
29     * Property: grid
30     * {Array(Array(<OpenLayers.Tile>))} This is an array of rows, each row is
31     *     an array of tiles.
32     */
33    grid: null,
34
35    /**
36     * APIProperty: singleTile
37     * {Boolean} Moves the layer into single-tile mode, meaning that one tile
38     *     will be loaded. The tile's size will be determined by the 'ratio'
39     *     property. When the tile is dragged such that it does not cover the
40     *     entire viewport, it is reloaded.
41     */
42    singleTile: false,
43
44    /** APIProperty: ratio
45     *  {Float} Used only when in single-tile mode, this specifies the
46     *          ratio of the size of the single tile to the size of the map.
47     */
48    ratio: 1.5,
49
50    /**
51     * APIProperty: buffer
52     * {Integer} Used only when in gridded mode, this specifies the number of
53     *           extra rows and colums of tiles on each side which will
54     *           surround the minimum grid tiles to cover the map.
55     */
56    buffer: 2,
57
58    /**
59     * APIProperty: numLoadingTiles
60     * {Integer} How many tiles are still loading?
61     */
62    numLoadingTiles: 0,
63
64    /**
65     * Constructor: OpenLayers.Layer.Grid
66     * Create a new grid layer
67     *
68     * Parameters:
69     * name - {String}
70     * url - {String}
71     * params - {Object}
72     * options - {Object} Hashtable of extra options to tag onto the layer
73     */
74    initialize: function(name, url, params, options) {
75        OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this, 
76                                                                arguments);
77       
78        //grid layers will trigger 'tileloaded' when each new tile is
79        // loaded, as a means of progress update to listeners.
80        // listeners can access 'numLoadingTiles' if they wish to keep track
81        // of the loading progress
82        //
83        this.events.addEventType("tileloaded");
84
85        this.grid = [];
86    },
87
88    /**
89     * APIMethod: destroy
90     * Deconstruct the layer and clear the grid.
91     */
92    destroy: function() {
93        this.clearGrid();
94        this.grid = null;
95        this.tileSize = null;
96        OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments); 
97    },
98
99    /**
100     * Method: clearGrid
101     * Go through and remove all tiles from the grid, calling
102     *    destroy() on each of them to kill circular references
103     */
104    clearGrid:function() {
105        if (this.grid) {
106            for(var iRow=0, len=this.grid.length; iRow<len; iRow++) {
107                var row = this.grid[iRow];
108                for(var iCol=0, clen=row.length; iCol<clen; iCol++) {
109                    var tile = row[iCol];
110                    this.removeTileMonitoringHooks(tile);
111                    tile.destroy();
112                }
113            }
114            this.grid = [];
115        }
116    },
117
118    /**
119     * APIMethod: clone
120     * Create a clone of this layer
121     *
122     * Parameters:
123     * obj - {Object} Is this ever used?
124     *
125     * Returns:
126     * {<OpenLayers.Layer.Grid>} An exact clone of this OpenLayers.Layer.Grid
127     */
128    clone: function (obj) {
129       
130        if (obj == null) {
131            obj = new OpenLayers.Layer.Grid(this.name,
132                                            this.url,
133                                            this.params,
134                                            this.getOptions());
135        }
136
137        //get all additions from superclasses
138        obj = OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this, [obj]);
139
140        // copy/set any non-init, non-simple values here
141        if (this.tileSize != null) {
142            obj.tileSize = this.tileSize.clone();
143        }
144       
145        // we do not want to copy reference to grid, so we make a new array
146        obj.grid = [];
147
148        return obj;
149    },   
150
151    /**
152     * Method: moveTo
153     * This function is called whenever the map is moved. All the moving
154     * of actual 'tiles' is done by the map, but moveTo's role is to accept
155     * a bounds and make sure the data that that bounds requires is pre-loaded.
156     *
157     * Parameters:
158     * bounds - {<OpenLayers.Bounds>}
159     * zoomChanged - {Boolean}
160     * dragging - {Boolean}
161     */
162    moveTo:function(bounds, zoomChanged, dragging) {
163        OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this, arguments);
164       
165        bounds = bounds || this.map.getExtent();
166
167        if (bounds != null) {
168             
169            // if grid is empty or zoom has changed, we *must* re-tile
170            var forceReTile = !this.grid.length || zoomChanged;
171
172            // total bounds of the tiles
173            var tilesBounds = this.getTilesBounds();           
174     
175            if (this.singleTile) {
176               
177                // We want to redraw whenever even the slightest part of the
178                //  current bounds is not contained by our tile.
179                //  (thus, we do not specify partial -- its default is false)
180                if ( forceReTile || 
181                     (!dragging && !tilesBounds.containsBounds(bounds))) {
182                    this.initSingleTile(bounds);
183                }
184            } else {
185             
186                // if the bounds have changed such that they are not even
187                //  *partially* contained by our tiles (IE user has
188                //  programmatically panned to the other side of the earth)
189                //  then we want to reTile (thus, partial true). 
190                //
191                if (forceReTile || !tilesBounds.containsBounds(bounds, true)) {
192                    this.initGriddedTiles(bounds);
193                } else {
194                    //we might have to shift our buffer tiles
195                    this.moveGriddedTiles(bounds);
196                }
197            }
198        }
199    },
200   
201    /**
202     * APIMethod: setTileSize
203     * Check if we are in singleTile mode and if so, set the size as a ratio
204     *     of the map size (as specified by the layer's 'ratio' property).
205     *
206     * Parameters:
207     * size - {<OpenLayers.Size>}
208     */
209    setTileSize: function(size) { 
210        if (this.singleTile) {
211            size = this.map.getSize();
212            size.h = parseInt(size.h * this.ratio);
213            size.w = parseInt(size.w * this.ratio);
214        } 
215        OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this, [size]);
216    },
217       
218    /**
219     * Method: getGridBounds
220     * Deprecated. This function will be removed in 3.0. Please use
221     *     getTilesBounds() instead.
222     *
223     * Returns:
224     * {<OpenLayers.Bounds>} A Bounds object representing the bounds of all the
225     * currently loaded tiles (including those partially or not at all seen
226     * onscreen)
227     */
228    getGridBounds: function() {
229        var msg = "The getGridBounds() function is deprecated. It will be " +
230                  "removed in 3.0. Please use getTilesBounds() instead.";
231        OpenLayers.Console.warn(msg);
232        return this.getTilesBounds();
233    },
234
235    /**
236     * APIMethod: getTilesBounds
237     * Return the bounds of the tile grid.
238     *
239     * Returns:
240     * {<OpenLayers.Bounds>} A Bounds object representing the bounds of all the
241     *     currently loaded tiles (including those partially or not at all seen
242     *     onscreen).
243     */
244    getTilesBounds: function() {   
245        var bounds = null; 
246       
247        if (this.grid.length) {
248            var bottom = this.grid.length - 1;
249            var bottomLeftTile = this.grid[bottom][0];
250   
251            var right = this.grid[0].length - 1; 
252            var topRightTile = this.grid[0][right];
253   
254            bounds = new OpenLayers.Bounds(bottomLeftTile.bounds.left, 
255                                           bottomLeftTile.bounds.bottom,
256                                           topRightTile.bounds.right, 
257                                           topRightTile.bounds.top);
258           
259        }   
260        return bounds;
261    },
262
263    /**
264     * Method: initSingleTile
265     *
266     * Parameters:
267     * bounds - {<OpenLayers.Bounds>}
268     */
269    initSingleTile: function(bounds) {
270
271        //determine new tile bounds
272        var center = bounds.getCenterLonLat();
273        var tileWidth = bounds.getWidth() * this.ratio;
274        var tileHeight = bounds.getHeight() * this.ratio;
275                                       
276        var tileBounds = 
277            new OpenLayers.Bounds(center.lon - (tileWidth/2),
278                                  center.lat - (tileHeight/2),
279                                  center.lon + (tileWidth/2),
280                                  center.lat + (tileHeight/2));
281 
282        var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top);
283        var px = this.map.getLayerPxFromLonLat(ul);
284
285        if (!this.grid.length) {
286            this.grid[0] = [];
287        }
288
289        var tile = this.grid[0][0];
290        if (!tile) {
291            tile = this.addTile(tileBounds, px);
292           
293            this.addTileMonitoringHooks(tile);
294            tile.draw();
295            this.grid[0][0] = tile;
296        } else {
297            tile.moveTo(tileBounds, px);
298        }           
299       
300        //remove all but our single tile
301        this.removeExcessTiles(1,1);
302    },
303
304    /**
305     * Method: calculateGridLayout
306     * Generate parameters for the grid layout. This 
307     *
308     * Parameters:
309     * bounds - {<OpenLayers.Bound>}
310     * extent - {<OpenLayers.Bounds>}
311     * resolution - {Number}
312     *
313     * Returns:
314     * Object containing properties tilelon, tilelat, tileoffsetlat,
315     * tileoffsetlat, tileoffsetx, tileoffsety
316     */
317    calculateGridLayout: function(bounds, extent, resolution) {
318        var tilelon = resolution * this.tileSize.w;
319        var tilelat = resolution * this.tileSize.h;
320       
321        var offsetlon = bounds.left - extent.left;
322        var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
323        var tilecolremain = offsetlon/tilelon - tilecol;
324        var tileoffsetx = -tilecolremain * this.tileSize.w;
325        var tileoffsetlon = extent.left + tilecol * tilelon;
326       
327        var offsetlat = bounds.top - (extent.bottom + tilelat); 
328        var tilerow = Math.ceil(offsetlat/tilelat) + this.buffer;
329        var tilerowremain = tilerow - offsetlat/tilelat;
330        var tileoffsety = -tilerowremain * this.tileSize.h;
331        var tileoffsetlat = extent.bottom + tilerow * tilelat;
332       
333        return { 
334          tilelon: tilelon, tilelat: tilelat,
335          tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
336          tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
337        };
338
339    },
340
341    /**
342     * Method: initGriddedTiles
343     *
344     * Parameters:
345     * bounds - {<OpenLayers.Bounds>}
346     */
347    initGriddedTiles:function(bounds) {
348       
349        // work out mininum number of rows and columns; this is the number of
350        // tiles required to cover the viewport plus at least one for panning
351
352        var viewSize = this.map.getSize();
353        var minRows = Math.ceil(viewSize.h/this.tileSize.h) + 
354                      Math.max(1, 2 * this.buffer);
355        var minCols = Math.ceil(viewSize.w/this.tileSize.w) +
356                      Math.max(1, 2 * this.buffer);
357       
358        var extent = this.getMaxExtent();
359        var resolution = this.map.getResolution();
360       
361        var tileLayout = this.calculateGridLayout(bounds, extent, resolution);
362
363        var tileoffsetx = Math.round(tileLayout.tileoffsetx); // heaven help us
364        var tileoffsety = Math.round(tileLayout.tileoffsety);
365
366        var tileoffsetlon = tileLayout.tileoffsetlon;
367        var tileoffsetlat = tileLayout.tileoffsetlat;
368       
369        var tilelon = tileLayout.tilelon;
370        var tilelat = tileLayout.tilelat;
371
372        this.origin = new OpenLayers.Pixel(tileoffsetx, tileoffsety);
373
374        var startX = tileoffsetx; 
375        var startLon = tileoffsetlon;
376
377        var rowidx = 0;
378       
379        var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
380        var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
381       
382   
383        do {
384            var row = this.grid[rowidx++];
385            if (!row) {
386                row = [];
387                this.grid.push(row);
388            }
389
390            tileoffsetlon = startLon;
391            tileoffsetx = startX;
392            var colidx = 0;
393 
394            do {
395                var tileBounds = 
396                    new OpenLayers.Bounds(tileoffsetlon, 
397                                          tileoffsetlat, 
398                                          tileoffsetlon + tilelon,
399                                          tileoffsetlat + tilelat);
400
401                var x = tileoffsetx;
402                x -= layerContainerDivLeft;
403
404                var y = tileoffsety;
405                y -= layerContainerDivTop;
406
407                var px = new OpenLayers.Pixel(x, y);
408                var tile = row[colidx++];
409                if (!tile) {
410                    tile = this.addTile(tileBounds, px);
411                    this.addTileMonitoringHooks(tile);
412                    row.push(tile);
413                } else {
414                    tile.moveTo(tileBounds, px, false);
415                }
416     
417                tileoffsetlon += tilelon;       
418                tileoffsetx += this.tileSize.w;
419            } while ((tileoffsetlon <= bounds.right + tilelon * this.buffer)
420                     || colidx < minCols);
421             
422            tileoffsetlat -= tilelat;
423            tileoffsety += this.tileSize.h;
424        } while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
425                || rowidx < minRows);
426       
427        //shave off exceess rows and colums
428        this.removeExcessTiles(rowidx, colidx);
429
430        //now actually draw the tiles
431        this.spiralTileLoad();
432    },
433
434    /**
435     * Method: getMaxExtent
436     * Get this layer's maximum extent. (Implemented as a getter for
437     *     potential specific implementations in sub-classes.)
438     *
439     * Returns:
440     * {OpenLayers.Bounds}
441     */
442    getMaxExtent: function() {
443        return this.maxExtent;
444    },
445   
446    /**
447     * Method: spiralTileLoad
448     *   Starts at the top right corner of the grid and proceeds in a spiral
449     *    towards the center, adding tiles one at a time to the beginning of a
450     *    queue.
451     *
452     *   Once all the grid's tiles have been added to the queue, we go back
453     *    and iterate through the queue (thus reversing the spiral order from
454     *    outside-in to inside-out), calling draw() on each tile.
455     */
456    spiralTileLoad: function() {
457        var tileQueue = [];
458 
459        var directions = ["right", "down", "left", "up"];
460
461        var iRow = 0;
462        var iCell = -1;
463        var direction = OpenLayers.Util.indexOf(directions, "right");
464        var directionsTried = 0;
465       
466        while( directionsTried < directions.length) {
467
468            var testRow = iRow;
469            var testCell = iCell;
470
471            switch (directions[direction]) {
472                case "right":
473                    testCell++;
474                    break;
475                case "down":
476                    testRow++;
477                    break;
478                case "left":
479                    testCell--;
480                    break;
481                case "up":
482                    testRow--;
483                    break;
484            } 
485   
486            // if the test grid coordinates are within the bounds of the
487            //  grid, get a reference to the tile.
488            var tile = null;
489            if ((testRow < this.grid.length) && (testRow >= 0) &&
490                (testCell < this.grid[0].length) && (testCell >= 0)) {
491                tile = this.grid[testRow][testCell];
492            }
493           
494            if ((tile != null) && (!tile.queued)) {
495                //add tile to beginning of queue, mark it as queued.
496                tileQueue.unshift(tile);
497                tile.queued = true;
498               
499                //restart the directions counter and take on the new coords
500                directionsTried = 0;
501                iRow = testRow;
502                iCell = testCell;
503            } else {
504                //need to try to load a tile in a different direction
505                direction = (direction + 1) % 4;
506                directionsTried++;
507            }
508        } 
509       
510        // now we go through and draw the tiles in forward order
511        for(var i=0, len=tileQueue.length; i<len; i++) {
512            var tile = tileQueue[i];
513            tile.draw();
514            //mark tile as unqueued for the next time (since tiles are reused)
515            tile.queued = false;       
516        }
517    },
518
519    /**
520     * APIMethod: addTile
521     * Gives subclasses of Grid the opportunity to create an
522     * OpenLayer.Tile of their choosing. The implementer should initialize
523     * the new tile and take whatever steps necessary to display it.
524     *
525     * Parameters
526     * bounds - {<OpenLayers.Bounds>}
527     * position - {<OpenLayers.Pixel>}
528     *
529     * Returns:
530     * {<OpenLayers.Tile>} The added OpenLayers.Tile
531     */
532    addTile:function(bounds, position) {
533        // Should be implemented by subclasses
534    },
535   
536    /**
537     * Method: addTileMonitoringHooks
538     * This function takes a tile as input and adds the appropriate hooks to
539     *     the tile so that the layer can keep track of the loading tiles.
540     *
541     * Parameters:
542     * tile - {<OpenLayers.Tile>}
543     */
544    addTileMonitoringHooks: function(tile) {
545       
546        tile.onLoadStart = function() {
547            //if that was first tile then trigger a 'loadstart' on the layer
548            if (this.numLoadingTiles == 0) {
549                this.events.triggerEvent("loadstart");
550            }
551            this.numLoadingTiles++;
552        };
553        tile.events.register("loadstart", this, tile.onLoadStart);
554     
555        tile.onLoadEnd = function() {
556            this.numLoadingTiles--;
557            this.events.triggerEvent("tileloaded");
558            //if that was the last tile, then trigger a 'loadend' on the layer
559            if (this.numLoadingTiles == 0) {
560                this.events.triggerEvent("loadend");
561            }
562        };
563        tile.events.register("loadend", this, tile.onLoadEnd);
564        tile.events.register("unload", this, tile.onLoadEnd);
565    },
566
567    /**
568     * Method: removeTileMonitoringHooks
569     * This function takes a tile as input and removes the tile hooks
570     *     that were added in addTileMonitoringHooks()
571     *
572     * Parameters:
573     * tile - {<OpenLayers.Tile>}
574     */
575    removeTileMonitoringHooks: function(tile) {
576        tile.unload();
577        tile.events.un({
578            "loadstart": tile.onLoadStart,
579            "loadend": tile.onLoadEnd,
580            "unload": tile.onLoadEnd,
581            scope: this
582        });
583    },
584   
585    /**
586     * Method: moveGriddedTiles
587     *
588     * Parameters:
589     * bounds - {<OpenLayers.Bounds>}
590     */
591    moveGriddedTiles: function(bounds) {
592        var buffer = this.buffer || 1;
593        while (true) {
594            var tlLayer = this.grid[0][0].position;
595            var tlViewPort = 
596                this.map.getViewPortPxFromLayerPx(tlLayer);
597            if (tlViewPort.x > -this.tileSize.w * (buffer - 1)) {
598                this.shiftColumn(true);
599            } else if (tlViewPort.x < -this.tileSize.w * buffer) {
600                this.shiftColumn(false);
601            } else if (tlViewPort.y > -this.tileSize.h * (buffer - 1)) {
602                this.shiftRow(true);
603            } else if (tlViewPort.y < -this.tileSize.h * buffer) {
604                this.shiftRow(false);
605            } else {
606                break;
607            }
608        };
609    },
610
611    /**
612     * Method: shiftRow
613     * Shifty grid work
614     *
615     * Parameters:
616     * prepend - {Boolean} if true, prepend to beginning.
617     *                          if false, then append to end
618     */
619    shiftRow:function(prepend) {
620        var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1);
621        var grid = this.grid;
622        var modelRow = grid[modelRowIndex];
623
624        var resolution = this.map.getResolution();
625        var deltaY = (prepend) ? -this.tileSize.h : this.tileSize.h;
626        var deltaLat = resolution * -deltaY;
627
628        var row = (prepend) ? grid.pop() : grid.shift();
629
630        for (var i=0, len=modelRow.length; i<len; i++) {
631            var modelTile = modelRow[i];
632            var bounds = modelTile.bounds.clone();
633            var position = modelTile.position.clone();
634            bounds.bottom = bounds.bottom + deltaLat;
635            bounds.top = bounds.top + deltaLat;
636            position.y = position.y + deltaY;
637            row[i].moveTo(bounds, position);
638        }
639
640        if (prepend) {
641            grid.unshift(row);
642        } else {
643            grid.push(row);
644        }
645    },
646
647    /**
648     * Method: shiftColumn
649     * Shift grid work in the other dimension
650     *
651     * Parameters:
652     * prepend - {Boolean} if true, prepend to beginning.
653     *                          if false, then append to end
654     */
655    shiftColumn: function(prepend) {
656        var deltaX = (prepend) ? -this.tileSize.w : this.tileSize.w;
657        var resolution = this.map.getResolution();
658        var deltaLon = resolution * deltaX;
659
660        for (var i=0, len=this.grid.length; i<len; i++) {
661            var row = this.grid[i];
662            var modelTileIndex = (prepend) ? 0 : (row.length - 1);
663            var modelTile = row[modelTileIndex];
664           
665            var bounds = modelTile.bounds.clone();
666            var position = modelTile.position.clone();
667            bounds.left = bounds.left + deltaLon;
668            bounds.right = bounds.right + deltaLon;
669            position.x = position.x + deltaX;
670
671            var tile = prepend ? this.grid[i].pop() : this.grid[i].shift();
672            tile.moveTo(bounds, position);
673            if (prepend) {
674                row.unshift(tile);
675            } else {
676                row.push(tile);
677            }
678        }
679    },
680   
681    /**
682     * Method: removeExcessTiles
683     * When the size of the map or the buffer changes, we may need to
684     *     remove some excess rows and columns.
685     *
686     * Parameters:
687     * rows - {Integer} Maximum number of rows we want our grid to have.
688     * colums - {Integer} Maximum number of columns we want our grid to have.
689     */
690    removeExcessTiles: function(rows, columns) {
691       
692        // remove extra rows
693        while (this.grid.length > rows) {
694            var row = this.grid.pop();
695            for (var i=0, l=row.length; i<l; i++) {
696                var tile = row[i];
697                this.removeTileMonitoringHooks(tile);
698                tile.destroy();
699            }
700        }
701       
702        // remove extra columns
703        while (this.grid[0].length > columns) {
704            for (var i=0, l=this.grid.length; i<l; i++) {
705                var row = this.grid[i];
706                var tile = row.pop();
707                this.removeTileMonitoringHooks(tile);
708                tile.destroy();
709            }
710        }
711    },
712
713    /**
714     * Method: onMapResize
715     * For singleTile layers, this will set a new tile size according to the
716     * dimensions of the map pane.
717     */
718    onMapResize: function() {
719        if (this.singleTile) {
720            this.clearGrid();
721            this.setTileSize();
722        }
723    },
724   
725    /**
726     * APIMethod: getTileBounds
727     * Returns The tile bounds for a layer given a pixel location.
728     *
729     * Parameters:
730     * viewPortPx - {<OpenLayers.Pixel>} The location in the viewport.
731     *
732     * Returns:
733     * {<OpenLayers.Bounds>} Bounds of the tile at the given pixel location.
734     */
735    getTileBounds: function(viewPortPx) {
736        var maxExtent = this.maxExtent;
737        var resolution = this.getResolution();
738        var tileMapWidth = resolution * this.tileSize.w;
739        var tileMapHeight = resolution * this.tileSize.h;
740        var mapPoint = this.getLonLatFromViewPortPx(viewPortPx);
741        var tileLeft = maxExtent.left + (tileMapWidth *
742                                         Math.floor((mapPoint.lon -
743                                                     maxExtent.left) /
744                                                    tileMapWidth));
745        var tileBottom = maxExtent.bottom + (tileMapHeight *
746                                             Math.floor((mapPoint.lat -
747                                                         maxExtent.bottom) /
748                                                        tileMapHeight));
749        return new OpenLayers.Bounds(tileLeft, tileBottom,
750                                     tileLeft + tileMapWidth,
751                                     tileBottom + tileMapHeight);
752    },
753   
754    CLASS_NAME: "OpenLayers.Layer.Grid"
755});
Note: See TracBrowser for help on using the repository browser.