From 61a3c2a072cbc3683eb2ae6eb63617057af0ba92 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Tue, 27 Sep 2011 07:37:08 -0600 Subject: [PATCH 1/3] only change bounds when wrapDateLine is true; remove unused variable --- lib/OpenLayers/Layer.js | 5 ++- lib/OpenLayers/Layer/Grid.js | 10 +++++ lib/OpenLayers/Tile.js | 56 +++++++++++++++++++++++--- tests/manual/dateline-smallextent.html | 53 ++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 tests/manual/dateline-smallextent.html diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index 3d2af3f1df..4a6bd4c80d 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -293,7 +293,10 @@ OpenLayers.Layer = OpenLayers.Class({ /** * APIProperty: wrapDateLine - * {Boolean} #487 for more info. + * {Boolean} Wraps the world at the international dateline, so the map can + * be panned infinitely in longitudinal direction. Only use this on the + * base layer, and only if the layer's maxExtent equals the world bounds. + * #487 for more info. */ wrapDateLine: false, diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 0ad307eed9..2cb41a72fc 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -403,6 +403,16 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { * tileoffsetlat, tileoffsetx, tileoffsety */ calculateGridLayout: function(bounds, origin, resolution) { + bounds = bounds.clone(); + var maxExtent = this.map.getMaxExtent(), + width = maxExtent.getWidth(); + // move the bounds one world width to the right until the origin is + // within the world extent + while (bounds.left < maxExtent.left) { + bounds.left += width; + bounds.right += width; + } + var tilelon = resolution * this.tileSize.w; var tilelat = resolution * this.tileSize.h; diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js index 73c710d16a..adfbceb9ba 100644 --- a/lib/OpenLayers/Tile.js +++ b/lib/OpenLayers/Tile.js @@ -103,7 +103,7 @@ OpenLayers.Tile = OpenLayers.Class({ initialize: function(layer, position, bounds, url, size, options) { this.layer = layer; this.position = position.clone(); - this.bounds = bounds.clone(); + this.setBounds(bounds); this.url = url; if (size) { this.size = size.clone(); @@ -171,14 +171,58 @@ OpenLayers.Tile = OpenLayers.Class({ * Returns: * {Boolean} Whether or not the tile should actually be drawn. */ - shouldDraw: function() { - var maxExtent = this.layer.maxExtent; - var withinMaxExtent = (maxExtent && - this.bounds.intersectsBounds(maxExtent, false)); + shouldDraw: function() { + var withinMaxExtent = false, + maxExtent = this.layer.maxExtent; + if (maxExtent) { + // prepare up to 3 versions of the layer's maxExtent, to make sure + // that the intersectsBounds check below catches all cases of + // extents that cross the dateline: + // (1) left bound positive, right bound negative (wrapped) + // (2) left bound positive, right bound positive (exceeding world) + // (3) left bound negative (exceeding world), right bound positive + var maxExtents = [maxExtent]; + if (this.layer.map.baseLayer.wrapDateLine) { + var worldExtentWidth = this.layer.map.getMaxExtent().getWidth(); + maxExtent = this.layer.maxExtent.clone(); + if (maxExtent.left > maxExtent.right) { + maxExtent.left -= worldExtentWidth; + } + maxExtents.push(maxExtent); + maxExtent = this.layer.maxExtent.clone(); + if (maxExtent.right < maxExtent.left) { + maxExtent.right += worldExtentWidth; + } + maxExtents.push(maxExtent); + } + for (var i=maxExtents.length-1; i>=0; --i) { + if (this.bounds.intersectsBounds(maxExtents[i], false)) { + withinMaxExtent = true; + break; + } + } + } return withinMaxExtent || this.layer.displayOutsideMaxExtent; }, + /** + * Method: setBounds + * Sets the bounds on this instance + * + * Parameters: + * bounds {} + */ + setBounds: function(bounds) { + bounds = bounds.clone(); + var maxExtent = this.layer.maxExtent, + worldExtent = this.layer.map.getMaxExtent(); + if (maxExtent && this.layer.map.baseLayer.wrapDateLine) { + bounds = bounds.wrapDateLine(worldExtent); + } + this.bounds = bounds; + }, + /** * Method: moveTo * Reposition the tile. @@ -194,7 +238,7 @@ OpenLayers.Tile = OpenLayers.Class({ redraw = true; } - this.bounds = bounds.clone(); + this.setBounds(bounds); this.position = position.clone(); if (redraw) { this.draw(); diff --git a/tests/manual/dateline-smallextent.html b/tests/manual/dateline-smallextent.html new file mode 100644 index 0000000000..a0797d8773 --- /dev/null +++ b/tests/manual/dateline-smallextent.html @@ -0,0 +1,53 @@ + + + + + + + OpenLayers: Sketch handlers crossing the dateline + + + + + + + + +

OpenLayers overlays crossing the dateline test

+ +

+ The overlay has an extent smaller than the world extent. The base layer + is configured with wrapDateLine set to true. New Zealand and a part of + Australia should always be visible on the map. +

+
+ + From 99d012f32156bd4e86dd4098f16d0a14b700870e Mon Sep 17 00:00:00 2001 From: ahocevar Date: Tue, 27 Sep 2011 07:38:22 -0600 Subject: [PATCH 2/3] only change bounds when wrapDateLine is true; remove unused variable --- lib/OpenLayers/Layer/Grid.js | 18 ++++++++++-------- lib/OpenLayers/Tile.js | 5 ++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 2cb41a72fc..696d6e92cf 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -404,14 +404,16 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ calculateGridLayout: function(bounds, origin, resolution) { bounds = bounds.clone(); - var maxExtent = this.map.getMaxExtent(), - width = maxExtent.getWidth(); - // move the bounds one world width to the right until the origin is - // within the world extent - while (bounds.left < maxExtent.left) { - bounds.left += width; - bounds.right += width; - } + if (this.map.baseLayer.wrapDateLine) { + var maxExtent = this.map.getMaxExtent(), + width = maxExtent.getWidth(); + // move the bounds one world width to the right until the origin is + // within the world extent + while (bounds.left < maxExtent.left) { + bounds.left += width; + bounds.right += width; + } + } var tilelon = resolution * this.tileSize.w; var tilelat = resolution * this.tileSize.h; diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js index adfbceb9ba..3266ce7902 100644 --- a/lib/OpenLayers/Tile.js +++ b/lib/OpenLayers/Tile.js @@ -215,9 +215,8 @@ OpenLayers.Tile = OpenLayers.Class({ */ setBounds: function(bounds) { bounds = bounds.clone(); - var maxExtent = this.layer.maxExtent, - worldExtent = this.layer.map.getMaxExtent(); - if (maxExtent && this.layer.map.baseLayer.wrapDateLine) { + var worldExtent = this.layer.map.getMaxExtent(); + if (this.layer.map.baseLayer.wrapDateLine) { bounds = bounds.wrapDateLine(worldExtent); } this.bounds = bounds; From dfdcdb8d3341d4e921dd09394ddd319b0bbfead5 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Wed, 28 Sep 2011 07:41:00 -0600 Subject: [PATCH 3/3] improvements suggested by bartvde --- lib/OpenLayers/Tile.js | 18 ++++++++---------- tests/manual/dateline-smallextent.html | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js index 3266ce7902..bc7c1baf6f 100644 --- a/lib/OpenLayers/Tile.js +++ b/lib/OpenLayers/Tile.js @@ -183,17 +183,15 @@ OpenLayers.Tile = OpenLayers.Class({ // (3) left bound negative (exceeding world), right bound positive var maxExtents = [maxExtent]; if (this.layer.map.baseLayer.wrapDateLine) { - var worldExtentWidth = this.layer.map.getMaxExtent().getWidth(); - maxExtent = this.layer.maxExtent.clone(); if (maxExtent.left > maxExtent.right) { - maxExtent.left -= worldExtentWidth; + var worldWidth = this.layer.map.getMaxExtent().getWidth(); + maxExtent = this.layer.maxExtent.clone(); + maxExtent.left -= worldWidth; + maxExtents.push(maxExtent); + maxExtent = this.layer.maxExtent.clone(); + maxExtent.right += worldWidth; + maxExtents.push(maxExtent); } - maxExtents.push(maxExtent); - maxExtent = this.layer.maxExtent.clone(); - if (maxExtent.right < maxExtent.left) { - maxExtent.right += worldExtentWidth; - } - maxExtents.push(maxExtent); } for (var i=maxExtents.length-1; i>=0; --i) { if (this.bounds.intersectsBounds(maxExtents[i], false)) { @@ -215,8 +213,8 @@ OpenLayers.Tile = OpenLayers.Class({ */ setBounds: function(bounds) { bounds = bounds.clone(); - var worldExtent = this.layer.map.getMaxExtent(); if (this.layer.map.baseLayer.wrapDateLine) { + var worldExtent = this.layer.map.getMaxExtent(); bounds = bounds.wrapDateLine(worldExtent); } this.bounds = bounds; diff --git a/tests/manual/dateline-smallextent.html b/tests/manual/dateline-smallextent.html index a0797d8773..ed80a8a9e7 100644 --- a/tests/manual/dateline-smallextent.html +++ b/tests/manual/dateline-smallextent.html @@ -28,7 +28,7 @@ function init(){ ); var extent = new OpenLayers.Bounds(15849982.183008, -11368938.517442, -14206280.326992, -1350184.3474419); var wms = new OpenLayers.Layer.WMS( "world", - "/geoserver/wms", + "http://demo.opengeo.org/geoserver/wms", {layers: 'world', transparent: true}, {maxExtent: extent} );