From 132bfc539b598ce791c6184dd98d6a29f41c1b88 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Wed, 3 Aug 2011 21:14:15 -0500 Subject: [PATCH] Handle Leaflet freak-out on removed layers during tile load, clean up panning --- web/js/dynmaputils.js | 31 +++++++++++++++++++++++++++++++ web/js/map.js | 38 +++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/web/js/dynmaputils.js b/web/js/dynmaputils.js index fa2e5163..dbdfffa3 100644 --- a/web/js/dynmaputils.js +++ b/web/js/dynmaputils.js @@ -45,9 +45,40 @@ var DynmapTileLayer = L.TileLayer.extend({ updateTile: function(tile) { this._loadTile(tile, tile.tilePoint, this._map.getZoom()); }, + // Override to fix loads completing after layer removed + _addTilesFromCenterOut: function(bounds) { + if(this._container == null) // Ignore if we've stopped being active layer + return; + var queue = [], + center = bounds.getCenter(); + + for (var j = bounds.min.y; j <= bounds.max.y; j++) { + for (var i = bounds.min.x; i <= bounds.max.x; i++) { + if ((i + ':' + j) in this._tiles) { continue; } + queue.push(new L.Point(i, j)); + } + } + + // load tiles in order of their distance to center + queue.sort(function(a, b) { + return a.distanceTo(center) - b.distanceTo(center); + }); + + var fragment = document.createDocumentFragment(); + + this._tilesToLoad = queue.length; + for (var k = 0, len = this._tilesToLoad; k < len; k++) { + this._addTile(queue[k], fragment); + } + + this._container.appendChild(fragment); + }, // We should override this, since Leaflet does modulo on tilePoint by default. (https://github.com/CloudMade/Leaflet/blob/master/src/layer/tile/TileLayer.js#L151) _addTile: function(tilePoint) { + if(this._container == null) // Ignore if we're not active layer + return; + var tilePos = this._getTilePos(tilePoint), zoom = this._map.getZoom(), key = tilePoint.x + ':' + tilePoint.y, diff --git a/web/js/map.js b/web/js/map.js index 71078834..c79b12f2 100644 --- a/web/js/map.js +++ b/web/js/map.js @@ -299,7 +299,7 @@ DynMap.prototype = { }); }, getProjection: function() { return this.maptype.getProjection(); }, - selectMap: function(map, completed) { + selectMapAndPan: function(map, location, completed) { if (!map) { throw "Cannot select map " + map; } var me = this; @@ -333,9 +333,12 @@ DynMap.prototype = { me.map.options.maxZoom = me.maptype.options.maxZoom; me.map.options.minZoom = me.maptype.options.minZoom; - if (projectionChanged || worldChanged) { + if (projectionChanged || worldChanged || location) { var centerPoint; - if(worldChanged) { + if(location) { + centerPoint = me.getProjection().fromLocationToLatLng(location); + } + else if(worldChanged) { var centerLocation = $.extend({ x: 0, y: 64, z: 0 }, mapWorld.center); centerPoint = me.getProjection().fromLocationToLatLng(centerLocation); } @@ -369,28 +372,37 @@ DynMap.prototype = { completed(); } }, - selectWorld: function(world, completed) { + selectMap: function(map, completed) { + this.selectMapAndPan(map, null, completed); + }, + selectWorldAndPan: function(world, location, completed) { var me = this; if (typeof(world) === 'String') { world = me.worlds[world]; } if (me.world === world) { - if (completed) { completed(); } + if(location) { + var latlng = me.maptype.getProjection().fromLocationToLatLng(location); + me.panToLatLng(latlng, completed); + } + else { + if (completed) { completed(); } + } return; } - me.selectMap(world.defaultmap, completed); + me.selectMapAndPan(world.defaultmap, location, completed); + }, + selectWorld: function(world, completed) { + this.selectWorldAndPan(world, null, completed); }, panToLocation: function(location, completed) { var me = this; - var pan = function() { - var latlng = me.maptype.getProjection().fromLocationToLatLng(location); - me.panToLatLng(latlng, completed); - }; if (location.world) { - me.selectWorld(location.world, function() { - pan(); + me.selectWorldAndPan(location.world, location, function() { + if(completed) completed(); }); } else { - pan(); + var latlng = me.maptype.getProjection().fromLocationToLatLng(location); + me.panToLatLng(latlng, completed); } }, panToLayerPoint: function(point, completed) {