Merge pull request #3129 from Leaflet/tile-reloading

Clean up tile loading
This commit is contained in:
Vladimir Agafonkin 2015-01-13 13:14:40 +02:00
commit e6796fadb8
2 changed files with 47 additions and 43 deletions

View File

@ -32,11 +32,7 @@ L.GridLayer = L.Layer.extend({
this._pruneTiles = L.Util.throttle(this._pruneTiles, 200, this); this._pruneTiles = L.Util.throttle(this._pruneTiles, 200, this);
this._levels = {}; this._levels = {};
this._tiles = {}; this._tiles = {};
this._loaded = {};
this._retain = {};
this._tilesToLoad = 0;
this._reset(); this._reset();
this._update(); this._update();
@ -156,7 +152,7 @@ L.GridLayer = L.Layer.extend({
if (L.Browser.ielt9) { if (L.Browser.ielt9) {
// IE doesn't inherit filter opacity properly, so we're forced to set it on tiles // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
for (var i in this._tiles) { for (var i in this._tiles) {
L.DomUtil.setOpacity(this._tiles[i], opacity); L.DomUtil.setOpacity(this._tiles[i].el, opacity);
} }
} else { } else {
L.DomUtil.setOpacity(this._container, opacity); L.DomUtil.setOpacity(this._container, opacity);
@ -205,31 +201,35 @@ L.GridLayer = L.Layer.extend({
if (!this._map) { return; } if (!this._map) { return; }
this._retain = {};
var bounds = this._map.getBounds(), var bounds = this._map.getBounds(),
z = this._tileZoom, z = this._tileZoom,
range = this._getTileRange(bounds, z), range = this._getTileRange(bounds, z),
i, j, key, found; i, j, key, tile, found;
for (key in this._tiles) {
this._tiles[key].retain = false;
}
for (i = range.min.x; i <= range.max.x; i++) { for (i = range.min.x; i <= range.max.x; i++) {
for (j = range.min.y; j <= range.max.y; j++) { for (j = range.min.y; j <= range.max.y; j++) {
key = i + ':' + j + ':' + z; key = i + ':' + j + ':' + z;
tile = this._tiles[key];
this._retain[key] = true; if (!tile) { continue; }
tile.retain = true;
if (!this._loaded[key]) { if (!tile.loaded) {
found = this._retainParent(i, j, z, z - 5) || this._retainChildren(i, j, z, z + 2); found = this._retainParent(i, j, z, z - 5) || this._retainChildren(i, j, z, z + 2);
} }
} }
} }
for (key in this._tiles) { for (key in this._tiles) {
if (!this._retain[key]) { tile = this._tiles[key];
if (!this._loaded[key]) { if (!tile.retain) {
if (!tile.loaded) {
this._removeTile(key); this._removeTile(key);
this._tilesToLoad--;
} else if (this._map._fadeAnimated) { } else if (this._map._fadeAnimated) {
setTimeout(L.bind(this._deferRemove, this, key), 250); setTimeout(L.bind(this._deferRemove, this, key), 250);
} else { } else {
@ -243,11 +243,11 @@ L.GridLayer = L.Layer.extend({
for (var key in this._tiles) { for (var key in this._tiles) {
this._removeTile(key); this._removeTile(key);
} }
this._tilesToLoad = 0;
}, },
_deferRemove: function (key) { _deferRemove: function (key) {
if (!this._retain[key]) { var tile = this._tiles[key];
if (tile && !tile.retain) {
this._removeTile(key); this._removeTile(key);
} }
}, },
@ -257,10 +257,11 @@ L.GridLayer = L.Layer.extend({
y2 = Math.floor(y / 2), y2 = Math.floor(y / 2),
z2 = z - 1; z2 = z - 1;
var key = x2 + ':' + y2 + ':' + z2; var key = x2 + ':' + y2 + ':' + z2,
tile = this._tiles[key];
if (this._loaded[key]) { if (tile && tile.loaded) {
this._retain[key] = true; tile.retain = true;
return true; return true;
} else if (z2 > minZoom) { } else if (z2 > minZoom) {
@ -275,10 +276,11 @@ L.GridLayer = L.Layer.extend({
for (var i = 2 * x; i < 2 * x + 2; i++) { for (var i = 2 * x; i < 2 * x + 2; i++) {
for (var j = 2 * y; j < 2 * y + 2; j++) { for (var j = 2 * y; j < 2 * y + 2; j++) {
var key = i + ':' + j + ':' + (z + 1); var key = i + ':' + j + ':' + (z + 1),
tile = this._tiles[key];
if (this._loaded[key]) { if (tile && tile.loaded) {
this._retain[key] = true; tile.retain = true;
} else if (z + 1 < maxZoom) { } else if (z + 1 < maxZoom) {
this._retainChildren(i, j, z + 1, maxZoom); this._retainChildren(i, j, z + 1, maxZoom);
@ -360,6 +362,7 @@ L.GridLayer = L.Layer.extend({
} }
this._addTiles(bounds); this._addTiles(bounds);
this._pruneTiles();
}, },
// tile coordinates range for particular geo bounds and zoom // tile coordinates range for particular geo bounds and zoom
@ -395,28 +398,21 @@ L.GridLayer = L.Layer.extend({
return a.distanceTo(center) - b.distanceTo(center); return a.distanceTo(center) - b.distanceTo(center);
}); });
var tilesToLoad = queue.length; if (queue.length !== 0) {
if (tilesToLoad !== 0) {
// if its the first batch of tiles to load // if its the first batch of tiles to load
if (!this._tilesToLoad) { if (this._tilesToLoad() === 0) {
this.fire('loading'); this.fire('loading');
} }
this._tilesToLoad += tilesToLoad;
// create DOM fragment to append tiles in one batch // create DOM fragment to append tiles in one batch
var fragment = document.createDocumentFragment(); var fragment = document.createDocumentFragment();
for (i = 0; i < tilesToLoad; i++) { for (i = 0; i < queue.length; i++) {
this._addTile(queue[i], fragment); this._addTile(queue[i], fragment);
} }
this._level.el.appendChild(fragment); this._level.el.appendChild(fragment);
} }
this._pruneTiles();
}, },
_isValidTile: function (coords) { _isValidTile: function (coords) {
@ -482,13 +478,12 @@ L.GridLayer = L.Layer.extend({
var tile = this._tiles[key]; var tile = this._tiles[key];
if (!tile) { return; } if (!tile) { return; }
L.DomUtil.remove(tile); L.DomUtil.remove(tile.el);
delete this._tiles[key]; delete this._tiles[key];
delete this._loaded[key];
this.fire('tileunload', { this.fire('tileunload', {
tile: tile, tile: tile.el,
coords: this._keyToTileCoords(key) coords: this._keyToTileCoords(key)
}); });
}, },
@ -534,7 +529,9 @@ L.GridLayer = L.Layer.extend({
L.DomUtil.setPosition(tile, tilePos, true); L.DomUtil.setPosition(tile, tilePos, true);
// save tile in cache // save tile in cache
this._tiles[key] = tile; this._tiles[key] = {
el: tile
};
container.appendChild(tile); container.appendChild(tile);
this.fire('tileloadstart', { this.fire('tileloadstart', {
@ -554,21 +551,20 @@ L.GridLayer = L.Layer.extend({
var key = this._tileCoordsToKey(coords); var key = this._tileCoordsToKey(coords);
if (!this._tiles[key]) { return; } tile = this._tiles[key];
if (!tile) { return; }
this._loaded[key] = true; tile.loaded = true;
this._pruneTiles(); this._pruneTiles();
L.DomUtil.addClass(tile, 'leaflet-tile-loaded'); L.DomUtil.addClass(tile.el, 'leaflet-tile-loaded');
this.fire('tileload', { this.fire('tileload', {
tile: tile, tile: tile.el,
coords: coords coords: coords
}); });
this._tilesToLoad--; if (this._tilesToLoad() === 0) {
if (this._tilesToLoad === 0) {
this.fire('load'); this.fire('load');
} }
}, },
@ -593,6 +589,14 @@ L.GridLayer = L.Layer.extend({
_animateZoom: function (e) { _animateZoom: function (e) {
this._setZoomTransforms(e.center, e.zoom); this._setZoomTransforms(e.center, e.zoom);
},
_tilesToLoad: function () {
var result = 0;
for (var key in this._tiles) {
if (this._tiles[key].loading) { result++; }
}
return result;
} }
}); });

View File

@ -136,7 +136,7 @@ L.TileLayer = L.GridLayer.extend({
_abortLoading: function () { _abortLoading: function () {
var i, tile; var i, tile;
for (i in this._tiles) { for (i in this._tiles) {
tile = this._tiles[i]; tile = this._tiles[i].el;
tile.onload = L.Util.falseFn; tile.onload = L.Util.falseFn;
tile.onerror = L.Util.falseFn; tile.onerror = L.Util.falseFn;