diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 7d2d6ced5f..adf516364f 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -779,15 +779,36 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { //determine new tile bounds var center = bounds.getCenterLonLat(); + var tileWidth = bounds.getWidth() * this.ratio; var tileHeight = bounds.getHeight() * this.ratio; - + var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth/2), center.lat - (tileHeight/2), center.lon + (tileWidth/2), center.lat + (tileHeight/2)); - + + // adjust tile bounds so they do not exceed maxExtent, except when the + // layer's maxExtent equals the world bounds or displayOutsideMaxExtent + // is set to true + var ignoreMaxExtent = + (this.map.baseLayer.wrapDateLine && + this.maxExtent.equals(this.map.getMaxExtent())) || + this.displayOutsideMaxExtent; + if(!ignoreMaxExtent) { + tileBounds.bottom = Math.max(this.maxExtent.bottom, tileBounds.bottom); + tileBounds.top = Math.min(this.maxExtent.top, tileBounds.top); + tileBounds.left = Math.max(this.maxExtent.left, tileBounds.left); + tileBounds.right = Math.min(this.maxExtent.right, tileBounds.right); + tileWidth = tileBounds.getWidth(); + tileHeight = tileBounds.getHeight(); + } + var resolution = this.map.getResolution(), + size = this.tileSize; + size.w = (tileWidth / resolution) | 0; + size.h = (tileHeight / resolution) | 0; + var px = this.map.getLayerPxFromLonLat({ lon: tileBounds.left, lat: tileBounds.top diff --git a/tests/Layer/Grid.html b/tests/Layer/Grid.html index d2f85cb5ea..1635268b8b 100644 --- a/tests/Layer/Grid.html +++ b/tests/Layer/Grid.html @@ -449,7 +449,7 @@ } function test_Layer_Grid_initSingleTile(t) { - t.plan( 11 ); + t.plan( 24 ); layer = new OpenLayers.Layer.Grid(name, url, params, { singleTile: true, @@ -462,14 +462,17 @@ var desiredUL = new OpenLayers.LonLat(-40,145); translatedPX = {}; + layer.tileSize = new OpenLayers.Size(); layer.map = { + baseLayer: {wrapDateLine: true}, + getMaxExtent: function() { return new OpenLayers.Bounds(-180,-90,180,90); }, getLayerPxFromLonLat: function(ul) { t.ok(ul.lon === desiredUL.lon && ul.lat === desiredUL.lat, "correct ul passed to translation"); return translatedPX; }, - getResolution: function() { - } - } + getResolution:function(){return 1;} + }; + layer.maxExtent = layer.map.getMaxExtent(); var newTile = { draw: function() { @@ -499,10 +502,58 @@ 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); - + layer.initSingleTile(bounds); + + //test maxExtent restrictions + //reset grid + layer.grid = []; + //more useful mocks + layer.map = { + baseLayer: {wrapDateLine: false}, + getMaxExtent: function() { return new OpenLayers.Bounds(-180,-90,180,90); }, + getLayerPxFromLonLat: function(ul) { + return { + x:ul.lon, + y:ul.lat + }; + }, + getResolution: function(){return 1;} + }; + layer.addTile = function(tileBounds, px) { + t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to addTile to create new tile"); + t.ok(px.x == translatedPX.x && px.y == translatedPX.y, "correct tile px passed to addTile to create new tile"); + return newTile; + }; + tile = { + moveTo: function(tileBounds, px) { + t.ok(tileBounds.equals(desiredTileBounds), "correct tile bounds passed to tile.moveTo()"); + t.ok(px.x == translatedPX.x && px.y == translatedPX.y, "correct tile px passed to tile.moveTo()"); + } + }; + //test bound fully contains the maxExtent + //tile bounds -10,10,50,100 -> apply ratio -40,-35,80,145 + layer.maxExtent = new OpenLayers.Bounds(0,20,40,90); + desiredTileBounds = new OpenLayers.Bounds(0,20,40,90); + translatedPX = {x:0,y:90}; + layer.initSingleTile(bounds); + + //test bound overlaps the maxExtent + bounds = new OpenLayers.Bounds(-10,10,50,100); + //with ratio applied tile bounds are -40,-35,80,145 + layer.maxExtent = new OpenLayers.Bounds(-50,20,40,150); + desiredTileBounds = new OpenLayers.Bounds(-40,20,40,145); + translatedPX = {x:-40,y:145}; + layer.grid = [[ tile ]]; + layer.initSingleTile(bounds); + t.ok(layer.tileSize.equals(new OpenLayers.Size(80, 125)), "tileSize correct."); + + //test bounds where ratio will be applied on all edges + layer.displayOutsideMaxExtent = true; + desiredTileBounds = new OpenLayers.Bounds(-40,-35,80,145); + layer.initSingleTile(bounds); + t.ok(layer.tileSize.equals(new OpenLayers.Size(120, 180)), "tileSize correct.") } function test_Layer_Grid_addTileMonitoringHooks(t) {