[OpenLayers-Commits] r11376 - in sandbox/ahocevar/layercontainer: lib/OpenLayers lib/OpenLayers/Layer tests

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Wed Feb 23 18:00:17 EST 2011


Author: ahocevar
Date: 2011-02-23 15:00:17 -0800 (Wed, 23 Feb 2011)
New Revision: 11376

Modified:
   sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer.js
   sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer/Grid.js
   sandbox/ahocevar/layercontainer/lib/OpenLayers/Map.js
   sandbox/ahocevar/layercontainer/tests/Map.html
Log:
pixel based panning with moveByPx method - currently not working for EventPane layers and Layer.Bing (likely because of layer.addOptions and/or layer.restrictedMinZoom issues)

Modified: sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer/Grid.js
===================================================================
--- sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer/Grid.js	2011-02-23 22:52:52 UTC (rev 11375)
+++ sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer/Grid.js	2011-02-23 23:00:17 UTC (rev 11376)
@@ -126,6 +126,19 @@
         this._moveGriddedTiles = OpenLayers.Function.bind(
             this.moveGriddedTiles, this
         );
+        
+        this.events.register("move", this, function() {
+            if (!this._forceReTile) {
+                if (this.timerId != null) {
+                    window.clearTimeout(this.timerId);
+                }
+                this.timerId = window.setTimeout(
+                    this._moveGriddedTiles,
+                    this.tileLoadingDelay
+                );
+            }
+            delete this._forceReTile;
+        });
     },
 
     /**
@@ -232,17 +245,8 @@
                 //  then we want to reTile (thus, partial true).  
                 //
                 if (forceReTile || !tilesBounds.containsBounds(bounds, true)) {
+                    this._forceReTile = 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
-                    );
                 }
             }
         }

Modified: sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer.js
===================================================================
--- sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer.js	2011-02-23 22:52:52 UTC (rev 11375)
+++ sandbox/ahocevar/layercontainer/lib/OpenLayers/Layer.js	2011-02-23 23:00:17 UTC (rev 11376)
@@ -77,7 +77,8 @@
      * loadcancel - Triggered when layer loading is canceled.
      * visibilitychanged - Triggered when layer visibility is changed.
      * move - Triggered when layer moves (triggered with every mousemove
-     *     during a drag).
+     *     during a drag). If available, the delta of the movement will be
+     *     passed in an argument as dx and dy properties.
      * moveend - Triggered when layer is done moving, object passed as
      *     argument has a zoomChanged boolean property which tells that the
      *     zoom has changed.
@@ -1200,21 +1201,12 @@
     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); 
-
-                if (this.wrapDateLine) {
-                    lonlat = lonlat.wrapDateLine(this.maxExtent);
-                }
-            } // else { DEBUG STATEMENT }
+            var map = this.map;
+            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);
         }
         return lonlat;
     },
@@ -1234,15 +1226,12 @@
     getViewPortPxFromLonLat: function (lonlat) {
         var px = null; 
         if (lonlat != null) {
-            var res = this.map.resolution;
-            var center = this.map.extent.getCenterLonLat();
-            var lonDelta = lonlat.lon - center.lon;
-            var latDelta = center.lat - lonlat.lat;
-            var halfViewPortWidth = this.map.size.w / 2;
-            var halfViewPortHeight = this.map.size.h / 2;
-            var left = halfViewPortWidth + lonDelta / res;
-            var top = halfViewPortHeight + latDelta / res;
-            px = new OpenLayers.Pixel(left, top);
+            var map = this.map;
+            var res = map.getResolution();
+            var maxExtent = map.getMaxExtent();
+            var x = map.minPx.x + (lonlat.lon - maxExtent.left) / res;
+            var y = map.minPx.y + (maxExtent.top - lonlat.lat) / res;
+            px = new OpenLayers.Pixel(x, y);
         }
         return px;
     },

Modified: sandbox/ahocevar/layercontainer/lib/OpenLayers/Map.js
===================================================================
--- sandbox/ahocevar/layercontainer/lib/OpenLayers/Map.js	2011-02-23 22:52:52 UTC (rev 11375)
+++ sandbox/ahocevar/layercontainer/lib/OpenLayers/Map.js	2011-02-23 23:00:17 UTC (rev 11376)
@@ -220,6 +220,8 @@
      * {<OpenLayers.LonLat>} The current center of the map
      */
     center: null,
+    
+    centerPx: null,
 
     /**
      * Property: resolution
@@ -415,6 +417,22 @@
     paddingForPopups : null,
     
     /**
+     * Property: minPx
+     * {<OpenLayers.Pixel>}
+     *
+     * lower left of maxExtent in viewport pixel space
+     */
+    minPx: null,
+    
+    /**
+     * Property: maxPx
+     * {<OpenLayers.Pixel>}
+     *
+     * top right of maxExtent in viewport pixel space
+     */
+    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.
@@ -1123,7 +1141,7 @@
             if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {
 
                 // preserve center and scale when changing base layers
-                var center = this.center;
+                var center = this.getCachedCenter();
                 var newResolution = OpenLayers.Util.getResolutionFromScale(
                     this.getScale(), newBaseLayer.units
                 );
@@ -1385,7 +1403,7 @@
                     this.layers[i].onMapResize();                
                 }
     
