patch for #487 -- dateline wrapping

git-svn-id: http://svn.openlayers.org/trunk/openlayers@3323 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
euzuro
2007-06-12 18:03:59 +00:00
parent 76f9234e3b
commit f56f136523
13 changed files with 519 additions and 25 deletions

View File

@@ -299,6 +299,32 @@ OpenLayers.LonLat.prototype = {
return equals;
},
/**
* @param {OpenLayers.Bounds} maxExtent
*
* @returns A copy of this lonlat, but wrapped around the "dateline" (as
* specified by the borders of maxExtent)
* @type OpenLayers.LonLat
*/
wrapDateLine: function(maxExtent) {
var newLonLat = this.clone();
if (maxExtent) {
//shift right?
while (newLonLat.lon < maxExtent.left) {
newLonLat.lon += maxExtent.getWidth();
}
//shift left?
while (newLonLat.lon > maxExtent.right) {
newLonLat.lon -= maxExtent.getWidth();
}
}
return newLonLat;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.LonLat"
};
@@ -666,6 +692,50 @@ OpenLayers.Bounds.prototype = {
return quadrant;
},
/**
* @param {OpenLayers.Bounds} maxExtent
* @param {Object} options
* @option {float} leftTolerance Allow for a margin of error with the
* 'left' value of this bound.
* Default is 0
* @option {float} rightTolerance Allow for a margin of error with the
* 'right' value of this bound.
* Default is 0
*
* @returns A copy of this bounds, but wrapped around the "dateline" (as
* specified by the borders of maxExtent). Note that this
* function only returns 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.
* @type OpenLayers.Bounds
*/
wrapDateLine: function(maxExtent, options) {
options = options || new Object();
var leftTolerance = options.leftTolerance || 0;
var rightTolerance = options.rightTolerance || 0;
var newBounds = this.clone();
if (maxExtent) {
//shift right?
while ( newBounds.left < maxExtent.left &&
(newBounds.right - rightTolerance) <= maxExtent.left ) {
newBounds = newBounds.add(maxExtent.getWidth(), 0);
}
//shift left?
while ( (newBounds.left + leftTolerance) >= maxExtent.right &&
newBounds.right > maxExtent.right ) {
newBounds = newBounds.add(-maxExtent.getWidth(), 0);
}
}
return newBounds;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Bounds"
};

View File

@@ -139,6 +139,12 @@ OpenLayers.Layer.prototype = {
/** @type Boolean */
displayOutsideMaxExtent: false,
/** wrapDateLine -- #487 for more info.
*
* @type @Boolean
*/
wrapDateLine: false,
/**
@@ -165,6 +171,10 @@ OpenLayers.Layer.prototype = {
this.events = new OpenLayers.Events(this, this.div,
this.EVENT_TYPES);
}
if (this.wrapDateLine) {
this.displayOutsideMaxExtent = true;
}
},
/**
@@ -616,6 +626,10 @@ OpenLayers.Layer.prototype = {
lonlat = new OpenLayers.LonLat(center.lon + delta_x * res ,
center.lat - delta_y * res);
if (this.wrapDateLine) {
lonlat = lonlat.wrapDateLine(this.maxExtent);
}
} // else { DEBUG STATEMENT }
}
return lonlat;
@@ -641,23 +655,6 @@ OpenLayers.Layer.prototype = {
return px;
},
/**
* Adjusts the extent of a bounds in map units by the layer's gutter
* in pixels.
*
* @param {OpenLayers.Bounds} bounds
* @type OpenLayers.Bounds
* @return A bounds adjusted in height and width by the gutter
*/
adjustBoundsByGutter: function(bounds) {
var mapGutter = this.gutter * this.map.getResolution();
bounds = new OpenLayers.Bounds(bounds.left - mapGutter,
bounds.bottom - mapGutter,
bounds.right + mapGutter,
bounds.top + mapGutter);
return bounds;
},
/**
* Sets the opacity for the entire layer (all images)
* @param {Float} opacity
@@ -681,6 +678,38 @@ OpenLayers.Layer.prototype = {
this.div.style.zIndex = zIdx;
},
/**
* This function will take a bounds, and if wrapDateLine option is set
* on the layer, it will return a bounds which is wrapped around the world.
* We do not wrap for bounds which *cross* the maxExtent.left/right, only
* bounds which are entirely to the left or entirely to the right.
*
* @param {OpenLayers.Bounds} bounds
* @private
*/
adjustBounds: function (bounds) {
if (this.gutter) {
// Adjust the extent of a bounds in map units by the
// layer's gutter in pixels.
var mapGutter = this.gutter * this.map.getResolution();
bounds = new OpenLayers.Bounds(bounds.left - mapGutter,
bounds.bottom - mapGutter,
bounds.right + mapGutter,
bounds.top + mapGutter);
}
if (this.wrapDateLine) {
// wrap around the date line, within the limits of rounding error
var wrappingOptions = {
'rightTolerance':this.getResolution()
};
bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions);
}
return bounds;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer"
};

