Push dateline wrapping to intersectsBounds method.

It should simplify things by pushing the dateline wrapping stuff into the intersectsBounds method.
This commit is contained in:
tschaub
2011-09-29 12:21:05 -06:00
parent c53374c797
commit 516914c935
3 changed files with 76 additions and 47 deletions

View File

@@ -428,48 +428,79 @@ OpenLayers.Bounds = OpenLayers.Class({
*
* Parameters:
* bounds - {<OpenLayers.Bounds>} The target bounds.
* options - {Object} Optional parameters.
*
* Acceptable options:
* inclusive - {Boolean} Treat coincident borders as intersecting. Default
* is true. If false, bounds that do not overlap but only touch at the
* border will not be considered as intersecting.
* worldBounds - {<OpenLayers.Bounds>} If a worldBounds is provided, two
* bounds will be considered as intersecting if they intersect when
* shifted to within the world bounds. This applies only to bounds that
* cross or are completely outside the world bounds.
*
* Returns:
* {Boolean} The passed-in bounds object intersects this bounds.
*/
intersectsBounds:function(bounds, inclusive) {
if (inclusive == null) {
inclusive = true;
intersectsBounds:function(bounds, options) {
options = options || {};
if (typeof options === "boolean") {
options = {inclusive: true};
}
if (options.worldBounds) {
var self = this.wrapDateLine(options.worldBounds)
bounds = bounds.wrapDateLine(options.worldBounds);
} else {
self = this;
}
if (options.inclusive == null) {
options.inclusive = true;
}
var intersects = false;
var mightTouch = (
this.left == bounds.right ||
this.right == bounds.left ||
this.top == bounds.bottom ||
this.bottom == bounds.top
self.left == bounds.right ||
self.right == bounds.left ||
self.top == bounds.bottom ||
self.bottom == bounds.top
);
// if the two bounds only touch at an edge, and inclusive is false,
// then the bounds don't *really* intersect.
if (inclusive || !mightTouch) {
if (options.inclusive || !mightTouch) {
// otherwise, if one of the boundaries even partially contains another,
// inclusive of the edges, then they do intersect.
var inBottom = (
((bounds.bottom >= this.bottom) && (bounds.bottom <= this.top)) ||
((this.bottom >= bounds.bottom) && (this.bottom <= bounds.top))
((bounds.bottom >= self.bottom) && (bounds.bottom <= self.top)) ||
((self.bottom >= bounds.bottom) && (self.bottom <= bounds.top))
);
var inTop = (
((bounds.top >= this.bottom) && (bounds.top <= this.top)) ||
((this.top > bounds.bottom) && (this.top < bounds.top))
((bounds.top >= self.bottom) && (bounds.top <= self.top)) ||
((self.top > bounds.bottom) && (self.top < bounds.top))
);
var inLeft = (
((bounds.left >= this.left) && (bounds.left <= this.right)) ||
((this.left >= bounds.left) && (this.left <= bounds.right))
((bounds.left >= self.left) && (bounds.left <= self.right)) ||
((self.left >= bounds.left) && (self.left <= bounds.right))
);
var inRight = (
((bounds.right >= this.left) && (bounds.right <= this.right)) ||
((this.right >= bounds.left) && (this.right <= bounds.right))
((bounds.right >= self.left) && (bounds.right <= self.right)) ||
((self.right >= bounds.left) && (self.right <= bounds.right))
);
intersects = ((inBottom || inTop) && (inLeft || inRight));
}
// document me
if (options.worldBounds && !intersects) {
var world = options.worldBounds;
var width = world.getWidth();
var selfCrosses = !world.containsBounds(self);
var boundsCrosses = !world.containsBounds(bounds);
if (selfCrosses && !boundsCrosses) {
bounds = bounds.add(-width, 0);
intersects = self.intersectsBounds(bounds, {inclusive: options.inclusive});
} else if (boundsCrosses && !selfCrosses) {
self = self.add(-width, 0);
intersects = bounds.intersectsBounds(self, {inclusive: options.inclusive});
}
}
return intersects;
},
@@ -577,8 +608,9 @@ OpenLayers.Bounds = OpenLayers.Class({
* a different bounds value if this bounds is
* *entirely* outside of the maxExtent. If this
* bounds straddles the dateline (is part in/part
* out of maxExtent), the returned bounds will be
* merely a copy of this one.
* out of maxExtent), the returned bounds will always
* cross the left edge of the given maxExtent.
*.
*/
wrapDateLine: function(maxExtent, options) {
options = options || {};
@@ -589,18 +621,24 @@ OpenLayers.Bounds = OpenLayers.Class({
var newBounds = this.clone();
if (maxExtent) {
var width = maxExtent.getWidth();
//shift right?
while ( newBounds.left < maxExtent.left &&
(newBounds.right - rightTolerance) <= maxExtent.left ) {
newBounds = newBounds.add(maxExtent.getWidth(), 0);
newBounds = newBounds.add(width, 0);
}
//shift left?
while ( (newBounds.left + leftTolerance) >= maxExtent.right &&
newBounds.right > maxExtent.right ) {
newBounds = newBounds.add(-maxExtent.getWidth(), 0);
newBounds = newBounds.add(-width, 0);
}
// crosses right? force left
if (newBounds.left < maxExtent.right && newBounds.right > maxExtent.right) {
newBounds = newBounds.add(-width, 0);
}
}
return newBounds;

View File

@@ -175,29 +175,10 @@ OpenLayers.Tile = OpenLayers.Class({
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) {
if (maxExtent.left > maxExtent.right) {
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);
}
}
for (var i=maxExtents.length-1; i>=0; --i) {
if (this.bounds.intersectsBounds(maxExtents[i], false)) {
withinMaxExtent = true;
break;
}
var map = this.layer.map;
var worldBounds = map.baseLayer.wrapDateLine && map.getMaxExtent();
if (this.bounds.intersectsBounds(maxExtent, {inclusive: false, worldBounds: worldBounds})) {
withinMaxExtent = true;
}
}

View File

@@ -22,19 +22,29 @@ var map;
function init(){
map = new OpenLayers.Map('map');
var osm = new OpenLayers.Layer.OSM(
"OSM", null,
var base = new OpenLayers.Layer.WMS("marble",
"http://demo.opengeo.org/geoserver/wms",
{layers: "topp:naturalearth"},
{wrapDateLine: true}
);
var extent = new OpenLayers.Bounds(15849982.183008, -11368938.517442, -14206280.326992, -1350184.3474419);
var extent = new OpenLayers.Bounds(142.3828125,-70.902270266175,233.6171875,-12.039326531729);
var wms = new OpenLayers.Layer.WMS( "world",
"http://demo.opengeo.org/geoserver/wms",
{layers: 'world', transparent: true},
{maxExtent: extent}
);
var poly = extent.toGeometry();
var vector = new OpenLayers.Layer.Vector();
poly.components[0].components.forEach(function(point) {
vector.addFeatures([
new OpenLayers.Feature.Vector(point)
]);
})
map.addLayers([osm, wms]);
map.addLayers([base, wms, vector]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.zoomToExtent(extent);
}