From b2d7cf110b18b9fbc1efce0d2a6b6c93a3581c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Tue, 21 Jun 2016 15:27:44 +0200 Subject: [PATCH] Fix #4039: Use different L.Bounds for "marking as prunable" and loading tiles (#4650) * Fix #4039: Use different L.Bounds for "marking as prunable" and loading tiles. * configurable tile pruning tests * using spy for testing load did not happen --- spec/suites/layer/tile/GridLayerSpec.js | 137 ++++++++++++++++++++++++ src/layer/tile/GridLayer.js | 16 ++- 2 files changed, 150 insertions(+), 3 deletions(-) diff --git a/spec/suites/layer/tile/GridLayerSpec.js b/spec/suites/layer/tile/GridLayerSpec.js index fd1b15274..0d1cf21ba 100644 --- a/spec/suites/layer/tile/GridLayerSpec.js +++ b/spec/suites/layer/tile/GridLayerSpec.js @@ -679,4 +679,141 @@ describe('GridLayer', function () { }); + describe("configurable tile pruning", function () { + var clock, grid, counts; + + beforeEach(function () { + clock = sinon.useFakeTimers(); + + grid = L.gridLayer({ + attribution: 'Grid Layer', + tileSize: L.point(256, 256) + }); + + grid.createTile = function (coords) { + var tile = document.createElement('div'); + tile.innerHTML = [coords.x, coords.y, coords.z].join(', '); + tile.style.border = '2px solid red'; + return tile; + }; + + counts = { + tileload: 0, + tileerror: 0, + tileloadstart: 0, + tileunload: 0 + }; + + grid.on('tileload tileunload tileerror tileloadstart', function (ev) { +// console.log(ev.type); + counts[ev.type]++; + }); +// grid.on('tileunload', function (ev) { +// console.log(ev.type, ev.coords, counts); +// }); + + map.options.fadeAnimation = false; + map.options.zoomAnimation = false; + }); + + afterEach(function () { + clock.restore(); + grid.off(); + grid = undefined; + counts = undefined; + }); + + it("Loads map, moves forth by 512 px, keepBuffer = 0", function (done) { + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(16); + expect(counts.tileload).to.be(16); + expect(counts.tileunload).to.be(0); + grid.off('load'); + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(28); + expect(counts.tileload).to.be(28); + expect(counts.tileunload).to.be(12); + done(); + }); + + map.panBy([512, 512], {animate: false}); + clock.tick(250); + }); + + grid.options.keepBuffer = 0; + + map.addLayer(grid).setView([0, 0], 10); + clock.tick(250); + }); + + it("Loads map, moves forth and back by 512 px, keepBuffer = 0", function (done) { + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(16); + expect(counts.tileload).to.be(16); + expect(counts.tileunload).to.be(0); + grid.off('load'); + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(28); + expect(counts.tileload).to.be(28); + expect(counts.tileunload).to.be(12); + + grid.off('load'); + grid.on('load', function () { + expect(counts.tileloadstart).to.be(40); + expect(counts.tileload).to.be(40); + expect(counts.tileunload).to.be(24); + done(); + }); + + map.panBy([-512, -512], {animate: false}); + clock.tick(250); + }); + + map.panBy([512, 512], {animate: false}); + clock.tick(250); + }); + + grid.options.keepBuffer = 0; + + map.addLayer(grid).setView([0, 0], 10); + clock.tick(250); + }); + + it("Loads map, moves forth and back by 512 px, default keepBuffer", function (done) { + + var spy = sinon.spy(); + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(16); + expect(counts.tileload).to.be(16); + expect(counts.tileunload).to.be(0); + grid.off('load'); + + grid.on('load', function () { + expect(counts.tileloadstart).to.be(28); + expect(counts.tileload).to.be(28); + expect(counts.tileunload).to.be(0); + grid.off('load'); + + grid.addEventListener('load', spy); + + map.panBy([-512, -512], {animate: false}); + clock.tick(250); + + expect(spy.called).to.be(false); + done(); + }); + + map.panBy([512, 512], {animate: false}); + clock.tick(250); + }); + + map.addLayer(grid).setView([0, 0], 10); + clock.tick(250); + }); + }); }); diff --git a/src/layer/tile/GridLayer.js b/src/layer/tile/GridLayer.js index c011bcdc1..885a71b34 100644 --- a/src/layer/tile/GridLayer.js +++ b/src/layer/tile/GridLayer.js @@ -120,7 +120,11 @@ L.GridLayer = L.Layer.extend({ // @option className: String = '' // A custom class name to assign to the tile layer. Empty by default. - className: '' + className: '', + + // @option keepBuffer: Number = 2 + // When panning the map, keep this many rows and columns of tiles before unloading them. + keepBuffer: 2 }, initialize: function (options) { @@ -595,10 +599,16 @@ L.GridLayer = L.Layer.extend({ var pixelBounds = this._getTiledPixelBounds(center), tileRange = this._pxBoundsToTileRange(pixelBounds), tileCenter = tileRange.getCenter(), - queue = []; + queue = [], + margin = this.options.keepBuffer, + noPruneRange = new L.Bounds(tileRange.getBottomLeft().subtract([margin, -margin]), + tileRange.getTopRight().add([margin, -margin])); for (var key in this._tiles) { - this._tiles[key].current = false; + var c = this._tiles[key].coords; + if (c.z !== this._tileZoom || !noPruneRange.contains(L.point(c.x, c.y))) { + this._tiles[key].current = false; + } } // _update just loads more tiles. If the tile zoom level differs too much