diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 6e2dbf809b..2ca3dec334 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -77,6 +77,18 @@ OpenLayers.Map.prototype = { /** @type int */ zoom: 0, + /** Used to store a unique identifier that changes when the map view + * changes. viewRequestID should be used when adding data asynchronously + * to the map: viewRequestID is incremented when you initiate your + * request (right now during changing of baselayers and changing of zooms). + * It is stored here in the map and also in the data that will be coming + * back asynchronously. Before displaying this data on request completion, + * we check that the viewRequestID of the data is still the same as that + * of the map. Fix for #480 + * + * @type String */ + viewRequestID: 0, + // Options /** @type OpenLayers.Size */ @@ -448,6 +460,11 @@ OpenLayers.Map.prototype = { // set new baselayer and make it visible this.baseLayer = newBaseLayer; + + // Increment viewRequestID since the baseLayer is + // changing. This is used by tiles to check if they should + // draw themselves. + this.viewRequestID++; this.baseLayer.setVisibility(true, noEvent); //redraw all layers @@ -743,6 +760,9 @@ OpenLayers.Map.prototype = { for (var i = 0; i < this.popups.length; i++) { this.popups[i].updatePosition(); } + + // zoom level has changed, increment viewRequestID. + this.viewRequestID++; } var bounds = this.getExtent(); diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js index 6539e933ed..1ba3c94b88 100644 --- a/lib/OpenLayers/Tile/Image.js +++ b/lib/OpenLayers/Tile/Image.js @@ -34,6 +34,7 @@ OpenLayers.Tile.Image.prototype = destroy: function() { if ((this.imgDiv != null) && (this.imgDiv.parentNode == this.layer.div)) { this.layer.div.removeChild(this.imgDiv); + this.imgDiv.map = null; } this.imgDiv = null; OpenLayers.Tile.prototype.destroy.apply(this, arguments); @@ -52,6 +53,8 @@ OpenLayers.Tile.Image.prototype = if (this.imgDiv == null) { this.initImgDiv(); } + + this.imgDiv.viewRequestID = this.layer.map.viewRequestID; this.url = this.layer.getURL(this.bounds); @@ -132,6 +135,10 @@ OpenLayers.Tile.Image.prototype = null, null, null, this.layer.opacity); } + + // we need this reference to check back the viewRequestID + this.imgDiv.map = this.layer.map; + }, /** diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index c275564dce..edf3522595 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -217,8 +217,25 @@ OpenLayers.Util.setOpacity = function(element, opacity) { } OpenLayers.Util.onImageLoad = function() { - this.style.backgroundColor = null; - this.style.display = ""; + // The complex check here is to solve issues described in #480. + // Every time a map view changes, it increments the 'viewRequestID' + // property. As the requests for the images for the new map view are sent + // out, they are tagged with this unique viewRequestID. + // + // If an image has no viewRequestID property set, we display it regardless, + // but if it does have a viewRequestID property, we check that it matches + // the viewRequestID set on the map. + // + // If the viewRequestID on the map has changed, that means that the user + // has changed the map view since this specific request was sent out, and + // therefore this tile does not need to be displayed (so we do not execute + // this code that turns its display on). + // + if (!this.viewRequestID || + (this.viewRequestID == this.map.viewRequestID)) { + this.style.backgroundColor = null; + this.style.display = ""; + } }; OpenLayers.Util.onImageLoadErrorColor = "pink"; diff --git a/tests/grid_inittiles.html b/tests/grid_inittiles.html index 78905d621d..da665d55fc 100644 --- a/tests/grid_inittiles.html +++ b/tests/grid_inittiles.html @@ -11,7 +11,7 @@