Reputation: 5
I'm currently working on a leaflet map, where the provided tiles are limited to certain regions. To prevent the loading of missing tiles I've added bounds to the layers like so:
layer.options.bounds = latLngBounds
The bounds for that specific region go from lng -200 to -20.
Now the problem is, that it does indeed prevent loading tiles outside of the bounds, but it also doesn't load the tiles from -200 to -180. So far I've tried to make the coordinates positive, adding offsets, other tiles, adding the bounds when creating the layers and using a L.latLngBounds instead of a simple array.
Is there a way to tell leaflet to go over the anti-meridian?
Here is a snipped that shows the problem with a live example:
var latLon = [40, -100]
const tileW = 22.5
const corner1 = L.latLng(-66.51, -202.5)
const corner2 = L.latLng(66.51, -22.5)
const latLngBounds = L.latLngBounds(corner1, corner2)
var map = L.map('map', {minZoom: 2}).setView(latLon, 2)
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
bounds: latLngBounds
});
osm.addTo(map)
// Expected map position
L.marker(latLngBounds.getNorthEast()).addTo(map)
L.marker(latLngBounds.getSouthWest()).addTo(map)
L.marker(latLngBounds.getNorthWest()).addTo(map)
L.marker(latLngBounds.getSouthEast()).addTo(map)
// Antimeridian
L.marker([0, -180]).addTo(map)
#map { height: 90vh; }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
Upvotes: 0
Views: 477
Reputation: 11378
You need to change the function where leaflet check if the tile is in the bounds:
L.BoundsTiles = L.TileLayer.extend({
_isValidTile: function (coords) {
var crs = this._map.options.crs;
if (!crs.infinite) {
// don't load tile if it's out of bounds and not wrapped
var bounds = this._globalTileRange;
if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
(!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
}
if (!this.options.bounds) { return true; }
// don't load tile if it doesn't intersect the bounds in options
var tileBounds = this._tileCoordsToBounds(coords);
var bounds = L.latLngBounds(this.options.bounds);
if(!bounds.overlaps(tileBounds)){
var bounds2 = L.latLngBounds([bounds._southWest,bounds._northEast]);
bounds2._southWest.lng += 360;
bounds2._northEast.lng += 360;
return bounds2.overlaps(tileBounds);
}
return L.latLngBounds(this.options.bounds).overlaps(tileBounds);
},
})
var osm = new L.BoundsTiles('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
bounds: latLngBounds
});
https://jsfiddle.net/falkedesign/8j6g5p07/
Upvotes: 0