Merge pull request #3518 from Leaflet/visible-tiles

Reworked pixelBounds calculation in GridTile to deal with fractional zoom
This commit is contained in:
Vladimir Agafonkin 2015-06-09 07:32:13 -04:00
commit 79105f78a7
2 changed files with 73 additions and 8 deletions

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/screen.css" />
<script type="text/javascript" src="../../build/deps.js"></script>
<script src="../leaflet-include.js"></script>
<style>
#map {
margin: 256px;
width: auto;
overflow: visible
}
</style>
</head>
<body>
The CSS in this page makes the boundaries of the GridLayer tiles visible. Tiles which do not overlap the map bounds shall not be shown, even at fractional zoom levels.
<button onclick='map.zoomIn(0.1)'> Zoom + 0.1 </button>
<button onclick='map.zoomOut(0.1)'> Zoom - 0.1 </button>
<div id="map" class="map"></div>
<script type="text/javascript">
var mapopts = {
center: [35, -122],
zoom : 5.7
};
var map = L.map('map', mapopts);
var grid = L.gridLayer({
attribution: 'Grid Layer'
});
grid.createTile = function (coords, done) {
var tile = document.createElement('div');
tile.innerHTML = [coords.x, coords.y, coords.z].join(', ');
tile.style.border = '2px solid red';
// tile.style.background = 'white';
// test async
setTimeout(function () {
done(null, tile);
}, 0);
return tile;
};
map.addLayer(grid);
</script>
</body>
</html>

View File

@ -413,12 +413,16 @@ L.GridLayer = L.Layer.extend({
if (!map) { return; }
if (center === undefined) { center = map.getCenter(); }
if (zoom === undefined) { zoom = Math.round(map.getZoom()); }
if (zoom === undefined) { zoom = map.getZoom(); }
var tileZoom = Math.round(zoom);
if (zoom > this.options.maxZoom ||
zoom < this.options.minZoom) { return; }
if (tileZoom > this.options.maxZoom ||
tileZoom < this.options.minZoom) { return; }
var pixelBounds = map.getPixelBounds(center, zoom),
var scale = this._map.getZoomScale(zoom, tileZoom),
pixelCenter = map.project(center, tileZoom).floor(),
halfSize = map.getSize().divideBy(scale * 2),
pixelBounds = new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)),
tileRange = this._pxBoundsToTileRange(pixelBounds),
tileCenter = tileRange.getCenter(),
queue = [];
@ -431,7 +435,7 @@ L.GridLayer = L.Layer.extend({
for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
var coords = new L.Point(i, j);
coords.z = zoom;
coords.z = tileZoom;
if (!this._isValidTile(coords)) { continue; }