Destroy layer does not clear tile queue
Platform: Widows 8.0 IE10 Openlayers 2.13.1, using WMS layers
Steps to reproduce: Have tiles in a tile queue Call the destroy method on the layer The tile queue will now have tiles in it with many properties being null When one of these tiles are processed an exception occurs
I believe this is due to the order in which a layer is destroyed, the first step is to destroy tiles, which first nullifies the properties on the tiles, this also has the effect of nullifying the properties on the tiles in the tile queue. The prelayerdestory event which is fired after the tile have been destroyed, triggers an event to try and clear the tile queue, but as the tiles now have their layer set to null, it is unable to
As a work around after destroying a layers I manually clear the queue:
var tileCount = this.map.tileManager.tileQueue[this.map.id].length - 1;
for (var j = tileCount; j >= 0; j--) {
var l = this.map.tileManager.tileQueue[this.map.id][j];
if (!l.layer) {
this.map.tileManager.tileQueue[this.map.id].splice(j, 1);
}
}
Thanks @lesma for this detailed description. It also explains the cause for an issue we recently worked around, without being able to find a real fix.
Do you think you can come up with a pull request to fix the order in which things are processed upon destroy?
Thanks @ahocevar ahocevar getting back so quickly
Too be honest don’t think I’m really familiar enough with the openlayers code base to determine exactly what to change to cause the event to fire at the start of the destroy method and have it work.
Very happy to test anything though!
A similar bug occurs when using zoomToExtent inside a changebaselayer event. Using @lesma's hack to flush the queue after the zoom makes everything work.
Thanks :)
I'm seeing this as well switching layouts via Fullscreen API. Monkey patching this with the follwing seems to work but is less than ideal.
drawTilesFromQueue: function(map) {
var tileQueue = this.tileQueue[map.id];
var limit = this.tilesPerFrame;
var animating = map.zoomTween && map.zoomTween.playing;
var tile;
while (!animating && tileQueue.length && limit) {
tile = tileQueue.shift();
if (tile.layer) tile.draw(true);
--limit;
}
}