在Leaflet中使用多个切片图层时,避免加载不可见的切片

jel*_*han 6 leaflet

我正在使用带有两个图块层的Leaflet.第一个,我将其称为地下室瓷砖层,为整个世界提供瓷砖.第二个覆盖在由弹跳选项定义的特定区域中的地下室图块层.我将这称为覆盖瓦片层.在代码中,这看起来像如下:

var map = L.map('map');

// OpenstreetMap tile layer as basement
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// overlaying tile layer for specific region defined by bounds
L.tileLayer('http://{s}.examples.com/overlay/{z}/{x}/{y}.png', {
  bounds: L.latLngBounds(L.latLng(59.321966, 18.05943), L.latLng(59.328469, 18.076167));
}).addTo(map);
Run Code Online (Sandbox Code Playgroud)

重叠的图块层不透明.因此,对于边界区域,仅覆盖的图块层的图块是可见的.不需要由地下室瓷砖层提供的瓷砖.但我没有找到防止Leaflet装载这些不必要的瓷砖的方法.任何暗示我都会很高兴.

我想过使用tile事件来中断不需要的tile的加载.但据记录的tile事件无法操纵tile加载.

这是一个展示行为的JSFiddle.如你所见,例如,瓷砖14/4825/6155.png是从openstreetmap.org加载的,所以它是不可见的.

在我的用例中,另一种想法使它更复杂:覆盖地图具有严格的边界,因为它是由历史地图表生成的.因此,瓷砖在覆盖地图的边界处是透明的.在这些区域中,必须加载地下室地图的图块.

jel*_*han 4

感谢@FrankPhillips 在评论中的提示,我发现我可以覆盖_isValidTileL.GridLayer 中的方法来实现该功能。我可以添加一个洞选项作为与弹跳选项相反的选项。

\n\n
L.ExtendedTileLayer = L.TileLayer.extend({    \n    _isValidTile: function (coords) {\n        var crs = this._map.options.crs;\n\n        if (!crs.infinite) {\n            // don\'t load tile if it\'s out of bounds and not wrapped\n\n            /*\n             * this._globalTileRange is not defined\n             * not quite sure why\n             */\n            var globalTileRange = this._map.getPixelWorldBounds( coords.z );\n\n            var bounds = globalTileRange;\n            if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||\n                (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }\n        }\n\n        var tileBounds = this._tileCoordsToBounds(coords);\n\n        // don\'t load tile if it doesn\'t intersect the bounds in options\n        if (this.options.bounds &&\n            ! L.latLngBounds(this.options.bounds).intersects(tileBounds)) {\n            return false;\n        }\n\n        // don\'t load tile if it does intersect the hole in options\n        if (this.options.hole &&\n            L.latLngBounds(this.options.hole).intersects(tileBounds)) {\n            return false;\n        }\n\n        return true;\n    },\n});\n\nvar map = L.map(\'map\', {\n    center: [40.777838, -73.968654], \n    zoom: 14\n});\n\nnew L.ExtendedTileLayer(\'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\',{\n    attribution: \'\xc2\xa9 <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors\',\n    hole: L.latLngBounds(\n        L.latLng(40.791853, -73.967128),\n        L.latLng(40.781455, -73.955713)\n    )\n}).addTo(map);\n\nL.tileLayer(\'http://tile.stamen.com/toner/{z}/{x}/{y}.png\', {\n    attribution: \'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.\',\n    bounds: L.latLngBounds(\n        L.latLng(40.791853, -73.967128),\n        L.latLng(40.781455, -73.955713)\n    )\n}).addTo(map);\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新了 JSFiddle以显示它的工作原理。

\n\n

_isValidTile大部分只是从传单原文复制而来。我必须重新实现,this._globalTileRange因为 is 未定义。代码仅适用于 leaflet-src.js,因为_isValidTime在生产版本中已被丑化。

\n