summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Layer/Grid.html
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Layer/Grid.html')
-rw-r--r--misc/openlayers/tests/Layer/Grid.html1593
1 files changed, 1593 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Layer/Grid.html b/misc/openlayers/tests/Layer/Grid.html
new file mode 100644
index 0000000..495a9ab
--- /dev/null
+++ b/misc/openlayers/tests/Layer/Grid.html
@@ -0,0 +1,1593 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
+ var layer;
+
+ var name = 'Test Layer';
+ var url = "http://vmap0.tiles.osgeo.org/wms/vmap0";
+ var params = {layers: 'basic', format: 'image/png'};
+
+ /**
+ * NOTE TO READER:
+ *
+ * Some of the tests on the Grid class actually use the WMS class.
+ * This is because WMS is a subclass of Grid and it implements the
+ * core functions which are necessary to test the tile-generation
+ * mechanism.
+ *
+ */
+
+
+ function test_constructor (t) {
+ t.plan( 7 );
+
+ layer = new OpenLayers.Layer.Grid(name, url, params, null);
+ t.ok( layer instanceof OpenLayers.Layer.Grid, "returns OpenLayers.Layer.Grid object" );
+ t.eq( layer.buffer, 0, "buffer default is 0");
+ t.eq( layer.ratio, 1.5, "ratio default is 1.5");
+ t.eq( layer.numLoadingTiles, 0, "numLoadingTiles starts at 0");
+ t.ok( layer.tileClass === OpenLayers.Tile.Image, "tileClass default is OpenLayers.Tile.Image");
+ t.eq( layer.className, 'olLayerGrid', "className default is olLayerGrid");
+
+ var obj = {};
+ var func = function() {};
+ layer.events.register('tileloaded', obj, func);
+
+ t.ok( layer.events.listeners['tileloaded'].length == 1, "one listener for tileloaded after register");
+ }
+
+ function test_constructor_singleTile(t) {
+ t.plan(2);
+ layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true});
+ t.eq( layer.className, 'olLayerGridSingleTile', "className default is olLayerGridSingleTile");
+ t.eq( layer.removeBackBufferDelay, 0, "removeBackBufferDelay default is 0");
+ }
+
+ function test_setMap(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map', {tileManager: null});
+ layer = new OpenLayers.Layer.Grid(name, url, params, null);
+ map.addLayer(layer);
+ t.ok(OpenLayers.Element.hasClass(layer.div, "olLayerGrid"),
+ "olLayerGrid class assigned to layer div");
+ map.destroy();
+ }
+
+ function test_setMap_singleTile(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true});
+ map.addLayer(layer);
+ t.ok(OpenLayers.Element.hasClass(layer.div, "olLayerGridSingleTile"),
+ "olLayerGridSingleTile class assigned to layer div");
+ map.destroy();
+ }
+
+ function test_Layer_Grid_inittiles (t) {
+ t.plan( 2 );
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2});
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0,0),5);
+ t.eq( layer.grid.length, 8, "Grid rows is correct." );
+ t.eq( layer.grid[0].length, 7, "Grid cols is correct." );
+
+ }
+
+ function test_Layer_Grid_tileClass(t) {
+ t.plan(2);
+
+ var myTileClass = OpenLayers.Class(OpenLayers.Tile, {});
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params, {
+ tileClass: myTileClass
+ });
+ map.addLayer(layer);
+
+ t.ok(layer.tileClass === myTileClass, "tileClass is set");
+ var instance = layer.addTile(new OpenLayers.Bounds(-10, 10, 50, 100),
+ new OpenLayers.Pixel(10, 12));
+
+ t.ok(instance instanceof myTileClass, "addTile returns type is correct");
+
+ map.destroy();
+ }
+
+ function test_Layer_Grid_clearTiles (t) {
+ t.plan(4);
+
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ map.addLayer(layer);
+
+ map.setCenter(new OpenLayers.LonLat(0,0));
+
+ var numTiles = layer.grid.length * layer.grid[0].length;
+
+ //our count of how many times tile.destroy() is called
+ tilesDeleted = 0;
+
+ //this will get set to false if we try to destroy a tile that has
+ // not been unhookedv
+ allTilesUnhooked = true;
+
+ OpenLayers.Tile.Image.prototype._destroy =
+ OpenLayers.Tile.Image.prototype.destroy;
+
+ OpenLayers.Tile.Image.prototype.destroy = function() {
+ if (!this.unhooked) {
+ allTilesUnhooked = false;
+ }
+ tilesDeleted++;
+ }
+
+ layer.removeTileMonitoringHooks = function(tile) {
+ tile.unhooked = true;
+ }
+
+ layer.clearGrid();
+
+ t.ok( layer.grid != null, "layer.grid does not get nullified" );
+ t.eq(tilesDeleted, numTiles, "all tiles destroy()ed properly");
+ t.ok(allTilesUnhooked, "all tiles unhooked before being destroyed");
+ t.eq(layer.gridResolution, null, "gridResolution set to null");
+
+ OpenLayers.Tile.Image.prototype.destroy =
+ OpenLayers.Tile.Image.prototype._destroy;
+
+ }
+
+
+ function test_Layer_Grid_getTilesBounds(t) {
+ t.plan(4);
+
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+
+
+ //normal grid
+ var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};
+ var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};
+ layer.grid = [ [6, tr],
+ [bl, 7]];
+
+ var bounds = layer.getTilesBounds();
+ var testBounds = new OpenLayers.Bounds(1,2,3,4);
+
+ t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds");
+
+ //no tiles
+ layer.grid = [];
+ bounds = layer.getTilesBounds();
+
+ t.ok(bounds == null, "getTilesBounds() on a tile-less grid returns null");
+
+
+ //singleTile
+ var singleTile = { bounds: new OpenLayers.Bounds(1,2,3,4)};
+ layer.grid = [ [ singleTile ] ];
+ bounds = layer.getTilesBounds();
+
+ t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds");
+
+ //world wrapped around the dateline
+ var bl = { bounds: new OpenLayers.Bounds(0,-90,180,90)};
+ var tr = { bounds: new OpenLayers.Bounds(-180,-90,0,90)};
+ layer.grid = [[bl, tr]];
+
+ var bounds = layer.getTilesBounds();
+ var testBounds = new OpenLayers.Bounds(0,-90,360,90);
+
+ t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds");
+
+ }
+
+ function test_Layer_Grid_getResolution(t) {
+ t.plan( 1 );
+
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ map.addLayer(layer);
+
+ map.zoom = 5;
+
+ t.eq( layer.getResolution(), 0.0439453125, "getResolution() returns correct value");
+ }
+
+ function test_Layer_Grid_getZoomForExtent(t) {
+ t.plan( 2 );
+ var bounds, zoom;
+
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ map.addLayer(layer);
+
+ bounds = new OpenLayers.Bounds(10,10,12,12);
+ zoom = layer.getZoomForExtent(bounds);
+
+ t.eq( zoom, 8, "getZoomForExtent() returns correct value");
+
+ bounds = new OpenLayers.Bounds(10,10,100,100);
+ zoom = layer.getZoomForExtent(bounds);
+
+ t.eq( zoom, 2, "getZoomForExtent() returns correct value");
+ }
+
+ function test_moveGriddedTiles(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params, {buffer: 2});
+ map.addLayer(layer);
+ map.setCenter([0, 0], 5);
+ var count = 0;
+ layer.shiftColumn = function(prepend) {
+ ++count;
+ OpenLayers.Layer.WMS.prototype.shiftColumn.apply(this, arguments);
+ }
+ map.moveTo([15, 0]);
+ t.delay_call(.5, function() {
+ t.eq(count, 1, "column shifted once");
+ });
+ }
+
+ function test_Layer_Grid_moveTo(t) {
+
+ t.plan(13);
+
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ layer.destroy = function() {}; //we're going to do funky things with the grid
+ layer.applyBackBuffer = function() {}; // backbuffering isn't under test here
+ map.addLayer(layer);
+ map.setCenter([-10, 0], 5);
+
+ var log = [];
+
+ //make sure null bounds doesnt cause script error.
+ // no test necessary, just action
+ map.getExtent = function() { return null; }
+ layer.singleTile = false;
+ layer.moveTo(); //checks to make sure null bounds doesnt break us
+
+
+ //observing globals
+ layer.initSingleTile = function(bounds) {
+ g_WhichFunc = "InitSingle";
+ g_Bounds = bounds;
+ };
+ layer.initGriddedTiles = function(bounds) {
+ g_WhichFunc = "InitGridded";
+ g_Bounds = bounds;
+ };
+ layer.moveGriddedTiles = function() {
+ g_WhichFunc = "MoveGridded";
+ g_Bounds = layer.map.getExtent();
+ };
+ var clearTestBounds = function() {
+ g_WhichFunc = null;
+ g_Bounds = null;
+ };
+
+ //default map extent (tested every time below)
+ b = new OpenLayers.Bounds(0,0,100,100);
+ map.getExtent = function() {
+ return b;
+ };
+ var tilesBounds = null;
+ layer.getTilesBounds = function() {
+ return tilesBounds;
+ }
+
+
+//FORCE
+
+ //empty grid
+ layer.grid = [];
+ //grid
+ clearTestBounds();
+ layer.singleTile = false;
+ layer.moveTo()
+ t.ok(g_Bounds.equals(b), "if grid is empty, initGridded called");
+
+ //singletile
+ clearTestBounds();
+ layer.singleTile = true;
+ layer.moveTo()
+ t.ok(g_Bounds.equals(b), "if grid is empty, initSingleTile called");
+
+ //zoomChanged
+ zoomChanged = true;
+ layer.grid = [ [ {} ] ];
+
+ //grid
+ clearTestBounds();
+ layer.singleTile = false;
+ layer.moveTo(null, zoomChanged);
+ t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initGridded called");
+
+ //singletile
+ clearTestBounds();
+ layer.singleTile = true;
+ layer.moveTo(null, zoomChanged);
+ t.ok(g_Bounds.equals(b), "if layer has grid but zoomChanged is called, initSingleTile called");
+
+
+//NO FORCE
+ zoomChanged = false;
+ layer.grid = [ [ {} ] ];
+
+ //single tile
+ layer.singleTile = true;
+
+ //DRAGGING
+ var dragging = true;
+
+ //in bounds
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(-10,-10,110,110);
+ layer.moveTo(null, zoomChanged, dragging);
+ t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()");
+
+ //out bounds
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(10,10,120,120);
+ layer.moveTo(null, zoomChanged, dragging);
+ t.ok(g_Bounds == null, "if dragging and tile out of bounds, no init()");
+
+ //NOT DRAGGING
+ dragging = false;
+
+ //in bounds
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(-10,-10,110,110);
+ layer.moveTo(null, zoomChanged, dragging);
+ t.ok(g_Bounds == null, "if dragging and tile in bounds, no init()");
+
+ //out bounds
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(10,10,120,120);
+ layer.moveTo(null, zoomChanged, dragging);
+ t.ok(g_WhichFunc == "InitSingle", "if not dragging and tile out of bounds, we call initSingleTile()");
+ t.ok(g_Bounds.equals(b), "if not dragging and tile out of bounds, we call initSingleTile() with correct bounds");
+
+
+ //gridded
+ layer.grid = [ [ {position: new OpenLayers.Pixel(0,0)} ] ];
+ layer.singleTile = false;
+
+ //regular move
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(10,10,120,120);
+ g_WhichFunc = null;
+ layer.moveTo(null, zoomChanged);
+ t.eq(g_WhichFunc, "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()");
+ t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds");
+
+ // drastic pan
+ clearTestBounds();
+ tilesBounds = new OpenLayers.Bounds(-150,-150,-120,-120);
+ layer.moveTo(null, zoomChanged);
+ t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()");
+ t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds");
+ }
+
+ /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR
+ *
+ * -insertColumn
+ * -insertRow
+ *
+
+ function 08_Layer_Grid_insertColumn(t) {
+ }
+
+ function 09_Layer_Grid_insertRow(t) {
+ }
+
+ *
+ */
+
+ function test_Layer_Grid_clone(t) {
+ t.plan(7);
+
+ var options = {tileSize: new OpenLayers.Size(500,50)};
+ var map = new OpenLayers.Map('map', options);
+ layer = new OpenLayers.Layer.Grid(name, url, params);
+ map.addLayer(layer);
+
+ layer.grid = [ [6, 7],
+ [8, 9]];
+
+ // if we clone when tiles are still loading, this should not influence the clone
+ layer.numLoadingTiles = 1;
+ var clone = layer.clone();
+ t.eq( clone.numLoadingTiles, 0, "numLoadingTiles should be reset");
+ t.ok( clone.grid != layer.grid, "clone does not copy grid");
+ t.ok( clone.grid.length == 0, "clone creates a new array instead");
+
+ t.eq(clone.backBuffer, null, "no backbuffer from original");
+
+ t.ok( clone.tileSize.equals(layer.tileSize), "tileSize correctly cloned");
+
+ layer.tileSize.w += 40;
+
+ t.eq( clone.tileSize.w, 500, "changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference");
+
+ t.eq( clone.alpha, layer.alpha, "alpha copied correctly");
+
+ layer.grid = null;
+ }
+
+ function test_Layer_Grid_setTileSize(t) {
+ t.plan(1);
+
+ OpenLayers.Layer.HTTPRequest.prototype._setTileSize =
+ OpenLayers.Layer.HTTPRequest.prototype.setTileSize;
+
+ OpenLayers.Layer.HTTPRequest.prototype.setTileSize = function(size) {
+ g_Size = size;
+ };
+
+
+ layer = new OpenLayers.Layer.Grid(name, url, params, {
+ singleTile: true
+ });
+ mapSize = new OpenLayers.Size(100,1000);
+ layer.map = {
+ getSize: function() { return mapSize; }
+ }
+
+ g_Size = null;
+ layer.setTileSize();
+
+ var idealSize = new OpenLayers.Size(150,1500);
+ t.ok( g_Size && g_Size.equals(idealSize), "correctly calculated tile size passed to superclass setTileSize() function");
+
+ OpenLayers.Layer.HTTPRequest.prototype.setTileSize =
+ OpenLayers.Layer.HTTPRequest.prototype._setTileSize;
+ }
+
+ function test_Layer_Grid_initSingleTile(t) {
+ t.plan( 11 );
+
+ layer = new OpenLayers.Layer.Grid(name, url, params, {
+ singleTile: true,
+ ratio: 2
+ });
+
+ var bounds = new OpenLayers.Bounds(-10,10,50,100);
+
+ var desiredTileBounds = new OpenLayers.Bounds(-40,-35,80,145);
+ var desiredUL = new OpenLayers.LonLat(-40,145);
+
+ translatedPX = {};
+ layer.map = {
+ getLayerPxFromLonLat: function(ul) {
+ t.ok(ul.lon === desiredUL.lon && ul.lat === desiredUL.lat, "correct ul passed to translation");
+ return translatedPX;
+ },
+ getResolution: function() {
+ }
+ }
+
+ var newTile = {
+ draw: function() {
+ t.ok(true, "newly created tile has been drawn");
+ }
+ };
+ layer.addTile = function(tileBounds, px) {
+ t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to addTile to create new tile");
+ t.ok(px == translatedPX, "correct tile px passed to addTile to create new tile");
+ return newTile;
+ };
+ layer.addTileMonitoringHooks = function(tile) {
+ t.ok(tile == newTile, "adding monitoring hooks to the newly added tile");
+ };
+ layer.removeExcessTiles = function(x,y) {
+ t.ok(x == 1 && y == 1, "removeExcessTiles called")
+ };
+
+
+ layer.grid = [];
+ layer.initSingleTile(bounds);
+
+ t.ok(layer.grid[0][0] == newTile, "grid's 0,0 is set to the newly created tile");
+
+ var tile = {
+ moveTo: function(tileBounds, px) {
+ t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to tile.moveTo()");
+ t.ok(px == translatedPX, "correct tile px passed to tile.moveTo()");
+ }
+ };
+ layer.grid = [[ tile ]];
+ layer.initSingleTile(bounds);
+
+ }
+
+ function test_Layer_Grid_addTileMonitoringHooks(t) {
+ t.plan(18);
+
+ layer = new OpenLayers.Layer.Grid();
+ layer.events = {
+ 'triggerEvent': function(str, evt) {
+ g_events.push([str, evt]);
+ }
+ }
+
+ var tile = {
+ events: {
+ register: function(name, obj, func) {
+ g_registered[name] = [obj, func];
+ },
+ on: function(obj) {
+ for (var o in obj) {
+ if (obj.hasOwnProperty(o)) {
+ tile.events.register(o, obj.scope, obj[o]);
+ }
+ }
+ }
+ },
+ imgDiv: {className: ''}
+ }
+
+ g_registered = {};
+ g_events = [];
+
+ layer.addTileMonitoringHooks(tile);
+
+ //loadstart
+ t.ok(tile.onLoadStart != null, "onLoadStart function created and added to tile");
+ entry = g_registered["loadstart"];
+ t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly registered");
+
+ layer.numLoadingTiles = 0;
+ g_events = [];
+ tile.onLoadStart.apply(layer);
+
+ t.eq(g_events[0][0], "loadstart", "loadstart event triggered when numLoadingTiles is 0");
+ t.eq(layer.numLoadingTiles, 1, "numLoadingTiles incremented");
+ t.eq(g_events[1][0], "tileloadstart", "tileloadstart event triggered");
+
+ g_events = [];
+ tile.onLoadStart.apply(layer);
+ t.eq(g_events.length, 1, "tileloadstart, but not loadstart triggered when numLoadingTiles is not 0");
+ t.eq(layer.numLoadingTiles, 2, "numLoadingTiles incremented");
+
+
+ //loadend
+ t.ok(tile.onLoadEnd != null, "onLoadEnd function created and added to tile");
+ entry = g_registered["loadend"];
+ t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly registered");
+
+ g_events = [];
+ tile.onLoadError.apply(layer);
+ t.eq(g_events[0][0], "tileerror", "tileerror triggered");
+ t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object");
+
+ layer.numLoadingTiles = 2;
+ g_events = [];
+ tile.onLoadEnd.apply(layer, [{}]);
+ t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is > 0");
+ t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object");
+ t.eq(g_events.length, 1, "loadend event not triggered when numLoadingTiles is > 0");
+ t.eq(layer.numLoadingTiles, 1, "numLoadingTiles decremented");
+
+
+ g_events = [];
+ layer.grid = [[{}]]; // to prevent error in updateBackBuffer
+ tile.onLoadEnd.apply(layer, [{}]);
+ t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is 0");
+ t.eq(g_events[1][0], "loadend", "loadend event triggered when numLoadingTiles is 0");
+ t.eq(layer.numLoadingTiles, 0, "numLoadingTiles decremented");
+ }
+
+ function test_Layer_Grid_removeTileMonitoringHooks(t) {
+ t.plan(2);
+
+ layer = new OpenLayers.Layer.Grid();
+
+ var tile = {
+ onLoadStart: {},
+ onLoadEnd: {},
+ unload: function() {},
+ events: {
+ unregister: function(name, obj, func) {
+ g_unregistered[name] = [obj, func];
+ },
+ un: OpenLayers.Events.prototype.un
+ }
+ }
+
+ g_unregistered = {};
+
+ layer.removeTileMonitoringHooks(tile);
+
+ entry = g_unregistered["loadstart"];
+ t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, "loadstart correctly unregistered");
+
+ entry = g_unregistered["loadend"];
+ t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly unregistered");
+ }
+
+ function test_Layer_Grid_tileSizeIsInteger(t) {
+ t.plan(1);
+
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.Grid(name, url, params, {
+ singleTile: true,
+ ratio: 1.5
+ });
+ map.addLayers([layer]);
+
+ width = layer.tileSize.w;
+ height = layer.tileSize.h;
+ t.ok(width == parseInt(width) && height == parseInt(height), "calculated tileSize width/height are integer values");
+ }
+ function test_Layer_Grid_getTileBounds(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map2", {zoomMethod: null});
+ var url = "http://octo.metacarta.com/cgi-bin/mapserv";
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+
+ var newParams = { layers: 'sooper',
+ chickpeas: 'image/png'};
+
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ map.zoomIn();
+ var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
+ t.eq(bounds.toBBOX(), "-180,-90,0,90", "get tile bounds returns correct bounds");
+ map.pan(200,0, {animate:false});
+ var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
+ t.eq(bounds.toBBOX(), "0,-90,180,90", "get tile bounds returns correct bounds after pan");
+ }
+
+ function test_Layer_Grid_moveTo_buffer_calculation (t) {
+ t.plan(6);
+
+ var map = new OpenLayers.Map( 'map3' ); // odd map size
+ var layer0 = new OpenLayers.Layer.WMS( "0 buffer: OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'}, {'buffer':0} );
+ map.addLayer(layer0);
+
+ var layer1 = new OpenLayers.Layer.WMS( "1 buffer: OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'}, {'buffer':1} );
+ map.addLayer(layer1);
+
+ var layer2 = new OpenLayers.Layer.WMS( "2 buffer: OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'}, {'buffer':2} );
+ map.addLayer(layer2);
+
+ map.setCenter(new OpenLayers.LonLat(0, 0), 4);
+ t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" );
+ map.setBaseLayer(layer1);
+ t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" );
+ map.setBaseLayer(layer2);
+ t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" );
+
+ // zooming in on Greenland exercises the bug from pre-r4313
+ map.setCenter(new OpenLayers.LonLat(0, 90), 4);
+ t.eq( layer0.grid.length, 3, "Grid rows with buffer:0" );
+ map.setBaseLayer(layer1);
+ t.eq( layer1.grid.length, 5, "Grid rows with buffer:1" );
+ map.setBaseLayer(layer2);
+ t.eq( layer2.grid.length, 7, "Grid rows with buffer:2" );
+ }
+
+ function test_Layer_Grid_destroy (t) {
+
+ t.plan( 9 );
+
+ var map = new OpenLayers.Map('map', {tileManager: null});
+ layer = new OpenLayers.Layer.Grid(name, url, params);
+ map.addLayer(layer);
+ layer.destroy();
+ t.eq( layer.grid, null, "layer.grid is null after destroy" );
+ t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" );
+
+
+ //test with tile creation
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ map.addLayer(layer);
+
+ map.setCenter(new OpenLayers.LonLat(0,0), 10);
+ map.setCenter(new OpenLayers.LonLat(1,1));
+
+ //grab a reference to one of the tiles
+ var tile = layer.grid[1][1];
+ t.eq( tile.imgDiv.className, "olTileImage", "Tile has an image" );
+
+ var removeBackBufferCalled = false;
+ layer.removeBackBuffer = function() {
+ removeBackBufferCalled = true;
+ };
+
+ layer.destroy();
+ t.eq( tile.imgDiv, null, "Tile destroyed" );
+ t.eq( layer.timerId, null, "Tile loading timeout cleared");
+ t.ok( layer.grid == null, "tiles appropriately destroyed")
+ t.ok( removeBackBufferCalled, "destroy calls removeBackBuffer");
+
+ // destroy after remove from map
+ layer = new OpenLayers.Layer.WMS(name, url, params);
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0,0), 10);
+ map.removeLayer(layer);
+ layer.destroy();
+ t.eq( layer.grid, null, "layer.grid is null after destroy" );
+ t.eq( layer.tileSize, null, "layer.tileSize is null after destroy" );
+ }
+
+ function test_setOpacity(t) {
+ t.plan(5);
+
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true,
+ opacity: '0.6'
+ });
+ map.addLayer(layer);
+ // setCenter adds tiles to the layer's grid
+ map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+
+ var tile = layer.grid[0][0], tileImg = tile.imgDiv;
+
+ tile.onImageLoad(); // simulate an image load event
+ t.eq(layer.opacity, '0.6', 'layer opacity value is correct');
+ t.eq(parseFloat(tileImg.style.opacity), 0.6, 'tile opacity is correct');
+
+ layer.setOpacity('0.2');
+ t.eq(layer.opacity, '0.2', 'layer opacity value is correct');
+ t.eq(parseFloat(tileImg.style.opacity), 0.2, 'tile opacity is correct');
+
+ tile = layer.addTile(new OpenLayers.Bounds(1, 2, 3, 4),
+ new OpenLayers.Pixel(5, 6));
+ tile.draw(); // add tile to the grid
+ tile.onImageLoad(); // simulate an image load event
+ t.eq(parseFloat(tile.imgDiv.style.opacity), 0.2, "tile opacity is correc");
+
+ map.destroy();
+ }
+
+ function test_getServerResolution(t) {
+
+ t.plan(4);
+
+ var layer = new OpenLayers.Layer.Grid('', '', {}, {});
+ var res;
+
+ res = layer.getServerResolution(1);
+ t.eq(res, 1, '[1] getServerResolution return value is correct');
+
+ layer.serverResolutions = [2, 1];
+ res = layer.getServerResolution(1);
+ t.eq(res, 1, '[2] getServerResolution return value is correct');
+
+ layer.serverResolutions = [2];
+ res = layer.getServerResolution(1);
+ t.eq(res, 2, '[3] getServerResolution return value is correct');
+
+ var exc;
+ layer.serverResolutions = [0.5];
+ res = layer.getServerResolution(1);
+ t.eq(res, 0.5, '[4] getServerResolution return value is correct');
+ }
+
+ function test_getServerZoom(t) {
+
+ t.plan(5);
+
+ var resolution, zoom;
+ var map = new OpenLayers.Map('map', {
+ resolutions: [8, 4, 2, 1, 0.5],
+ getResolution: function() {
+ return resolution;
+ }
+ });
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true});
+ map.addLayer(layer);
+
+ resolution = 8;
+ zoom = layer.getServerZoom();
+ t.eq(zoom, 0, '[1] getServerZoom return value is correct');
+
+ resolution = 4;
+ zoom = layer.getServerZoom();
+ t.eq(zoom, 1, '[2] getServerZoom return value is correct');
+
+ layer.serverResolutions = [2, 1];
+ resolution = 1;
+ zoom = layer.getServerZoom();
+ t.eq(zoom, 1, '[3] getServerZoom return value is correct');
+
+ layer.serverResolutions = [2];
+ resolution = 0.5;
+ zoom = layer.getServerZoom();
+ t.eq(zoom, 0, '[4] getServerZoom return value is correct');
+
+ var exc;
+ layer.serverResolutions = [0.5];
+ resolution = 1;
+ zoom = layer.getServerZoom();
+ t.eq(zoom, 0, '[4] getServerZoom return value is correct');
+
+ map.destroy();
+ }
+
+ function test_moveTo_scale(t) {
+
+ t.plan(11);
+
+ var map = new OpenLayers.Map('map', {
+ resolutions: [32, 16, 8, 4, 2, 1],
+ zoomMethod: null
+ });
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true,
+ serverResolutions: [32, 16, 8]
+ });
+ map.addLayer(layer);
+
+ // initial resolution is 8
+ map.setCenter(new OpenLayers.LonLat(0, 0), 2);
+
+ // test initial conditions
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, 'layer div scale is 1');
+
+ // change from resolution 8 to 4
+ map.zoomTo(3);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[8->4] layer div scale is 2');
+
+ // change from resolution 8 to 2
+ map.zoomTo(2); map.zoomTo(4);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[8->2] layer div scale is 4');
+
+ // change from resolution 8 to 1
+ map.zoomTo(2); map.zoomTo(5);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[8->1] layer div scale is 8');
+
+ // change from resolution 4 to 2
+ map.zoomTo(3); map.zoomTo(4);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[4->2] layer div scale is 4');
+
+ // change from resolution 4 to 1
+ map.zoomTo(3); map.zoomTo(5);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[4->1] layer div scale is 8');
+
+ // change from resolution 2 to 1
+ map.zoomTo(4); map.zoomTo(5);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[2->1] layer div scale is 8');
+
+ // change from resolution 1 to 2
+ map.zoomTo(5); map.zoomTo(4);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[1->2] layer div scale is 4');
+
+ // change from resolution 1 to 4
+ map.zoomTo(5); map.zoomTo(3);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[1->4] layer div scale is 2');
+
+ // change from resolution 1 to 8
+ map.zoomTo(5); map.zoomTo(2);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->8] layer div scale is 1');
+
+ // change from resolution 1 to 16
+ map.zoomTo(5); map.zoomTo(1);
+ t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->16] layer div scale is 1');
+
+ map.destroy();
+ }
+
+ function test_moveTo_backbuffer_singletile(t) {
+ t.plan(4);
+
+ var map = new OpenLayers.Map('map', {
+ resolutions: [1, 0.5, 0.025],
+ zoomMethod: null
+ });
+ var resolution;
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ singleTile: true,
+ isBaseLayer: true,
+ transitionEffect: 'resize',
+ applyBackBuffer: function(res) {
+ resolution = res;
+ }
+ });
+ map.addLayer(layer);
+
+ // initial resolution is 0.025
+ resolution = undefined;
+ map.setCenter(new OpenLayers.LonLat(0, 0), 2);
+ t.eq(resolution, 0.025,
+ 'applyBackBuffer not called on first moveTo');
+
+ // move to (-90, 45)
+ resolution = undefined;
+ map.setCenter(new OpenLayers.LonLat(-90, 45));
+ t.eq(resolution, 0.025,
+ 'applyBackBuffer called when map is moved');
+
+ // change to resolution 1
+ resolution = undefined;
+ map.zoomTo(0);
+ t.eq(resolution, 1,
+ 'applyBackBuffer called when map is zoomed out');
+
+ // change to resolution 0.5
+ resolution = undefined;
+ map.zoomTo(1);
+ t.eq(resolution, 0.5,
+ 'applyBackBuffer called when map is zoomed out');
+
+ map.destroy();
+ }
+
+ function test_moveTo_backbuffer(t) {
+ t.plan(4);
+
+ var map = new OpenLayers.Map('map', {
+ resolutions: [1, 0.5, 0.025],
+ zoomMethod: null
+ });
+ var resolution;
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true,
+ transitionEffect: 'resize',
+ applyBackBuffer: function(res) {
+ resolution = res;
+ }
+ });
+ map.addLayer(layer);
+
+ // initial resolution is 0.025
+ resolution = undefined;
+ map.setCenter(new OpenLayers.LonLat(0, 0), 2);
+ t.eq(resolution, 0.025,
+ 'applyBackBuffer not called on first moveTo');
+
+ // move to (-90, 45)
+ resolution = undefined;
+ map.setCenter(new OpenLayers.LonLat(-90, 45));
+ t.eq(resolution, undefined,
+ 'applyBackBuffer not called when map is moved');
+
+ // change to resolution 1
+ resolution = undefined;
+ map.zoomTo(0);
+ t.eq(resolution, 1,
+ 'applyBackBuffer called when map is zoomed out');
+
+ // change to resolution 0.5
+ map.zoomTo(1);
+ t.eq(resolution, 0.5,
+ 'applyBackBuffer called when map is zoomed out');
+
+ map.destroy();
+ }
+
+ function test_applyBackBuffer(t) {
+ t.plan(12);
+
+ var map = new OpenLayers.Map('map2');
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var backBuffer;
+
+ // test #1
+ layer.createBackBuffer = function() {
+ return;
+ };
+ layer.applyBackBuffer(2);
+ t.eq(layer.backBuffer, undefined,
+ 'back buffer not created if createBackBuffer returns undefined');
+
+ // test #2
+ layer.createBackBuffer = function() {
+ backBuffer = document.createElement('div');
+ return backBuffer;
+ };
+ layer.gridResolution = 32;
+ layer.backBufferResolution = 2;
+ layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);
+ layer.applyBackBuffer(2);
+ t.ok(layer.backBuffer === backBuffer,
+ 'back buffer set in layer');
+ t.ok(map.layerContainerDiv.firstChild === backBuffer,
+ 'back buffer inserted as first child');
+ t.eq(layer.backBuffer.style.left, '250px',
+ 'back buffer has correct left');
+ t.eq(layer.backBuffer.style.top, '275px',
+ 'back buffer has correct top');
+
+ // test #3
+ layer.createBackBuffer = function() {
+ backBuffer = document.createElement('div');
+ return backBuffer;
+ };
+ layer.gridResolution = 32;
+ layer.backBufferResolution = 2;
+ layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);
+ map.layerContainerOriginPx.x = 20;
+ map.layerContainerOriginPx.y = -20;
+ layer.applyBackBuffer(2);
+ t.ok(layer.backBuffer === backBuffer,
+ 'back buffer set in layer');
+ t.ok(map.layerContainerDiv.firstChild === backBuffer,
+ 'back buffer inserted as first child');
+ t.eq(layer.backBuffer.style.left, '230px',
+ 'back buffer has correct left');
+ t.eq(layer.backBuffer.style.top, '295px',
+ 'back buffer has correct top');
+
+ // test #4
+ // and a back buffer in the layer and do as if back buffer removal
+ // has been scheduled, and test that applyBackBuffer removes the
+ // back buffer and clears the timer
+ layer.createBackBuffer = function() {
+ return;
+ };
+ backBuffer = document.createElement('div');
+ map.layerContainerDiv.insertBefore(backBuffer, map.baseLayer.div);
+ layer.backBuffer = backBuffer;
+ layer.backBufferTimerId = 'fake';
+ layer.applyBackBuffer(2);
+ t.ok(backBuffer !== map.layerContainerDiv.firstChild,
+ 'back buffer is not first child of layer container div');
+ t.eq(layer.backBuffer, null,
+ 'back buffer not set in layer');
+ t.eq(layer.backBufferTimerId, null,
+ 'back buffer timer cleared');
+ map.destroy();
+ }
+
+ function test_createBackBuffer(t) {
+ t.plan(9);
+
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var createBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer;
+
+ var backBuffer;
+
+ OpenLayers.Tile.Image.prototype.createBackBuffer = function() {
+ return;
+ };
+ backBuffer = layer.createBackBuffer();
+ t.ok(backBuffer != undefined,
+ 'createBackBuffer returns a back buffer');
+ t.eq(backBuffer.childNodes.length, 0,
+ 'returned back buffer has no child nodes');
+
+ OpenLayers.Tile.Image.prototype.createBackBuffer = function() {
+ return document.createElement('div');
+ };
+
+ layer.transitionEffect = 'map-resize';
+ backBuffer = layer.createBackBuffer();
+ t.ok(backBuffer.style.zIndex == 99, 'z-index of backbuffer correct for "map-resize".');
+ layer.removeBackBuffer();
+
+ layer.transitionEffect = 'resize';
+ backBuffer = layer.createBackBuffer();
+ t.ok(backBuffer.style.zIndex == layer.getZIndex() - 1, 'z-index of backbuffer correct for "resize",');
+
+ layer.backBufferResolution = 1;
+ layer.gridResolution = 1;
+ layer.backBuffer = backBuffer;
+ layer.div.appendChild(backBuffer);
+ layer.backBufferLonLat = {lon: 0, lat: 0};
+ layer.applyBackBuffer(1);
+ t.ok(backBuffer != undefined,
+ 'createBackBuffer returns a back buffer');
+ t.eq(backBuffer.childNodes[0].style.left, '0px',
+ 'first tile has correct left');
+ t.eq(backBuffer.childNodes[0].style.top, '0px',
+ 'first tile has correct top');
+ t.eq(backBuffer.childNodes[1].style.left, '256px',
+ 'second tile has correct left');
+ t.eq(backBuffer.childNodes[1].style.top, '0px',
+ 'second tile has correct top');
+
+ map.destroy();
+ OpenLayers.Tile.Image.prototype.createBackBuffer = createBackBuffer;
+ }
+
+ function test_removeBackBuffer(t) {
+ t.plan(3);
+
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true});
+ map.addLayer(layer);
+
+ // add a fake back buffer
+ var backBuffer = document.createElement('div');
+ layer.backBuffer = backBuffer;
+ layer.div.appendChild(backBuffer);
+ layer.backBufferResolution = 32;
+
+ layer.removeBackBuffer();
+ t.eq(layer.backBuffer, null, 'backBuffer set to null in layer');
+ t.eq(layer.backBufferResolution, null,
+ 'backBufferResolution set to null in layer');
+ t.ok(backBuffer.parentNode !== layer.div,
+ 'back buffer removed from layer');
+
+ map.destroy();
+ }
+
+ function test_backbuffer_replace(t) {
+ t.plan(6);
+ var map = new OpenLayers.Map('map', {tileManager: null});
+ var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif');
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ layer.grid[1][1].onImageLoad();
+ layer.mergeNewParams({foo: 'bar'});
+ var tile = layer.grid[1][1];
+ t.ok(OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is marked for being replaced');
+ t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer created for tile');
+ // simulate a css declaration where '.olTileReplacing' sets display
+ // to none.
+ tile.imgDiv.style.display = 'none';
+ tile.onImageLoad();
+ t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');
+ t.ok(!document.getElementById(tile.id + '_bb'), 'backbuffer removed for tile');
+
+ layer.mergeNewParams({foo: 'baz'});
+ tile = layer.grid[1][1];
+ // simulate a css declaration where '.olTileReplacing' does not set
+ // display to none.
+ tile.imgDiv.style.display = 'block';
+ tile.onImageLoad();
+ t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');
+ t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer not removed for visible tile');
+ }
+
+ function test_backbuffer_replace_singleTile(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif', null, {
+ singleTile: true,
+ transitionEffect: 'resize'
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ t.delay_call(1, function() {
+ map.zoomIn();
+ var tile = layer.grid[0][0];
+ t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is not marked for being replaced for singleTile layers');
+ });
+ }
+
+ function test_singleTile_move_and_zoom(t) {
+
+ //
+ // In single tile mode with no transition effect, we insert a non-scaled
+ // backbuffer when the layer is moved. But if a zoom occurs right after
+ // a move, i.e. before the new image is received, we need to remove the
+ // backbuffer, or an ill-positioned image will be visible during the
+ // zoom transition.
+ //
+
+ t.plan(4);
+
+ var map = new OpenLayers.Map('map', {zoomMethod: null});
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true,
+ transitionEffect: null,
+ singleTile: true,
+ ratio: 1.1
+ });
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+
+ // move
+ map.setCenter(new OpenLayers.LonLat(50, 50));
+ t.ok(layer.backBuffer && layer.backBuffer.parentNode === layer.div,
+ 'backbuffer inserted after map move');
+ t.eq(layer.backBuffer.style.left, '-25px');
+ t.eq(layer.backBuffer.style.top, '-28px');
+ // zoom
+ map.zoomTo(1);
+ t.eq(layer.backBuffer, null,
+ 'back buffer removed when zooming');
+
+ map.destroy();
+ }
+
+ function test_backbuffer_scaled_layer(t) {
+ t.plan(12);
+
+ //
+ // set up
+ //
+
+ var map = new OpenLayers.Map('map', {
+ resolutions: [32, 16, 8, 4, 2, 1],
+ zoomMethod: null,
+ tileManager: null
+ });
+ var layer = new OpenLayers.Layer.WMS(
+ "WMS",
+ window.location.href + "#",
+ null,
+ {transitionEffect: "resize"}
+ );
+
+ layer.serverResolutions = [32, 16, 8];
+
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 2);
+
+ var origCreateBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer;
+ OpenLayers.Tile.Image.prototype.createBackBuffer = function() {
+ return document.createElement('div');
+ };
+
+ // we want to control when the back buffer is removed
+ var removeBackBuffer = OpenLayers.Function.bind(
+ layer.removeBackBuffer, layer);
+ layer.removeBackBuffer = function() {};
+
+ //
+ // test
+ //
+
+ // change resolution from 8 to 4
+ map.zoomTo(3);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[8->4] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 8 to 2
+ map.zoomTo(2); removeBackBuffer(); map.zoomTo(4);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[8->2] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 16 to 4
+ map.zoomTo(1); removeBackBuffer(); map.zoomTo(3);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 2,
+ '[16->4] back buffer width is as expected');
+ t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 2,
+ '[16->4] back buffer height is as expected');
+ removeBackBuffer();
+
+ // change resolution from 32 to 1
+ map.zoomTo(0); removeBackBuffer(); map.zoomTo(5);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 4,
+ '[32->1] back buffer width is as expected');
+ t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 4,
+ '[32->1] back buffer height is as expected');
+ removeBackBuffer();
+
+ // change resolution from 4 to 2
+ map.zoomTo(3); removeBackBuffer(); map.zoomTo(4);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[4->2] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 4 to 1
+ map.zoomTo(3); removeBackBuffer(); map.zoomTo(5);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[4->1] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 1 to 4
+ map.zoomTo(5); removeBackBuffer(); map.zoomTo(3);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[1->4] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 4 to 8
+ map.zoomTo(3); removeBackBuffer(); map.zoomTo(2);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
+ '[4->8] back buffer not scaled');
+ removeBackBuffer();
+
+ // change resolution from 4 to 16
+ map.zoomTo(3); removeBackBuffer(); map.zoomTo(1);
+ t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 0.5,
+ '[4->16] back buffer width is as expected');
+ t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 0.5,
+ '[4->16] back buffer height is as expected');
+ removeBackBuffer();
+
+ //
+ // tear down
+ //
+
+ map.destroy();
+ OpenLayers.Tile.Image.prototype.createBackBuffer = origCreateBackBuffer
+ }
+
+
+ function test_delayed_back_buffer_removal(t) {
+ //
+ // Test that the delaying of the back buffer removal behaves
+ // as expected.
+ //
+
+ t.plan(5);
+
+ // set up
+
+ var map = new OpenLayers.Map('map', {
+ resolutions: [32, 16, 8, 4, 2, 1],
+ zoomMethod: null
+ });
+ var layer = new OpenLayers.Layer.WMS('', '', {}, {
+ isBaseLayer: true,
+ transitionEffect: 'resize'
+ });
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+
+ map.zoomTo(1);
+
+ t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,
+ '[a] back buffer is first child of layer container div');
+
+ // Mark one tile loaded and add an element to the backbuffer, to see if
+ // backbuffer removal gets scheduled.
+ layer.backBuffer.appendChild(document.createElement('img'));
+ layer.grid[1][1].onImageLoad();
+
+ t.ok(layer.backBufferTimerId !== null,
+ '[a] back buffer scheduled for removal');
+
+ var backBuffer = layer.backBuffer;
+
+ map.zoomTo(2);
+
+ t.ok(layer.backBuffer !== backBuffer,
+ '[b] a new back buffer was created');
+ t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,
+ '[b] back buffer is first child of layer container div');
+ t.ok(layer.backBufferTimerId === null,
+ '[b] back buffer no longer scheduled for removal');
+
+ // tear down
+
+ map.destroy();
+ }
+
+ function test_getGridData(t) {
+ t.plan(12);
+
+ var layer = new OpenLayers.Layer.Grid(null, null, null, {
+ isBaseLayer: true, getURL: function() {
+ return "/bogus/path/to/tile";
+ }
+ });
+ var map = new OpenLayers.Map({
+ div: "map",
+ layers: [layer],
+ controls: [],
+ center: [0, 0],
+ zoom: 1
+ });
+
+ // get tile data for [0, 0]
+ var data = layer.getTileData({lon: 0, lat: 0});
+ t.ok(data && data.tile, "[0, 0]: got tile data");
+ t.eq(data.i, 0, "[0, 0]: i");
+ t.eq(data.j, 128, "[0, 0]: j");
+ t.ok(
+ data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),
+ "[0, 0]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ // get tile data for [-110, 45]
+ data = layer.getTileData({lon: -110, lat: 45});
+ t.ok(data && data.tile, "[-110, 45]: got tile data");
+ t.eq(data.i, 99, "[-110, 45]: i");
+ t.eq(data.j, 64, "[-110, 45]: j");
+ t.ok(
+ data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}),
+ "[-110, 45]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ // get tile data for [0, 300] (north of grid)
+ data = layer.getTileData({lon: 0, lat: 300})
+ t.eq(data, null, "[0, 300]: north of grid");
+
+ // get tile data for [400, 0] (east of grid)
+ data = layer.getTileData({lon: 400, lat: 0})
+ t.eq(data, null, "[400, 0]: east of grid");
+
+ // get tile data for [0, -500] (south of grid)
+ data = layer.getTileData({lon: 0, lat: -500})
+ t.eq(data, null, "[0, -500]: south of grid");
+
+ // get tile data for [-200, 0] (west of grid)
+ data = layer.getTileData({lon: -200, lat: 0})
+ t.eq(data, null, "[-200, 0]: west of grid");
+
+ map.destroy();
+
+ }
+
+ function test_getGridData_wrapped(t) {
+ t.plan(18);
+
+ var layer = new OpenLayers.Layer.Grid(null, null, null, {
+ isBaseLayer: true, getURL: function() {
+ return "/bogus/path/to/tile";
+ },
+ wrapDateLine: true
+ });
+ var map = new OpenLayers.Map({
+ div: "map",
+ layers: [layer],
+ controls: [],
+ center: [-50, 0],
+ zoom: 1
+ });
+
+ // get tile data for [0, 0]
+ var data = layer.getTileData({lon: 0, lat: 0});
+ t.ok(data && data.tile, "[0, 0]: got tile data");
+ t.eq(data.i, 0, "[0, 0]: i");
+ t.eq(data.j, 128, "[0, 0]: j");
+ t.ok(
+ data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),
+ "[0, 0]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ // get tile data for [-110, 45]
+ data = layer.getTileData({lon: -110, lat: 45});
+ t.ok(data && data.tile, "[-110, 45]: got tile data");
+ t.eq(data.i, 99, "[-110, 45]: i");
+ t.eq(data.j, 64, "[-110, 45]: j");
+ t.ok(
+ data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}),
+ "[-110, 45]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ // get tile data for [0, 300] (north of grid)
+ data = layer.getTileData({lon: 0, lat: 300})
+ t.eq(data, null, "[0, 300]: north of grid");
+
+ // get tile data for [400, 0] (equivalent to [40, 0] and visible on map)
+ data = layer.getTileData({lon: 400, lat: 0})
+ t.ok(data && data.tile, "[400, 0]: got tile data");
+ t.eq(data.i, 56, "[400, 0]: i");
+ t.eq(data.j, 128, "[400, 0]: j");
+ t.ok(
+ data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),
+ "[400, 0]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ // get tile data for [0, -500] (south of grid)
+ data = layer.getTileData({lon: 0, lat: -500})
+ t.eq(data, null, "[0, -500]: south of grid");
+
+ // get tile data for [-200, 0] (equivalent to [160, 0] and wrapped to west side map)
+ data = layer.getTileData({lon: -200, lat: 0})
+ t.ok(data && data.tile, "[-200, 0]: got tile data");
+ t.eq(data.i, 227, "[-200, 0]: i");
+ t.eq(data.j, 128, "[-200, 0]: j");
+ t.ok(
+ data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),
+ "[-200, 0]: tile bounds " + data.tile.bounds.toString()
+ );
+
+ map.destroy();
+
+ }
+
+ function test_removeExcessTiles(t) {
+ t.plan(15);
+
+ /*
+ * Set up
+ */
+
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.Grid('name', '/url',
+ {}, {isBaseLayer: true});
+ map.addLayer(layer);
+
+ function newTile(id) {
+ var t = new OpenLayers.Tile(layer,
+ new OpenLayers.Pixel(1, 1),
+ new OpenLayers.Bounds(1, 1, 1, 1));
+ t._id = id;
+ return t;
+ }
+
+ layer.grid = [
+ [newTile(1), newTile(2), newTile(3)],
+ [newTile(4), newTile(5)],
+ [newTile(6), newTile(7), newTile(8)]
+ ];
+
+ // create a clone to be able to test whether
+ // tiles have been destroyed or not
+ var grid = [
+ layer.grid[0].slice(),
+ layer.grid[1].slice(),
+ layer.grid[2].slice()
+ ];
+
+ /*
+ * Test
+ */
+
+ layer.removeExcessTiles(2, 2);
+
+ t.eq(layer.grid.length, 2, 'grid has two rows');
+ t.eq(layer.grid[0].length, 2, 'row #1 has two columns');
+ t.eq(layer.grid[0][0]._id, 1, 'row #1 col #1 includes expected tile');
+ t.eq(layer.grid[0][1]._id, 2, 'row #1 col #2 includes expected tile');
+ t.eq(layer.grid[1].length, 2, 'row #2 has two columns');
+ t.eq(layer.grid[1][0]._id, 4, 'row #2 col #1 includes expected tile');
+ t.eq(layer.grid[1][1]._id, 5, 'row #2 col #2 includes expected tile');
+
+ t.ok(grid[0][0].events != null, 'tile 0,0 not destroyed');
+ t.ok(grid[0][1].events != null, 'tile 0,1 not destroyed');
+ t.ok(grid[0][2].events == null, 'tile 0,2 destroyed');
+ t.ok(grid[1][0].events != null, 'tile 1,0 not destroyed');
+ t.ok(grid[1][1].events != null, 'tile 1,1 not destroyed');
+ t.ok(grid[2][0].events == null, 'tile 2,0 destroyed');
+ t.ok(grid[2][1].events == null, 'tile 2,1 destroyed');
+ t.ok(grid[2][2].events == null, 'tile 2,2 destroyed');
+
+ /*
+ * Tear down
+ */
+
+ map.destroy();
+ }
+
+ function test_addOptions(t) {
+ t.plan(15);
+ var map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2});
+ map.addLayer(layer);
+ t.eq(layer.tileSize, map.getTileSize(), "layer's tile size is equal to the map's tile size");
+ t.ok(layer.removeBackBufferDelay !== 0, "removeBackBufferDelay should not be 0 since we are not singleTile");
+ t.eq(layer.className, "olLayerGrid", "className correct for gridded mode");
+ map.setCenter(new OpenLayers.LonLat(0,0),5);
+ t.eq(layer.grid.length, 8, "Grid rows is correct.");
+ t.eq(layer.grid[0].length, 7, "Grid cols is correct.");
+ t.eq(layer.singleTile, false, "singleTile is false by default");
+ layer.addOptions({singleTile: true});
+ t.eq(layer.removeBackBufferDelay, 0, "removeBackBufferDelay set to 0 since singleTile is true");
+ t.eq(layer.singleTile, true, "singleTile set to true");
+ t.eq(layer.className, "olLayerGridSingleTile", "className correct for singleTile mode");
+ t.eq(layer.grid.length, 1, "Grid rows is correct.");
+ t.eq(layer.grid[0].length, 1, "Grid cols is correct.");
+ t.eq(layer.tileSize, new OpenLayers.Size(748, 823), "tile size changed");
+ layer.addOptions({singleTile: false});
+ t.eq(layer.grid.length, 8, "Grid rows is correct.");
+ t.eq(layer.grid[0].length, 7, "Grid cols is correct.");
+ t.eq(layer.tileSize, map.getTileSize(), "layer's tile size is equal to the map's tile size");
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:499px;height:549px;display:none"></div>
+<div id="map2" style="width:500px;height:550px;display:none"></div>
+<div id="map3" style="width:594px;height:464px;display:none"></div>
+<div id="map4" style="width:768px;height:512px;display:none"></div>
+</body>
+</html>