View File

@@ -49,6 +49,7 @@ OpenLayers.Layer.KaMap.prototype =
* @type String
*/
getURL: function (bounds) {
bounds = this.adjustBounds(bounds);
var mapRes = this.map.getResolution();
var scale = Math.round((this.map.getScale() * 10000)) / 10000;
var pX = Math.round(bounds.left / mapRes);

View File

@@ -87,9 +87,7 @@ OpenLayers.Layer.MapServer.prototype =
* @type String
*/
getURL: function (bounds) {
if(this.gutter) {
bounds = this.adjustBoundsByGutter(bounds);
}
bounds = this.adjustBounds(bounds);
// Make a list, so that getFullRequestString uses literal ","
var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top];

View File

@@ -71,6 +71,7 @@ OpenLayers.Layer.TMS.prototype =
* @type String
*/
getURL: function (bounds) {
bounds = this.adjustBounds(bounds);
var res = this.map.getResolution();
var x = (bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w);
var y = (bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h);

View File

@@ -94,9 +94,7 @@ OpenLayers.Layer.WMS.prototype =
* @type String
*/
getURL: function (bounds) {
if(this.gutter) {
bounds = this.adjustBoundsByGutter(bounds);
}
bounds = this.adjustBounds(bounds);
return this.getFullRequestString(
{BBOX:bounds.toBBOX(),
WIDTH:this.imageSize.w,

View File

@@ -69,6 +69,7 @@ OpenLayers.Layer.WorldWind.prototype =
* @type String
*/
getURL: function (bounds) {
bounds = this.adjustBounds(bounds);
var zoom = this.getZoom();
var extent = this.map.getMaxExtent();
var deg = this.lzd/Math.pow(2,this.getZoom());

View File

@@ -1168,8 +1168,30 @@ OpenLayers.Map.prototype = {
* @param {OpenLayers.Bounds} bounds
*/
zoomToExtent: function(bounds) {
this.setCenter(bounds.getCenterLonLat(),
this.getZoomForExtent(bounds));
var center = bounds.getCenterLonLat();
if (this.baseLayer.wrapDateLine) {
var maxExtent = this.getMaxExtent();
//fix straddling bounds (in the case of a bbox that straddles the
// dateline, it's left and right boundaries will appear backwards.
// we fix this by allowing a right value that is greater than the
// max value at the dateline -- this allows us to pass a valid
// bounds to calculate zoom)
//
bounds = bounds.clone();
while (bounds.right < bounds.left) {
bounds.right += maxExtent.getWidth();
}
//if the bounds was straddling (see above), then the center point
// we got from it was wrong. So we take our new bounds and ask it
// for the center. Because our new bounds is at least partially
// outside the bounds of maxExtent, the new calculated center
// might also be. We don't want to pass a bad center value to
// setCenter, so we have it wrap itself across the date line.
//
center = bounds.getCenterLonLat().wrapDateLine(maxExtent);
}
this.setCenter(center, this.getZoomForExtent(bounds));
},
/** Zoom to the full extent and recenter.