OpenLayers OpenLayers

Ticket #831: untiled.2.patch

File untiled.2.patch, 55.1 kB (added by euzuro, 1 year ago)

tim had snuck a test change into trunk before i created this patch.

  • tests/Tile/test_Image.html

    old new  
    2525        t.ok( tile.size.equals(size), "tile.size is set correctly"); 
    2626    } 
    2727    function test_02_Tile_Image_draw (t) { 
    28         t.plan( 5 ); 
     28        t.plan( 7 ); 
    2929 
    3030        var map = new OpenLayers.Map('map'); 
    3131         
     
    4040        var url = "http://www.openlayers.org/dev/tests/tileimage"; 
    4141        tile = new OpenLayers.Tile.Image(layer, position, bounds, url, size); 
    4242         
     43        tile.events.register("loadstart", this, function() {  
     44            t.ok(true, "loadstart triggered"); 
     45        }); 
     46        tile.events.register("reload", this, function() {  
     47            t.ok(true, "reload triggered"); 
     48        }); 
     49                 
     50        //this should trigger a "loadstart" event 
    4351        tile.draw(); 
     52         
    4453        var img = tile.imgDiv; 
    4554         
    4655        if (!isMozilla) 
     
    6372             "tile.draw creates an image"); 
    6473        t.eq( tile.imgDiv.style.width, "5px", "Image width is correct" ); 
    6574        t.eq( tile.imgDiv.style.height, "6px", "Image height is correct" ); 
     75 
     76        // this should trigger a "reload" event (since the image never actually 
     77        // loads in tests) 
     78        tile.draw(); 
     79         
    6680    } 
    6781    function test_03_Tile_Image_OutsideMaxExtent(t) { 
    6882        t.plan( 11 ); 
  • tests/test_Tile.html

    old new  
    55    var tile;  
    66     
    77    function test_01_Tile_constructor (t) { 
    8         t.plan( 8 ); 
     8        t.plan( 9 ); 
    99         
    1010        var layer = new Object(); // bogus layer 
    1111        var position = new OpenLayers.Pixel(10,20); 
     
    2424 
    2525        t.ok( tile.id != null, "tile is given an id"); 
    2626        t.ok( tile.id.startsWith("Tile_"), "tile's id starts correctly"); 
     27        t.ok( tile.events != null, "tile's events intitialized"); 
    2728    } 
    2829 
     30    function test_99_Tile_destroy(t) { 
     31        t.plan( 6 ); 
     32         
     33         
     34        var layer = new Object(); // bogus layer 
     35        var position = new OpenLayers.Pixel(10,20); 
     36        var bounds = new OpenLayers.Bounds(1,2,3,4); 
     37        var url = "bobob"; 
     38        var size = new OpenLayers.Size(5,6); 
     39         
     40        tile = new OpenLayers.Tile(layer, position, bounds, url, size); 
     41        tile.events.destroy = function() { 
     42            t.ok(true, "tile events destroy() called"); 
     43        } 
    2944 
     45  
     46        tile.destroy(); 
     47 
     48        t.ok(tile.layer == null, "tile.layer set to null"); 
     49        t.ok(tile.bounds == null, "tile.bounds set to null"); 
     50        t.ok(tile.size == null, "tile.size set to null"); 
     51        t.ok(tile.position == null, "tile.position set to null"); 
     52         
     53        t.ok(tile.events == null, "tile.events set to null"); 
     54    } 
     55 
     56 
    3057  // --> 
    3158  </script> 
    3259</head> 
  • tests/Layer/test_Grid.html

    old new  
    2323 
    2424 
    2525    function test_01_Layer_Grid_constructor (t) { 
    26         t.plan( 1 ); 
     26        t.plan( 5 ); 
    2727                        
    2828        layer = new OpenLayers.Layer.Grid(name, url, params, null); 
    2929        t.ok( layer instanceof OpenLayers.Layer.Grid, "returns OpenLayers.Layer.Grid object" ); 
     30        t.eq( layer.buffer, 2, "buffer default is 2"); 
     31        t.eq( layer.ratio, 1.5, "ratio default is 1.5"); 
     32        t.eq( layer.numLoadingTiles, 0, "numLoadingTiles starts at 0"); 
     33        t.ok( layer.events.listeners["tileloaded"] != null, "'tileloaded' event added to layer's event types"); 
     34         
    3035    } 
    3136 
    3237 
     
    4247    } 
    4348 
    4449    function test_03_Layer_Grid_clearTiles (t) { 
    45         t.plan(1); 
     50        t.plan(3); 
     51 
    4652        var map = new OpenLayers.Map('map'); 
    4753        layer = new OpenLayers.Layer.WMS(name, url, params); 
    4854        map.addLayer(layer); 
    4955 
    5056        map.setCenter(new OpenLayers.LonLat(0,0)); 
    5157 
     58        var numTiles = layer.grid.length * layer.grid[0].length; 
    5259 
    53         //grab a reference to one of the tiles 
    54         var tile = layer.grid[0][0];         
     60        //our count of how many times tile.destroy() is called 
     61        tilesDeleted = 0; 
     62         
     63        //this will get set to false if we try to destroy a tile that has  
     64        // not been unhookedv 
     65        allTilesUnhooked = true; 
     66         
     67        OpenLayers.Tile.Image.prototype._destroy = 
     68            OpenLayers.Tile.Image.prototype.destroy; 
    5569 
     70        OpenLayers.Tile.Image.prototype.destroy = function() { 
     71            if (!this.unhooked) { 
     72                allTilesUnhooked = false; 
     73            } 
     74            tilesDeleted++; 
     75        } 
     76 
     77        layer.removeTileMonitoringHooks = function(tile) { 
     78            tile.unhooked = true;             
     79        } 
     80 
    5681        layer.clearGrid(); 
    5782 
    5883        t.ok( layer.grid != null, "layer.grid does not get nullified" ); 
     84        t.eq(tilesDeleted, numTiles, "all tiles destroy()ed properly"); 
     85        t.ok(allTilesUnhooked, "all tiles unhooked before being destroyed"); 
     86 
     87        OpenLayers.Tile.Image.prototype.destroy = 
     88            OpenLayers.Tile.Image.prototype._destroy; 
     89         
    5990    } 
    6091 
    6192 
    62     function test_04_Layer_Grid_getGridBounds(t) { 
    63         t.plan( 1 ); 
     93    function test_04_Layer_Grid_getTilesBounds(t) { 
     94        t.plan( 3 ); 
    6495 
    6596        layer = new OpenLayers.Layer.WMS(name, url, params); 
    6697 
     98 
     99    //normal grid 
    67100        var bl = { bounds: new OpenLayers.Bounds(1,2,0,0)}; 
    68101        var tr = { bounds: new OpenLayers.Bounds(0,0,3,4)}; 
    69102        layer.grid = [ [6, tr],  
    70103                       [bl, 7]]; 
    71104 
    72         var bounds = layer.getGridBounds(); 
    73      
     105        var bounds = layer.getTilesBounds(); 
    74106        var testBounds = new OpenLayers.Bounds(1,2,3,4); 
    75107         
    76         t.ok( bounds.equals(testBounds), "getGridBounds() returns correct bounds") 
     108        t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); 
    77109 
    78         layer.grid = null; 
     110    //no tiles 
     111        layer.grid = new Array(); 
     112        bounds = layer.getTilesBounds(); 
     113         
     114        t.ok(bounds == null, "getTilesBounds() on a tile-less grid returns null"); 
     115         
     116 
     117    //singleTile 
     118        var singleTile = { bounds: new OpenLayers.Bounds(1,2,3,4)}; 
     119        layer.grid = [ [ singleTile ] ]; 
     120        bounds = layer.getTilesBounds(); 
     121         
     122        t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); 
     123         
    79124    } 
    80125 
    81126    function test_05_Layer_Grid_getResolution(t) { 
     
    108153 
    109154        t.eq( zoom, 2, "getZoomForExtent() returns correct value"); 
    110155    }    
     156     
     157    function test_07_Layer_Grid_moveTo(t) { 
    111158 
     159    t.plan(13); 
    112160 
     161        var map = new OpenLayers.Map('map'); 
     162        layer = new OpenLayers.Layer.WMS(name, url, params); 
     163        layer.destroy = function() {}; //we're going to do funky things with the grid 
     164        map.addLayer(layer); 
     165 
     166    //make sure null bounds doesnt cause script error.  
     167    // no test necessary, just action 
     168        map.getExtent = function() { return null; } 
     169        layer.singleTile = false; 
     170        layer.moveTo(); //checks to make sure null bounds doesnt break us 
     171   
     172 
     173 
     174      //observing globals 
     175        layer.initSingleTile = function(bounds) { 
     176            g_WhichFunc = "InitSingle"; 
     177            g_Bounds = bounds; 
     178        }; 
     179        layer.initGriddedTiles = function(bounds) { 
     180            g_WhichFunc = "InitGridded"; 
     181            g_Bounds = bounds; 
     182        }; 
     183        layer.moveGriddedTiles = function(bounds) { 
     184            g_WhichFunc = "MoveGridded"; 
     185            g_Bounds = bounds; 
     186        }; 
     187        var clearTestBounds = function() { 
     188            g_WhichFunc = null; 
     189            g_Bounds = null; 
     190        }; 
     191 
     192      //default map extent (tested every time below) 
     193        b = new OpenLayers.Bounds(0,0,100,100);         
     194        map.getExtent = function() { 
     195            return b; 
     196        }; 
     197        var tilesBounds = null; 
     198        layer.getTilesBounds = function() { 
     199            return tilesBounds; 
     200        } 
     201 
     202 
     203//FORCE 
     204 
     205    //empty grid 
     206        layer.grid = new Array(); 
     207       //grid 
     208        clearTestBounds(); 
     209        layer.singleTile = false; 
     210        layer.moveTo()         
     211        t.ok(g_Bounds.equals(b), "if grid is empty, initGridded called"); 
     212         
     213       //singletile 
     214        clearTestBounds(); 
     215        layer.singleTile = true; 
     216        layer.moveTo()         
     217        t.ok(g_Bounds.equals(b), "if grid is empty, initSingleTile called"); 
     218 
     219    //zoomChanged 
     220        zoomChanged = true; 
     221        layer.grid = [ [ {} ] ]; 
     222 
     223       //grid 
     224        clearTestBounds(); 
     225        layer.singleTile = false; 
     226        layer.moveTo(null, zoomChanged);         
     227        t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initGridded called"); 
     228         
     229       //singletile 
     230        clearTestBounds(); 
     231        layer.singleTile = true; 
     232        layer.moveTo(null, zoomChanged); 
     233        t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initSingleTile called"); 
     234 
     235 
     236        layer.getTilesBounds = function() { 
     237            return tilesBounds; 
     238        } 
     239         
     240         
     241 
     242//NO FORCE 
     243        zoomChanged = false; 
     244        layer.grid = [ [ {} ] ]; 
     245  
     246   //single tile 
     247        layer.singleTile = true;  
     248         
     249      //DRAGGING    
     250        var dragging = true; 
     251             
     252        //in bounds 
     253        clearTestBounds(); 
     254        tilesBounds = new OpenLayers.Bounds(-10,-10,110,110); 
     255        layer.moveTo(null, zoomChanged, dragging); 
     256        t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()"); 
     257         
     258        //out bounds 
     259        clearTestBounds(); 
     260        tilesBounds = new OpenLayers.Bounds(10,10,120,120); 
     261        layer.moveTo(null, zoomChanged, dragging); 
     262        t.ok(g_Bounds == null, "if dragging and tile out of bounds, no init()"); 
     263 
     264      //NOT DRAGGING 
     265        dragging = false; 
     266 
     267        //in bounds 
     268        clearTestBounds(); 
     269        tilesBounds = new OpenLayers.Bounds(-10,-10,110,110); 
     270        layer.moveTo(null, zoomChanged, dragging); 
     271        t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()"); 
     272         
     273        //out bounds 
     274        clearTestBounds(); 
     275        tilesBounds = new OpenLayers.Bounds(10,10,120,120); 
     276        layer.moveTo(null, zoomChanged, dragging); 
     277        t.ok(g_WhichFunc == "InitSingle", "if not dragging and tile out of bounds, we call initSingleTile()"); 
     278        t.ok(g_Bounds.equals(b), "if not dragging and tile out of bounds, we call initSingleTile() with correct bounds"); 
     279 
     280   
     281   //gridded 
     282        layer.grid = [ [ {} ] ]; 
     283        layer.singleTile = false; 
     284         
     285        // drastic pan 
     286        clearTestBounds(); 
     287        tilesBounds = new OpenLayers.Bounds(-150,-150,-120,-120); 
     288        layer.moveTo(null, zoomChanged); 
     289        t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()"); 
     290        t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds"); 
     291        
     292        //regular move  
     293        clearTestBounds(); 
     294        tilesBounds = new OpenLayers.Bounds(10,10,120,120); 
     295        layer.moveTo(null, zoomChanged); 
     296        t.ok(g_WhichFunc == "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()"); 
     297        t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds"); 
     298    } 
     299 
    113300    /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR  
    114301     *      
    115      *    -moveTo 
    116302     *    -insertColumn 
    117303     *    -insertRow 
    118      
    119     function 07_Layer_Grid_moveTo(t) { 
    120     } 
     304     *  
    121305 
    122306    function 08_Layer_Grid_insertColumn(t) { 
    123307    } 
     
    155339        layer.grid = null; 
    156340    } 
    157341 
    158     function test_11_Layer_Grid_setMap(t) { 
     342    function test_11_Layer_Grid_setTileSize(t) { 
     343        t.plan(1); 
    159344 
    160         t.plan(2); 
     345        OpenLayers.Layer.HTTPRequest.prototype._setTileSize =  
     346            OpenLayers.Layer.HTTPRequest.prototype.setTileSize; 
     347 
     348        OpenLayers.Layer.HTTPRequest.prototype.setTileSize = function(size) { 
     349            g_Size = size; 
     350        }; 
     351 
     352 
     353        layer = new OpenLayers.Layer.Grid(name, url, params, { 
     354            singleTile: true 
     355        }); 
     356        mapSize = new OpenLayers.Size(100,1000); 
     357        layer.map = { 
     358            getSize: function() { return mapSize; } 
     359        } 
    161360         
    162         var options = {tileSize: new OpenLayers.Size(500,50)}; 
    163         var map = new OpenLayers.Map('map', options); 
    164         layer = new OpenLayers.Layer.Grid(name, url, params); 
     361        g_Size = null; 
     362        layer.setTileSize(); 
     363         
     364        var idealSize = new OpenLayers.Size(150,1500); 
     365        t.ok( g_Size && g_Size.equals(idealSize), "correctly calculated tile size passed to superclass setTileSize() function"); 
     366  
     367        OpenLayers.Layer.HTTPRequest.prototype.setTileSize =  
     368            OpenLayers.Layer.HTTPRequest.prototype._setTileSize; 
     369    } 
     370     
     371    function test_12_Layer_Grid_initSingleTile(t) { 
     372      t.plan( 11 ); 
     373       
     374        layer = new OpenLayers.Layer.Grid(name, url, params, { 
     375            singleTile: true, 
     376            ratio: 2 
     377        }); 
     378         
     379        var bounds = new OpenLayers.Bounds(-10,10,50,100); 
     380         
     381        var desiredTileBounds = new OpenLayers.Bounds(-40,-35,80,145); 
     382        var desiredUL = new OpenLayers.LonLat(-40,145); 
     383         
     384        translatedPX = {}; 
     385        layer.map = { 
     386            getLayerPxFromLonLat: function(ul) { 
     387                t.ok(ul.equals(desiredUL), "correct ul passed to translation"); 
     388                return translatedPX;         
     389            } 
     390        } 
    165391 
     392        var newTile = { 
     393            draw: function() { 
     394                t.ok(true, "newly created tile has been drawn"); 
     395            } 
     396        }; 
     397        layer.addTile = function(tileBounds, px) { 
     398            t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to addTile to create new tile"); 
     399            t.ok(px == translatedPX, "correct tile px passed to addTile to create new tile"); 
     400            return newTile; 
     401        }; 
     402        layer.addTileMonitoringHooks = function(tile) { 
     403            t.ok(tile == newTile, "adding monitoring hooks to the newly added tile"); 
     404        }; 
     405        layer.removeExcessTiles = function(x,y) { 
     406            t.ok(x == 1 && y == 1, "removeExcessTiles called")   
     407        }; 
    166408 
    167         layer.setMap(map); 
     409 
     410        layer.grid = new Array(); 
     411        layer.initSingleTile(bounds);        
     412       
     413        t.ok(layer.grid[0][0] == newTile, "grid's 0,0 is set to the newly created tile");         
    168414         
    169         t.ok( layer.tileSize != null, "tileSize has been set"); 
    170         t.ok( (layer.tileSize.h == 50) && (layer.tileSize.w == 500), "tileSize has been set correctly"); 
     415        var tile = {  
     416            moveTo: function(tileBounds, px) { 
     417                t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to tile.moveTo()"); 
     418                t.ok(px == translatedPX, "correct tile px passed to tile.moveTo()"); 
     419            } 
     420        };  
     421        layer.grid = [[ tile ]]; 
     422        layer.initSingleTile(bounds);        
     423       
     424    }   
     425      
     426    function test_14_Layer_Grid_addTileMonitoringHooks(t) { 
     427        t.plan(14); 
     428         
     429        layer = new OpenLayers.Layer.Grid(); 
     430        layer.events = { 
     431            'triggerEvent': function(str) { 
     432                g_events.push(str);  
     433            } 
     434        } 
     435                 
     436        var tile = { 
     437            events: { 
     438                register: function(name, obj, func) { 
     439                    g_registered[name] = [obj, func]; 
     440                } 
     441            } 
     442        } 
     443 
     444        g_registered = {}; 
     445        g_events = new Array(); 
     446         
     447        layer.addTileMonitoringHooks(tile); 
     448         
     449    //loadstart 
     450        t.ok(tile.onLoadStart != null, "onLoadStart function created and added to tile"); 
     451        entry =  g_registered["loadstart"]; 
     452        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly registered"); 
     453 
     454        layer.numLoadingTiles = 0;  
     455        g_events = new Array(); 
     456        tile.onLoadStart.apply(layer); 
     457 
     458        t.eq(g_events[0], "loadstart", "loadstart event triggered when numLoadingTiles is 0"); 
     459        t.eq(layer.numLoadingTiles, 1, "numLoadingTiles incremented"); 
     460 
     461        g_events = new Array(); 
     462        tile.onLoadStart.apply(layer); 
     463        t.eq(g_events.length, 0, "loadstart event not triggered when numLoadingTiles is not 0"); 
     464        t.eq(layer.numLoadingTiles, 2, "numLoadingTiles incremented"); 
     465 
     466 
     467    //loadend 
     468        t.ok(tile.onLoadEnd != null, "onLoadEnd function created and added to tile"); 
     469        entry = g_registered["loadend"]; 
     470        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly registered"); 
     471         
     472        layer.numLoadingTiles = 2;  
     473        g_events = new Array(); 
     474        tile.onLoadEnd.apply(layer); 
     475        t.eq(g_events[0], "tileloaded", "tileloaded triggered when numLoadingTiles is > 0"); 
     476        t.eq(g_events.length, 1, "loadend event not triggered when numLoadingTiles is > 0"); 
     477        t.eq(layer.numLoadingTiles, 1, "numLoadingTiles decremented"); 
     478 
     479 
     480        g_events = new Array(); 
     481        tile.onLoadEnd.apply(layer); 
     482        t.eq(g_events[0], "tileloaded", "tileloaded triggered when numLoadingTiles is 0"); 
     483        t.eq(g_events[1], "loadend", "loadend event triggered when numLoadingTiles is 0"); 
     484        t.eq(layer.numLoadingTiles, 0, "numLoadingTiles decremented"); 
    171485    } 
     486     
     487    function test_15_Layer_Grid_removeTileMonitoringHooks(t) { 
     488        t.plan(2); 
     489         
     490        layer = new OpenLayers.Layer.Grid(); 
     491                 
     492        var tile = { 
     493            onLoadStart: {}, 
     494            onLoadEnd: {}, 
     495            events: { 
     496                unregister: function(name, obj, func) { 
     497                    g_unregistered[name] = [obj, func]; 
     498                } 
     499            } 
     500        } 
    172501 
     502        g_unregistered = {}; 
     503         
     504        layer.removeTileMonitoringHooks(tile); 
     505         
     506        entry =  g_unregistered["loadstart"]; 
     507        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly unregistered"); 
    173508 
     509        entry =  g_unregistered["loadend"]; 
     510        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly unregistered"); 
     511    } 
     512 
    174513    function test_99_Layer_Grid_destroy (t) { 
    175514 
    176515        t.plan( 5 ); 
  • tests/Layer/test_KaMap.html

    old new  
    6262        layer.grid = [ [6, tr],  
    6363                       [bl, 7]]; 
    6464 
    65         var bounds = layer.getGridBounds(); 
     65        var bounds = layer.getTilesBounds(); 
    6666     
    6767        var testBounds = new OpenLayers.Bounds(1,2,3,4); 
    6868         
  • tests/Layer/test_TMS.html

    old new  
    4646        layer.grid = [ [6, tr],  
    4747                       [bl, 7]]; 
    4848 
    49         var bounds = layer.getGridBounds(); 
     49        var bounds = layer.getTilesBounds(); 
    5050     
    5151        var testBounds = new OpenLayers.Bounds(1,2,3,4); 
    5252         
  • lib/OpenLayers/Tile/Image.js

    old new  
    9696        if (!OpenLayers.Tile.prototype.draw.apply(this, arguments)) { 
    9797            return false;     
    9898        } 
     99         
     100        if (this.isLoading) { 
     101            //if we're already loading, send 'reload' instead of 'loadstart'. 
     102            this.events.triggerEvent("reload");  
     103        } else { 
     104            this.isLoading = true; 
     105            this.events.triggerEvent("loadstart"); 
     106        } 
     107         
    99108        if (this.imgDiv == null) { 
    100109            this.initImgDiv(); 
    101110        } 
     
    202211        // we need this reference to check back the viewRequestID 
    203212        this.imgDiv.map = this.layer.map; 
    204213 
     214        //bind a listener to the onload of the image div so that we  
     215        // can register when a tile has finished loading. 
     216        var onload = function() { 
     217             
     218            //normally isLoading should always be true here but there are some  
     219            // right funky conditions where loading and then reloading a tile 
     220            // with the same url *really*fast*. this check prevents sending  
     221            // a 'loadend' if the msg has already been sent 
     222            // 
     223            if (this.isLoading) {  
     224                this.isLoading = false;  
     225                this.events.triggerEvent("loadend");  
     226            } 
     227        } 
     228        OpenLayers.Event.observe(this.imgDiv, 'load', 
     229                                 onload.bindAsEventListener(this)); 
     230 
    205231    }, 
    206232 
    207233    /** 
  • lib/OpenLayers/Tile.js

    old new  
    2121OpenLayers.Tile.prototype = { 
    2222     
    2323    /**  
     24     * Constant: EVENT_TYPES 
     25     * {Array(String)} Supported application event types 
     26     */ 
     27    EVENT_TYPES: [ "loadstart", "loadend", "reload"], 
     28     
     29    /** 
     30     * APIProperty: events 
     31     * {<OpenLayers.Events>} An events object that handles all  
     32     *                       events on the tile. 
     33     */ 
     34    events: null, 
     35 
     36    /** 
    2437     * Property: id  
    2538     * {String} null 
    2639     */ 
     
    6679     */ 
    6780    drawn: false, 
    6881 
     82    /** 
     83     * Property: isLoading 
     84     * {Boolean} Is the tile loading? 
     85     */ 
     86    isLoading: false, 
     87     
    6988    /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor. 
    7089     *             there is no need for the base tile class to have a url. 
    7190     *  
     
    88107 
    89108        //give the tile a unique id based on its BBOX. 
    90109        this.id = OpenLayers.Util.createUniqueID("Tile_"); 
     110         
     111        this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES); 
    91112    }, 
    92113     
    93114    /**  
     
    99120        this.bounds = null; 
    100121        this.size = null; 
    101122        this.position = null; 
     123         
     124        this.events.destroy(); 
     125        this.events = null; 
    102126    }, 
    103127 
    104128    /** 
  • lib/OpenLayers/Layer/Grid.js

    old new  
    2929     */ 
    3030    grid: null, 
    3131 
     32    /** APIProperty: ratio 
     33     *  {Float} Used only when in single-tile mode, this specifies the  
     34     *          ratio of the size of the single tile to the size of the map. 
     35     */ 
     36    ratio: 1.5, 
     37 
    3238    /** 
    3339     * APIProperty: buffer 
    34      * {Integer} 
     40     * {Integer} Used only when in gridded mode, this specifies the number of  
     41     *           extra rows and colums of tiles which will surround the minimum 
     42     *           grid tiles to cover the map. 
    3543     */ 
    3644    buffer: 2, 
    3745 
    3846    /** 
     47     * APIProperty: numLoadingTiles 
     48     * {Integer} How many tiles are still loading? 
     49     */ 
     50    numLoadingTiles: 0, 
     51 
     52    /** 
    3953     * Constructor: OpenLayers.Layer.Grid 
    4054     * Create a new grid layer 
    4155     * 
     
    4458     * url - {String} 
    4559     * params - {Object} 
    4660     * options - {Object} Hashtable of extra options to tag onto the layer 
    47     */ 
     61    */ 
    4862    initialize: function(name, url, params, options) { 
    4963        OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,  
    5064                                                                arguments); 
     65         
     66        //grid layers will trigger 'tileloaded' when each new tile is  
     67        // loaded, as a means of progress update to listeners. 
     68        // listeners can access 'numLoadingTiles' if they wish to keep track 
     69        // of the loading progress 
     70        // 
     71        this.events.addEventType("tileloaded"); 
     72 
    5173        this.grid = new Array(); 
    5274    }, 
    5375 
     
    7294            for(var iRow=0; iRow < this.grid.length; iRow++) { 
    7395                var row = this.grid[iRow]; 
    7496                for(var iCol=0; iCol < row.length; iCol++) { 
    75                     row[iCol].destroy(); 
     97                    var tile = row[iCol]; 
     98                    this.removeTileMonitoringHooks(tile); 
     99                    tile.destroy(); 
    76100                } 
    77101            } 
    78102            this.grid = []; 
     
    113137    },     
    114138 
    115139    /** 
    116      * Method: setMap 
    117      * When the layer is added to a map, then we can ask the map for 
    118      *   its default tile size 
    119      * 
    120      * Parameters: 
    121      * map - {<OpenLayers.Map>} 
    122      */ 
    123     setMap: function(map) { 
    124         OpenLayers.Layer.HTTPRequest.prototype.setMap.apply(this, arguments); 
    125         if (this.tileSize == null) { 
    126             this.tileSize = this.map.getTileSize(); 
    127         } 
    128     }, 
    129  
    130     /** 
    131140     * Method: moveTo 
    132141     * This function is called whenever the map is moved. All the moving 
    133142     * of actual 'tiles' is done by the map, but moveTo's role is to accept 
     
    141150    moveTo:function(bounds, zoomChanged, dragging) { 
    142151        OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this, arguments); 
    143152         
    144         if (bounds == null) { 
    145             bounds = this.map.getExtent(); 
    146         } 
     153        bounds = bounds || this.map.getExtent(); 
     154 
    147155        if (bounds != null) { 
    148             if (!this.grid.length || zoomChanged  
    149                 || !this.getGridBounds().containsBounds(bounds, true)) {  
    150                 this._initTiles(); 
     156              
     157            // if grid is empty or zoom has changed, we *must* re-tile 
     158            var forceReTile = !this.grid.length || zoomChanged; 
     159 
     160            // total bounds of the tiles 
     161            var tilesBounds = this.getTilesBounds();             
     162       
     163            if (this.singleTile) { 
     164                 
     165                // We want to redraw whenever even the slightest part of the  
     166                //  current bounds is not contained by our tile. 
     167                //  (thus, we do not specify partial -- its default is false) 
     168                if ( forceReTile ||  
     169                     (!dragging && !tilesBounds.containsBounds(bounds))) { 
     170                    this.initSingleTile(bounds); 
     171                } 
    151172            } else { 
    152                 var buffer = (this.buffer) ? this.buffer*1.5 : 1; 
    153                 while (true) { 
    154                     var tlLayer = this.grid[0][0].position; 
    155                     var tlViewPort =  
    156                         this.map.getViewPortPxFromLayerPx(tlLayer); 
    157                     if (tlViewPort.x > -this.tileSize.w * (buffer - 1)) { 
    158                         this.shiftColumn(true); 
    159                     } else if (tlViewPort.x < -this.tileSize.w * buffer) { 
    160                         this.shiftColumn(false); 
    161                     } else if (tlViewPort.y > -this.tileSize.h * (buffer - 1)) { 
    162                         this.shiftRow(true); 
    163                     } else if (tlViewPort.y < -this.tileSize.h * buffer) { 
    164                         this.shiftRow(false); 
    165                     } else { 
    166                         break; 
    167                     } 
    168                 }; 
    169                 if (this.buffer == 0) { 
    170                     for (var r=0, rl=this.grid.length; r<rl; r++) { 
    171                         var row = this.grid[r]; 
    172                         for (var c=0, cl=row.length; c<cl; c++) { 
    173                             var tile = row[c]; 
    174                             if (!tile.drawn && tile.bounds.intersectsBounds(bounds, false)) { 
    175                                 tile.draw(); 
    176                             } 
    177                         } 
    178                     } 
     173              
     174                // if the bounds have changed such that they are not even  
     175                //  *partially* contained by our tiles (IE user has  
     176                //  programmatically panned to the other side of the earth)  
     177                //  then we want to reTile (thus, partial true).   
     178                // 
     179                if (forceReTile || !tilesBounds.containsBounds(bounds, true)) { 
     180                    this.initGriddedTiles(bounds); 
     181                } else { 
     182                    //we might have to shift our buffer tiles 
     183                    this.moveGriddedTiles(bounds); 
    179184                } 
    180185            } 
    181186        } 
    182187    }, 
    183188     
    184189    /** 
    185      * Method: getGridBounds 
     190     * APIMethod: setTileSize 
     191     * Check if we are in singleTile mode and if so, set the size as a ratio 
     192     *     of the map size (as specified by the layer's 'ratio' property). 
     193     *  
     194     * Parameters: 
     195     * size - {<OpenLayers.Size>} 
     196     */ 
     197    setTileSize: function(size) {  
     198        if (this.singleTile) { 
     199            var size = this.map.getSize().clone(); 
     200            size.h = size.h * this.ratio; 
     201            size.w = size.w * this.ratio; 
     202        }  
     203        OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this, [size]); 
     204    }, 
     205         
     206    /** 
     207     * Method: getTilesBounds 
    186208     * Get the bounds of the grid 
    187209     *  
    188210     * Return: 
     
    190212     * currently loaded tiles (including those partially or not at all seen  
    191213     * onscreen) 
    192214     */ 
    193     getGridBounds:function() { 
     215    getTilesBounds:function() {     
     216        var bounds = null;  
    194217         
    195         var bottom = this.grid.length - 1; 
    196         var bottomLeftTile = this.grid[bottom][0]; 
     218        if (this.grid.length) { 
     219            var bottom = this.grid.length - 1; 
     220            var bottomLeftTile = this.grid[bottom][0]; 
     221     
     222            var right = this.grid[0].length - 1;  
     223            var topRightTile = this.grid[0][right]; 
     224     
     225            bounds = new OpenLayers.Bounds(bottomLeftTile.bounds.left,  
     226                                           bottomLeftTile.bounds.bottom, 
     227                                           topRightTile.bounds.right,  
     228                                           topRightTile.bounds.top); 
     229             
     230        }    
     231        return bounds; 
     232    }, 
    197233 
    198         var right = this.grid[0].length - 1;  
    199         var topRightTile = this.grid[0][right]; 
     234    /** 
     235     * Method: initSingleTile 
     236     *  
     237     * Parameters:  
     238     * bounds - {<OpenLayers.Bounds>} 
     239     */ 
     240    initSingleTile: function(bounds) { 
    200241 
    201         return new OpenLayers.Bounds(bottomLeftTile.bounds.left,  
    202                                      bottomLeftTile.bounds.bottom, 
    203                                      topRightTile.bounds.right,  
    204                                      topRightTile.bounds.top); 
     242        //determine new tile bounds 
     243        var center = bounds.getCenterLonLat(); 
     244        var tileWidth = bounds.getWidth() * this.ratio; 
     245        var tileHeight = bounds.getHeight() * this.ratio; 
     246                                        
     247        var tileBounds =  
     248            new OpenLayers.Bounds(center.lon - (tileWidth/2), 
     249                                  center.lat - (tileHeight/2), 
     250                                  center.lon + (tileWidth/2), 
     251                                  center.lat + (tileHeight/2)); 
     252   
     253        var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top); 
     254        var px = this.map.getLayerPxFromLonLat(ul); 
     255  
     256        if (!this.grid.length) { 
     257            this.grid[0] = new Array(); 
     258        } 
     259 
     260        var tile = this.grid[0][0]; 
     261        if (!tile) { 
     262            tile = this.addTile(tileBounds, px); 
     263             
     264            this.addTileMonitoringHooks(tile); 
     265            tile.draw(); 
     266            this.grid[0][0] = tile; 
     267        } else { 
     268            tile.moveTo(tileBounds, px); 
     269        }            
     270         
     271        //remove all but our single tile 
     272        this.removeExcessTiles(1,1); 
    205273    }, 
    206274 
    207275    /** 
    208      * Method: _initTiles 
    209      * Initialize the tiles 
     276     * Method: initGriddedTiles 
     277     *  
     278     * Parameters: 
     279     * bounds - {<OpenLayers.Bounds>} 
    210280     */ 
    211     _initTiles:function() { 
    212          
     281    initGriddedTiles:function(bounds) { 
     282        
    213283        // work out mininum number of rows and columns; this is the number of 
    214284        // tiles required to cover the viewport plus one for panning 
    215285        var viewSize = this.map.getSize(); 
    216286        var minRows = Math.ceil(viewSize.h/this.tileSize.h) + 1; 
    217287        var minCols = Math.ceil(viewSize.w/this.tileSize.w) + 1; 
    218288         
    219         var bounds = this.map.getExtent(); 
    220289        var extent = this.map.getMaxExtent(); 
    221290        var resolution = this.map.getResolution(); 
    222291        var tilelon = resolution * this.tileSize.w; 
     
    256325            var colidx = 0; 
    257326  
    258327            do { 
    259                 var tileBounds = new OpenLayers.Bounds(tileoffsetlon,  
    260                                                       tileoffsetlat,  
    261                                                       tileoffsetlon + tilelon, 
    262                                                       tileoffsetlat + tilelat); 
     328                var tileBounds =  
     329                    new OpenLayers.Bounds(tileoffsetlon,  
     330                                          tileoffsetlat,  
     331                                          tileoffsetlon + tilelon, 
     332                                          tileoffsetlat + tilelat); 
    263333 
    264334                var x = tileoffsetx; 
    265335                x -= parseInt(this.map.layerContainerDiv.style.left); 
     
    271341                var tile = row[colidx++]; 
    272342                if (!tile) { 
    273343                    tile = this.addTile(tileBounds, px); 
     344                    this.addTileMonitoringHooks(tile); 
    274345                    row.push(tile); 
    275346                } else { 
    276347                    tile.moveTo(tileBounds, px, false); 
     
    286357        } while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer) 
    287358                || rowidx < minRows) 
    288359         
    289         // remove extra rows 
    290         while (this.grid.length > rowidx) { 
    291             var row = this.grid.pop(); 
    292             for (var i=0, l=row.length; i<l; i++) { 
    293                 row[i].destroy(); 
    294             } 
    295         } 
    296          
    297         // remove extra columns 
    298         while (this.grid[0].length > colidx) { 
    299             for (var i=0, l=this.grid.length; i<l; i++) { 
    300                 var row = this.grid[i]; 
    301                 var tile = row.pop(); 
    302                 tile.destroy(); 
    303             } 
    304         } 
    305          
     360        //shave off exceess rows and colums 
     361        this.removeExcessTiles(rowidx, colidx); 
     362 
    306363        //now actually draw the tiles 
    307364        this.spiralTileLoad(); 
    308365    }, 
     
    396453        // Should be implemented by subclasses 
    397454    }, 
    398455     
     456    /**  
     457     * Method: addTileMonitoringHooks 
     458     * This function takes a tile as input and adds the appropriate hooks to  
     459     *     the tile so that the layer can keep track of the loading tiles. 
     460     *  
     461     * Parameters:  
     462     * tile - {<OpenLayers.Tile>} 
     463     */ 
     464    addTileMonitoringHooks: function(tile) { 
     465         
     466        tile.onLoadStart = function() { 
     467            //if that was first tile then trigger a 'loadstart' on the layer