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:
@@ -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"
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user