proper GridLayer wrapping/bounding

This commit is contained in:
Vladimir Agafonkin 2013-11-26 17:16:18 +02:00
parent 8f97ca619e
commit 82e43019ee
3 changed files with 50 additions and 19 deletions

View File

@ -31,7 +31,7 @@
// test async // test async
setTimeout(function () { setTimeout(function () {
done(tile); done(null, tile);
}, Math.random() * 500); }, Math.random() * 500);
return tile; return tile;

View File

@ -14,6 +14,8 @@ L.CRS.EPSG3857 = L.extend({}, L.CRS, {
return new L.Transformation(scale, 0.5, -scale, 0.5); return new L.Transformation(scale, 0.5, -scale, 0.5);
}()) }())
wrapLng: true
}); });
L.CRS.EPSG900913 = L.extend({}, L.CRS.EPSG3857, { L.CRS.EPSG900913 = L.extend({}, L.CRS.EPSG3857, {

View File

@ -108,15 +108,6 @@ L.GridLayer = L.Class.extend({
return this; return this;
}, },
isValidTile: function (coords) {
if (!this.options.bounds) { return true; }
var tileBounds = this._tileCoordsToBounds(coords),
bounds = L.latLngBounds(this.options.bounds);
return bounds.contains(tileBounds);
},
_getPane: function () { _getPane: function () {
// TODO pane in options? // TODO pane in options?
return this._map._panes.tilePane; return this._map._panes.tilePane;
@ -274,7 +265,7 @@ L.GridLayer = L.Class.extend({
coords = new L.Point(i, j); coords = new L.Point(i, j);
coords.z = zoom; coords.z = zoom;
if (!this._tileIsAdded(coords) && this.isValidTile(coords)) { if (!this._tileIsAdded(coords) && this._isValidTile(coords)) {
queue.push(coords); queue.push(coords);
} }
} }
@ -305,6 +296,21 @@ L.GridLayer = L.Class.extend({
this._tileContainer.appendChild(fragment); this._tileContainer.appendChild(fragment);
}, },
_isValidTile: function (coords) {
var crs = this._map.options.crs,
limit = this._getWrapTileNum();
if (!crs.wrapLng && (coords.x < 0 || coords.x >= limit.x)) { return; }
if (!crs.wrapLat && (coords.y < 0 || coords.y >= limit.y)) { return; }
if (!this.options.bounds) { return true; }
var tileBounds = this._tileCoordsToBounds(coords),
bounds = L.latLngBounds(this.options.bounds);
return bounds.contains(tileBounds);
},
_tileIsAdded: function (coords) { _tileIsAdded: function (coords) {
return this._tileCoordsToKey(coords) in this._tiles; return this._tileCoordsToKey(coords) in this._tiles;
}, },
@ -319,8 +325,6 @@ L.GridLayer = L.Class.extend({
nw = this._map.unproject(nwPoint), nw = this._map.unproject(nwPoint),
se = this._map.unproject(sePoint); se = this._map.unproject(sePoint);
// TODO rectangular
return new L.LatLngBounds(nw, se); return new L.LatLngBounds(nw, se);
}, },
@ -379,19 +383,23 @@ L.GridLayer = L.Class.extend({
}, },
_addTile: function (coords, container) { _addTile: function (coords, container) {
var tilePos = this._getTilePos(coords);
this._wrapCoords(coords);
var tile = this.createTile(coords, this._tileReady); var tile = this.createTile(coords, this._tileReady);
// TODO wrapping happens here? this.fire('tileloadstart', {tile: tile});
this._initTile(tile); this._initTile(tile);
// if createTile is defined with a second argument ("done" callback),
// we know that tile is async and will be ready later; otherwise
if (this.createTile.length < 2) { if (this.createTile.length < 2) {
// if tiles are sync, delay one frame for opacity anim to happen // mark tile as ready, but delay one frame for opacity anim to happen
setTimeout(L.bind(this._tileReady, this, tile), 0); setTimeout(L.bind(this._tileReady, this, null, tile), 0);
} }
var tilePos = this._getTilePos(coords);
/* /*
Chrome 20 layouts much faster with top/left (verify with timeline, frames) Chrome 20 layouts much faster with top/left (verify with timeline, frames)
Android 4 browser has display issues with top/left and requires transform instead Android 4 browser has display issues with top/left and requires transform instead
@ -406,7 +414,11 @@ L.GridLayer = L.Class.extend({
container.appendChild(tile); container.appendChild(tile);
}, },
_tileReady: function (tile) { _tileReady: function (err, tile) {
if (err) {
this.fire('tileerror', {error: err});
}
L.DomUtil.addClass(tile, 'leaflet-tile-loaded'); L.DomUtil.addClass(tile, 'leaflet-tile-loaded');
this.fire('tileload', {tile: tile}); this.fire('tileload', {tile: tile});
@ -435,6 +447,23 @@ L.GridLayer = L.Class.extend({
return tilePoint.multiplyBy(tileSize).subtract(origin); return tilePoint.multiplyBy(tileSize).subtract(origin);
}, },
_wrapCoords: function (coords) {
var crs = this._map.options.crs,
limit = this._getWrapTileNum();
if (crs.wrapLng) {
coords.x = ((coords.x % limit.x) + limit.x) % limit.x;
}
if (crs.wrapLat) {
coords.y = ((coords.y % limit.y) + limit.y) % limit.y;
}
},
_getWrapTileNum: function () {
var size = this._map.options.crs.getSize(this._map.getZoom());
return size.divideBy(this.options.tileSize);
},
_animateZoom: function (e) { _animateZoom: function (e) {
if (!this._animating) { if (!this._animating) {
this._animating = true; this._animating = true;