New private movePyPx method to avoid going through all the unnecessary pixel-lonlat conversions. p=elemoine,me (closes #3062)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11535 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
ahocevar
2011-02-25 18:02:12 +00:00
parent 4c40f7c11f
commit 2d5f29c55e
5 changed files with 262 additions and 59 deletions

View File

@@ -415,6 +415,23 @@ OpenLayers.Map = OpenLayers.Class({
*/
paddingForPopups : null,
/**
* Property: minPx
* {<OpenLayers.Pixel>} Lower left of maxExtent in viewport pixel space.
* Used to verify in moveByPx that the new location we're moving to
* is valid. It is also used in the getLonLatFromViewPortPx function
* of Layer.
*/
minPx: null,
/**
* Property: maxPx
* {<OpenLayers.Pixel>} Top right of maxExtent in viewport pixel space.
* Used to verify in moveByPx that the new location we're moving to
* is valid.
*/
maxPx: null,
/**
* Constructor: OpenLayers.Map
* Constructor for a new OpenLayers.Map instance. There are two possible
@@ -1140,7 +1157,7 @@ OpenLayers.Map = OpenLayers.Class({
if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {
// preserve center and scale when changing base layers
var center = this.getCenter();
var center = this.getCachedCenter();
var newResolution = OpenLayers.Util.getResolutionFromScale(
this.getScale(), newBaseLayer.units
);
@@ -1402,7 +1419,7 @@ OpenLayers.Map = OpenLayers.Class({
this.layers[i].onMapResize();
}
var center = this.getCenter();
var center = this.getCachedCenter();
if (this.baseLayer != null && center != null) {
var zoom = this.getZoom();
@@ -1453,7 +1470,7 @@ OpenLayers.Map = OpenLayers.Class({
var extent = null;
if (center == null) {
center = this.getCenter();
center = this.getCachedCenter();
}
if (resolution == null) {
resolution = this.getResolution();
@@ -1493,12 +1510,27 @@ OpenLayers.Map = OpenLayers.Class({
*/
getCenter: function () {
var center = null;
if (this.center) {
center = this.center.clone();
var cachedCenter = this.getCachedCenter();
if (cachedCenter) {
center = cachedCenter.clone();
}
return center;
},
/**
* Method: getCachedCenter
*
* Returns:
* {<OpenLayers.LonLat>}
*/
getCachedCenter: function() {
if (!this.center && this.size) {
this.center = this.getLonLatFromViewPortPx(
new OpenLayers.Pixel(this.size.w / 2, this.size.h / 2)
);
}
return this.center;
},
/**
* APIMethod: getZoom
@@ -1527,21 +1559,29 @@ OpenLayers.Map = OpenLayers.Class({
animate: true,
dragging: false
});
// getCenter
var centerPx = this.getViewPortPxFromLonLat(this.getCenter());
if (options.dragging) {
if (dx != 0 || dy != 0) {
this.moveByPx(dx, dy);
}
} else {
// if we don't have a center, we were using moveByPx previously
var forceSetCenter = !this.center;
// getCenter
var centerPx = this.getViewPortPxFromLonLat(this.getCachedCenter());
// adjust
var newCenterPx = centerPx.add(dx, dy);
// only call setCenter if not dragging or there has been a change
if (!options.dragging || !newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
if (options.animate) {
this.panTo(newCenterLonLat);
} else {
this.setCenter(newCenterLonLat, null, options.dragging);
}
}
// adjust
var newCenterPx = centerPx.add(dx, dy);
if (forceSetCenter || !newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
if (options.animate) {
this.panTo(newCenterLonLat);
} else {
this.setCenter(newCenterLonLat, null, options.dragging);
}
}
}
},
@@ -1558,7 +1598,7 @@ OpenLayers.Map = OpenLayers.Class({
if (!this.panTween) {
this.panTween = new OpenLayers.Tween(this.panMethod);
}
var center = this.getCenter();
var center = this.getCachedCenter();
// center will not change, don't do nothing
if (lonlat.lon == center.lon &&
@@ -1621,6 +1661,71 @@ OpenLayers.Map = OpenLayers.Class({
'caller': 'setCenter'
});
},
/**
* Method: moveByPx
* Drag the map by pixels.
*
* Parameters:
* dx - {Number}
* dy - {Number}
*/
moveByPx: function(dx, dy) {
dx = Math.round(dx);
dy = Math.round(dy);
var hw = this.size.w / 2;
var hh = this.size.h / 2;
var x = hw + dx;
var y = hh + dy;
var valid = y <= this.maxPx.y &&
y >= this.minPx.y;
var minX, maxX;
if (this.baseLayer.wrapDateLine === true) {
minX = this.minPx.x, maxX = this.maxPx.x;
} else {
valid = valid &&
x <= this.maxPx.x &&
x >= this.minPx.x;
}
if (this.restrictedExtent && valid) {
valid = !(this.maxPx.x - x < hw ||
x - this.minPx.x < hw ||
this.maxPx.y - y < hh ||
y - this.minPx.y < hh);
}
if (valid) {
this.center = null;
if (dx) {
this.layerContainerDiv.style.left =
parseInt(this.layerContainerDiv.style.left) - dx + "px";
this.minPx.x -= dx;
this.maxPx.x -= dx;
if (this.baseLayer.wrapDateLine === true) {
if (this.maxPx.x > maxX) {
this.maxPx.x -= (maxX - minX);
};
if (this.minPx.x < minX) {
this.minPx.x += (maxX - minX);
};
}
}
if (dy) {
this.layerContainerDiv.style.top =
parseInt(this.layerContainerDiv.style.top) - dy + "px";
this.minPx.y -= dy;
this.maxPx.y -= dy;
}
var layer, i, len;
for (i=0, len=this.layers.length; i<len; ++i) {
layer = this.layers[i];
if (layer.visibility) {
layer.moveByPx(dx, dy);
layer.events.triggerEvent("move");
}
}
this.events.triggerEvent("move");
}
},
/**
* Method: moveTo
@@ -1651,14 +1756,14 @@ OpenLayers.Map = OpenLayers.Class({
this.panTween.stop();
}
if (!this.center && !this.isValidLonLat(lonlat)) {
if (!this.getCachedCenter() && !this.isValidLonLat(lonlat)) {
lonlat = this.maxExtent.getCenterLonLat();
}
if(this.restrictedExtent != null) {
// In 3.0, decide if we want to change interpretation of maxExtent.
if(lonlat == null) {
lonlat = this.getCenter();
lonlat = this.center;
}
if(zoom == null) {
zoom = this.getZoom();
@@ -1705,7 +1810,7 @@ OpenLayers.Map = OpenLayers.Class({
}
if (centerChanged) {
if ((!zoomChanged) && (this.center)) {
if (!zoomChanged && this.center) {
// if zoom hasnt changed, just slide layerContainer
// (must be done before setting this.center to new value)
this.centerLayerContainer(lonlat);
@@ -1713,16 +1818,28 @@ OpenLayers.Map = OpenLayers.Class({
this.center = lonlat.clone();
}
var res = zoomChanged ?
this.getResolutionForZoom(zoom) : this.getResolution();
// (re)set the layerContainerDiv's location
if ((zoomChanged) || (this.layerContainerOrigin == null)) {
this.layerContainerOrigin = this.center.clone();
if (zoomChanged || this.layerContainerOrigin == null) {
this.layerContainerOrigin = this.getCachedCenter();
this.layerContainerDiv.style.left = "0px";
this.layerContainerDiv.style.top = "0px";
var maxExtent = this.getMaxExtent({restricted: true});
var maxExtentCenter = maxExtent.getCenterLonLat();
var lonDelta = this.center.lon - maxExtentCenter.lon;
var latDelta = maxExtentCenter.lat - this.center.lat;
var extentWidth = Math.round(maxExtent.getWidth() / res);
var extentHeight = Math.round(maxExtent.getHeight() / res);
var left = (this.size.w - extentWidth) / 2 - lonDelta / res;
var top = (this.size.h - extentHeight) / 2 - latDelta / res;
this.minPx = new OpenLayers.Pixel(left, top);
this.maxPx = new OpenLayers.Pixel(left + extentWidth, top + extentHeight);
}
if (zoomChanged) {
this.zoom = zoom;
this.resolution = this.getResolutionForZoom(zoom);
this.resolution = res;
// zoom level has changed, increment viewRequestID.
this.viewRequestID++;
}
@@ -1804,14 +1921,23 @@ OpenLayers.Map = OpenLayers.Class({
* lonlat - {<OpenLayers.LonLat>}
*/
centerLayerContainer: function (lonlat) {
var originPx = this.getViewPortPxFromLonLat(this.layerContainerOrigin);
var newPx = this.getViewPortPxFromLonLat(lonlat);
if ((originPx != null) && (newPx != null)) {
this.layerContainerDiv.style.left = Math.round(originPx.x - newPx.x) + "px";
this.layerContainerDiv.style.top = Math.round(originPx.y - newPx.y) + "px";
}
var oldLeft = parseInt(this.layerContainerDiv.style.left);
var oldTop = parseInt(this.layerContainerDiv.style.top);
var newLeft = Math.round(originPx.x - newPx.x);
var newTop = Math.round(originPx.y - newPx.y);
this.layerContainerDiv.style.left = newLeft + "px";
this.layerContainerDiv.style.top = newTop + "px";
var dx = oldLeft - newLeft;
var dy = oldTop - newTop;
this.minPx.x -= dx;
this.maxPx.x -= dx;
this.minPx.y -= dy;
this.maxPx.y -= dy;
}
},
/**
@@ -2225,7 +2351,7 @@ OpenLayers.Map = OpenLayers.Class({
var size = this.getSize();
var w_deg = size.w * res;
var h_deg = size.h * res;
var center = this.getCenter();
var center = this.getCachedCenter();
var extent = new OpenLayers.Bounds(center.lon - w_deg / 2,
center.lat - h_deg / 2,
@@ -2337,8 +2463,8 @@ OpenLayers.Map = OpenLayers.Class({
* {<OpenLayers.Size>} The geodesic size of the pixel in kilometers.
*/
getGeodesicPixelSize: function(px) {
var lonlat = px ? this.getLonLatFromPixel(px) : (this.getCenter() ||
new OpenLayers.LonLat(0, 0));
var lonlat = px ? this.getLonLatFromPixel(px) : (
this.getCachedCenter() || new OpenLayers.LonLat(0, 0));
var res = this.getResolution();
var left = lonlat.add(-res / 2, 0);
var right = lonlat.add(res / 2, 0);