[OpenLayers-Commits] r11535 - in trunk/openlayers: lib/OpenLayers
lib/OpenLayers/Layer tests
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Fri Feb 25 13:02:17 EST 2011
Author: ahocevar
Date: 2011-02-25 10:02:12 -0800 (Fri, 25 Feb 2011)
New Revision: 11535
Modified:
trunk/openlayers/lib/OpenLayers/Layer.js
trunk/openlayers/lib/OpenLayers/Layer/EventPane.js
trunk/openlayers/lib/OpenLayers/Layer/Grid.js
trunk/openlayers/lib/OpenLayers/Map.js
trunk/openlayers/tests/Map.html
Log:
New private movePyPx method to avoid going through all the unnecessary pixel-lonlat conversions. p=elemoine,me (closes #3062)
Modified: trunk/openlayers/lib/OpenLayers/Layer/EventPane.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Layer/EventPane.js 2011-02-25 17:05:19 UTC (rev 11534)
+++ trunk/openlayers/lib/OpenLayers/Layer/EventPane.js 2011-02-25 18:02:12 UTC (rev 11535)
@@ -211,6 +211,22 @@
OpenLayers.Layer.prototype.setZIndex.apply(this, arguments);
this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;
},
+
+ /**
+ * Method: moveByPx
+ * Move the layer based on pixel vector. To be implemented by subclasses.
+ *
+ * Parameters:
+ * dx - {Number} The x coord of the displacement vector.
+ * dy - {Number} The y coord of the displacement vector.
+ */
+ moveByPx: function(dx, dy) {
+ OpenLayers.Layer.prototype.moveByPx.apply(this, arguments);
+
+ if (this.dragPanMapObject) {
+ this.dragPanMapObject(dx, -dy);
+ }
+ },
/**
* Method: moveTo
Modified: trunk/openlayers/lib/OpenLayers/Layer/Grid.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Layer/Grid.js 2011-02-25 17:05:19 UTC (rev 11534)
+++ trunk/openlayers/lib/OpenLayers/Layer/Grid.js 2011-02-25 18:02:12 UTC (rev 11535)
@@ -251,19 +251,37 @@
if (forceReTile || !tilesBounds.containsBounds(bounds, true)) {
this.initGriddedTiles(bounds);
} else {
- // we might have to shift our buffer tiles, schedule
- // that
- if (this.timerId != null) {
- window.clearTimeout(this.timerId);
- }
- this.timerId = window.setTimeout(
- this._moveGriddedTiles,
- this.tileLoadingDelay
- );
+ this.scheduleMoveGriddedTiles();
}
}
}
},
+
+ /**
+ * Method: moveByPx
+ * Move the layer based on pixel vector.
+ *
+ * Parameters:
+ * dx - {Number}
+ * dy - {Number}
+ */
+ moveByPx: function(dx, dy) {
+ this.scheduleMoveGriddedTiles();
+ },
+
+ /**
+ * Method: scheduleMoveGriddedTiles
+ * Schedule the move of tiles.
+ */
+ scheduleMoveGriddedTiles: function() {
+ if (this.timerId != null) {
+ window.clearTimeout(this.timerId);
+ }
+ this.timerId = window.setTimeout(
+ this._moveGriddedTiles,
+ this.tileLoadingDelay
+ );
+ },
/**
* APIMethod: setTileSize
@@ -682,7 +700,9 @@
var shifted = true;
var buffer = this.buffer || 1;
var tlLayer = this.grid[0][0].position;
- var tlViewPort = this.map.getViewPortPxFromLayerPx(tlLayer);
+ var offsetX = parseInt(this.map.layerContainerDiv.style.left);
+ var offsetY = parseInt(this.map.layerContainerDiv.style.top);
+ tlViewPort = tlLayer.add(offsetX, offsetY);
if (tlViewPort.x > -this.tileSize.w * (buffer - 1)) {
this.shiftColumn(true);
} else if (tlViewPort.x < -this.tileSize.w * buffer) {
Modified: trunk/openlayers/lib/OpenLayers/Layer.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Layer.js 2011-02-25 17:05:19 UTC (rev 11534)
+++ trunk/openlayers/lib/OpenLayers/Layer.js 2011-02-25 18:02:12 UTC (rev 11535)
@@ -570,6 +570,17 @@
},
/**
+ * Method: moveByPx
+ * Move the layer based on pixel vector. To be implemented by subclasses.
+ *
+ * Parameters:
+ * dx - {Number} The x coord of the displacement vector.
+ * dy - {Number} The y coord of the displacement vector.
+ */
+ moveByPx: function(dx, dy) {
+ },
+
+ /**
* Method: setMap
* Set the map property for the layer. This is done through an accessor
* so that subclasses can override this and take special action once
@@ -1201,22 +1212,17 @@
*/
getLonLatFromViewPortPx: function (viewPortPx) {
var lonlat = null;
- if (viewPortPx != null) {
- var size = this.map.getSize();
- var center = this.map.getCenter();
- if (center) {
- var res = this.map.getResolution();
-
- var delta_x = viewPortPx.x - (size.w / 2);
- var delta_y = viewPortPx.y - (size.h / 2);
-
- lonlat = new OpenLayers.LonLat(center.lon + delta_x * res ,
- center.lat - delta_y * res);
+ var map = this.map;
+ if (viewPortPx != null && map.minPx) {
+ var res = map.getResolution();
+ var maxExtent = map.getMaxExtent();
+ var lon = (viewPortPx.x - map.minPx.x) * res + maxExtent.left;
+ var lat = (map.minPx.y - viewPortPx.y) * res + maxExtent.top;
+ lonlat = new OpenLayers.LonLat(lon, lat);
- if (this.wrapDateLine) {
- lonlat = lonlat.wrapDateLine(this.maxExtent);
- }
- } // else { DEBUG STATEMENT }
+ if (this.wrapDateLine) {
+ lonlat = lonlat.wrapDateLine(this.maxExtent);
+ }
}
return lonlat;
},
Modified: trunk/openlayers/lib/OpenLayers/Map.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Map.js 2011-02-25 17:05:19 UTC (rev 11534)
+++ trunk/openlayers/lib/OpenLayers/Map.js 2011-02-25 18:02:12 UTC (rev 11535)
@@ -416,6 +416,23 @@
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
* ways to call the map constructor. See the examples below.
@@ -1140,7 +1157,7 @@
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 @@
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 @@
var extent = null;
if (center == null) {
- center = this.getCenter();
+ center = this.getCachedCenter();
}
if (resolution == null) {
resolution = this.getResolution();
@@ -1493,12 +1510,27 @@
*/
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,22 +1559,30 @@
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 @@
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 @@
'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 @@
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 @@
}
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 @@
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 @@
* 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 @@
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.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);
Modified: trunk/openlayers/tests/Map.html
===================================================================
--- trunk/openlayers/tests/Map.html 2011-02-25 17:05:19 UTC (rev 11534)
+++ trunk/openlayers/tests/Map.html 2011-02-25 18:02:12 UTC (rev 11535)
@@ -1323,7 +1323,7 @@
var m = {
'baseLayer': { 'units': {} },
'getSize': function() { return {'w': 10, 'h': 15}; },
- 'getCenter': function() { return {'lon': -5, 'lat': -25}; },
+ 'getCachedCenter': function() { return {'lon': -5, 'lat': -25}; },
'zoomToExtent': function(extent, closest) {
t.ok(extent.equals(g_ExpectedExtent), "extent correctly calculated for zoomToExtent()");
t.ok(closest == g_Closest, "closest correctly passed on to zoomToExtent()");
@@ -1701,6 +1701,41 @@
map.destroy();
}
+ function test_moveByPx(t) {
+ t.plan(8);
+
+ var map = new OpenLayers.Map({
+ div: 'map',
+ maxExtent: new OpenLayers.Bounds(-50, -50, 50, 50),
+ restrictedExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ layers: [
+ new OpenLayers.Layer('name', {isBaseLayer: true})
+ ]
+ });
+ map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));
+
+ // check initial state
+ t.eq(map.layerContainerDiv.style.left, '0px', 'layer container left correct');
+ t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct');
+
+ // move to a valid position
+ map.moveByPx(-455, 455);
+ t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
+ t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+
+ // move outside the max extent
+ map.moveByPx(-4500, 4500);
+ t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
+ t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+
+ // move outside the restricted extent
+ map.moveByPx(-500, 500);
+ t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
+ t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+
+ map.destroy();
+ }
+
</script>
</head>
<body>
More information about the Commits
mailing list