-                var center = this.center;
+                var center = this.getCachedCenter();
     
                 if (this.baseLayer != null && center != null) {
                     var zoom = this.zoom;
@@ -1436,10 +1454,10 @@
         var extent = null;
         
         if (center == null) {
-            center = this.center;
+            center = this.getCachedCenter();
         }                
         if (resolution == null) {
-            resolution = this.resolution;
+            resolution = this.getResolution();
         }
     
         if ((center != null) && (resolution != null)) {
@@ -1476,12 +1494,38 @@
      */
     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.center = this.getLonLatFromViewPortPx(this.centerPx);
+        }
+        return this.center;
+    },
+    
+    /**
+     * Method: getCachedCenterPx
+     *
+     * Returns:
+     * {<OpenLayers.Pixel>}
+     */
+    getCachedCenterPx: function() {
+        if (!this.centerPx) {
+            this.centerPx = this.getViewPortPxFromLonLat(this.center);
+        }
+        return this.centerPx;
+    },
 
     /**
      * APIMethod: getZoom
@@ -1510,23 +1554,31 @@
             animate: true,
             dragging: false
         });
-        
-        // getCenter
-        var centerPx = this.getViewPortPxFromLonLat(this.getCenter());
-
-        // 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);
+        if (options.dragging || this._draggedByMoveByPx) {
+            this.moveByPx(dx, dy);
+            if (options.dragging) {
+                this._draggedByMoveByPx = true
             } else {
-                this.setCenter(newCenterLonLat, null, options.dragging);
-            }    
-        }
+                delete this._draggedByMoveByPx;
+                this.events.triggerEvent("moveend");
+            }
+        } else {
+            // getCenter
+            var centerPx = this.getCachedCenterPx();
 
+            // adjust
+            var newCenterPx = centerPx.add(dx, dy);
+
+            if (!newCenterPx.equals(centerPx)) {
+                var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
+                if (options.animate) {
+                    this.panTo(newCenterLonLat);
+                } else {
+                    this.setCenter(newCenterLonLat, null, options.dragging);
+                }    
+            }
+        }        
+
    },
    
    /** 
@@ -1538,11 +1590,11 @@
      * lonlat - {<OpenLayers.Lonlat>}
      */
     panTo: function(lonlat) {
-        if (this.panMethod && this.extent.scale(this.panRatio).containsLonLat(lonlat)) {
+        if (this.panMethod && this.getCachedExtent().scale(this.panRatio).containsLonLat(lonlat)) {
             if (!this.panTween) {
                 this.panTween = new OpenLayers.Tween(this.panMethod);
             }
-            var center = this.center;
+            var center = this.getCachedCenter();
 
             // center will not change, don't do nothing
             if (lonlat.lon == center.lon &&
@@ -1605,6 +1657,43 @@
             'caller': 'setCenter'
         });
     },
+    
+    /** 
+     * Method: moveByPx
+     * Drag the map by pixels
+     *
+     * Parameters:
+     * dx - {Number}
+     * dy - {Number}
+     */
+    moveByPx: function(dx, dy) {
+        var centerPx = this.getCachedCenterPx().add(dx, dy);
+        var valid = centerPx.x <= this.maxPx.x &&
+                    centerPx.x >= this.minPx.x &&
+                    centerPx.y <= this.maxPx.y &&
+                    centerPx.y >= this.minPx.y;
+        if (valid === true) {
+            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 (dy) {
+                this.layerContainerDiv.style.top =
+                    parseInt(this.layerContainerDiv.style.top) - dy + "px";
+                this.minPx.y -= dy;
+                this.maxPx.y -= dy;
+            }
+            this.events.triggerEvent("move");
+            var layer;
+            for (var i=0, ii=this.layers.length; i<ii; ++i) {
+                layer = this.layers[i];
+                layer.visibility && layer.events.triggerEvent("move");
+            }
+        }
+    },
 
     /**
      * Method: moveTo
@@ -1675,6 +1764,8 @@
             }
         }
 
+        var oldCenter = this.getCachedCenter();
+
         if (zoomChanged) {
             var maxExtent = this.getMaxExtent();
             this.layerContainerDiv.style.width =
@@ -1687,18 +1778,24 @@
         }
         
         var centerChanged =
-            this.isValidLonLat(lonlat) && !lonlat.equals(this.center);
-        if (centerChanged || !this.center) {
-            if (!this.center && !this.isValidLonLat(lonlat)) {
+            this.isValidLonLat(lonlat) && !lonlat.equals(oldCenter);
+        if (centerChanged || !oldCenter) {
+            if (!oldCenter && !this.isValidLonLat(lonlat)) {
                 lonlat = this.maxExtent.getCenterLonLat();
             }
-            this.centerLayerContainer(lonlat);
-            this.center = lonlat;
         }
         
         // if neither center nor zoom will change, no need to do anything
         if (zoomChanged || centerChanged || !dragging) {
 
+            if (zoomChanged || centerChanged) {
+                if (!lonlat) {
+                    lonlat = oldCenter;
+                }
+                this.center = lonlat;
+                this.centerLayerContainer(lonlat);
+            }
+
             if (!this.dragging && !noEvent) {
                 this.events.triggerEvent("movestart");
             }
@@ -1781,14 +1878,16 @@
         var center = this.getMaxExtent().getCenterLonLat();
         var lonDelta = lonlat.lon - center.lon;
         var latDelta = center.lat - lonlat.lat;
-        var halfExtentWidth = parseInt(this.layerContainerDiv.style.width) / 2;
-        var halfExtentHeight = parseInt(this.layerContainerDiv.style.height) / 2;
+        var extentWidth = parseInt(this.layerContainerDiv.style.width);
+        var extentHeight = parseInt(this.layerContainerDiv.style.height);
         var halfViewPortWidth = this.size.w / 2;
         var halfViewPortHeight = this.size.h / 2;
-        var left = halfViewPortWidth - halfExtentWidth - lonDelta / res;
-        var top = halfViewPortHeight - halfExtentHeight - latDelta / res;
+        var left = halfViewPortWidth - extentWidth / 2 - lonDelta / res;
+        var top = halfViewPortHeight - extentHeight / 2 - latDelta / res;
         this.layerContainerDiv.style.left = Math.round(left) + "px";
         this.layerContainerDiv.style.top  = Math.round(top) + "px";
+        this.minPx = new OpenLayers.Pixel(left, top);
+        this.maxPx = new OpenLayers.Pixel(left + extentWidth, top + extentHeight);
     },
 
     /**
@@ -1957,11 +2056,25 @@
      */
     getExtent: function () {
         var extent = null;
-        if (this.extent != null) {
-            extent = this.extent.clone();
+        var cachedExtent = this.getCachedExtent();
+        if (cachedExtent) {
+            extent = cachedExtent.clone();
         }
         return extent;
     },
+    
+    /**
+     * Method: getCachedExtent
+     *
+     * Returns:
+     * {<OpenLayers.Bounds>}
+     */
+    getCachedExtent: function() {
+        if (!this.extent) {
+            this.extent = this.baseLayer.getExtent();
+        }
+        return this.extent;
+    },
 
     /**
      * APIMethod: getResolution
@@ -2202,7 +2315,7 @@
         var size = this.size;
         var w_deg = size.w * res;
         var h_deg = size.h * res;
-        var center = this.center;
+        var center = this.getCachedCenter();
 
         var extent = new OpenLayers.Bounds(center.lon - w_deg / 2,
                                            center.lat - h_deg / 2,
@@ -2314,8 +2427,8 @@
      * {<OpenLayers.Size>} The geodesic size of the pixel in kilometers.
      */
     getGeodesicPixelSize: function(px) {
-        var lonlat = px ? this.getLonLatFromPixel(px) : (this.center ||
-            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);
@@ -2357,9 +2470,10 @@
         if (layerPx != null) {
             var res = this.resolution;
             var center = this.getMaxExtent().getCenterLonLat();
-            var deltaX = Math.round(center.lon / res - this.center.lon / res);
-            var deltaY = Math.round(this.center.lat / res - center.lat / res);
-            viewPortPx = layerPx.add(deltaX, deltaY);
+            var oldCenter = this.getCachedCenter();
+            var dx = Math.round(center.lon / res - oldCenter.lon / res);
+            var dy = Math.round(oldCenter.lat / res - center.lat / res);
+            viewPortPx = layerPx.add(dx, dy);
         }
         return viewPortPx;
     },
@@ -2379,9 +2493,10 @@
         if (viewPortPx != null) {
             var res = this.resolution;
             var center = this.getMaxExtent().getCenterLonLat();
-            var deltaX = Math.round(this.center.lon / res - center.lon / res);
-            var deltaY = Math.round(center.lat / res - this.center.lat / res);
-            layerPx = viewPortPx.add(deltaX, deltaY);
+            var oldCenter = this.getCachedCenter();
+            var dx = Math.round(oldCenter.lon / res - center.lon / res);
+            var dy = Math.round(center.lat / res - oldCenter.lat / res);
+            layerPx = viewPortPx.add(dx, dy);
         }
         return layerPx;
     },

Modified: sandbox/ahocevar/layercontainer/tests/Map.html
===================================================================
--- sandbox/ahocevar/layercontainer/tests/Map.html	2011-02-23 22:52:52 UTC (rev 11375)
+++ sandbox/ahocevar/layercontainer/tests/Map.html	2011-02-23 23:00:17 UTC (rev 11376)
@@ -1316,7 +1316,7 @@
         var m = {
             'baseLayer': { 'units': {} },
             'size': {'w': 10, 'h': 15},
-            'center': {'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()");



More information about the Commits mailing list