Leaflet 在传单中使用多个瓷砖层时,避免加载不可见的瓷砖

Leaflet 在传单中使用多个瓷砖层时,避免加载不可见的瓷砖,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="htt

我正在使用两个瓷砖层。第一层,我称之为地下室瓷砖层,为全世界提供瓷砖。第二层覆盖在“反弹”选项定义的特定区域中的地下室瓷砖层上。我将称之为叠加瓷砖层。在代码中,如下所示:

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);
var-map=L.map('map');
//OpenstreetMap地砖层作为基底
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png'{
属性:“©;贡献者”
}).addTo(地图);
//覆盖由边界定义的特定区域的瓷砖层
L.tileLayer('http://{s}.examples.com/overlay/{z}/{x}/{y}.png'{
边界:L.latLngBounds(L.latLng(59.321966,18.05943),L.latLng(59.328469,18.076167));
}).addTo(地图);
覆盖的瓷砖层不透明。因此,对于边界区域,只有重叠瓷砖层的瓷砖可见。不需要地下室瓷砖层提供的瓷砖。但我还没有找到一种方法来防止传单上贴上这些不必要的瓷砖。我很乐意得到任何提示

我考虑过使用tile事件来中断加载不需要的tile。但就文档化的磁贴事件而言,无法操纵磁贴加载

下面是一个演示该行为的示例。如您所见,tile 14/4825/6155.png是从openstreetmap.org加载的,即使它是不可见的


在我的用例中,另一个想法使它变得更复杂:叠加地图有严格的边界,因为它是由历史地图表生成的。因此,在重叠贴图的边界处,平铺是透明的。在这些区域,必须加载地下室地图的瓷砖

感谢@FrankPhillips在评论中的提示,我发现我可以覆盖L.GridLayer中的
\u isValidFile
方法来实现功能。我可以添加一个洞选项作为反弹选项的对立面

L.ExtendedTileLayer=L.TileLayer.extend({
_IsValidFile:函数(coords){
var crs=此。_map.options.crs;
如果(!crs.infinite){
//如果瓷砖超出边界且未包装,则不要加载瓷砖
/*
*此.\u globalTileRange未定义
*不太清楚为什么
*/
var globalTileRange=this.\u map.getPixelWorldBounds(coords.z);
var界限=全球公差;
if((!crs.wrapLng&&(coords.xbounds.max.x))||
(!crs.wrapLat&&(coords.ybounds.max.y)){return false;}
}
var tileBounds=此。_TileCordstoBounds(coords);
//如果平铺与选项中的边界不相交,则不要加载平铺
如果(this.options.bounds)&&
!L.latLngBounds(this.options.bounds).intersects(tileBounds)){
返回false;
}
//如果平铺与选项中的孔相交,则不要加载平铺
如果(this.options.hole)&&
L.latLngBounds(this.options.hole).相交(tileBounds)){
返回false;
}
返回true;
},
});
var map=L.map('map'{
中间:[40.777838,-73.968654],
缩放:14
});
新的L.ExtendedTileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'{
归属:‘©贡献者’,
孔:L.latLngBounds(
L.latLng(40.791853,-73.967128),
L.latLng(40.781455,-73.955713)
)
}).addTo(地图);
L.tileLayer('http://tile.stamen.com/toner/{z} /{x}/{y}.png'{
属性:“地图平铺依据,下方。数据依据,下方”,
边界:L.latLngBounds(
L.latLng(40.791853,-73.967128),
L.latLng(40.781455,-73.955713)
)
}).addTo(地图);
我想展示一下它的工作原理


\u isvalidfile
大部分是从传单原件中复制的。由于is未定义,我不得不重新实现
。\u globalTileRange
。代码仅适用于传单-src.js,因为\u isValidTime在生产构建中是丑陋的。

我想你是在问如何使覆盖仅显示在边界框内?如果这是您的问题,那么很难使用瓷砖层。使用单个平铺请求会更好地为您提供服务。如果您控制覆盖服务,我建议在该服务器上使用单个tile WMS设置。否则,如果您需要使用瓷砖,您将需要做大量的魔术来切割客户端的瓷砖。我真的不知道你在问什么。如果您只是问最后一段,只需将openstreetmaps层设置为basemap true即可。@FrankPhillips将平铺层限制在特定区域,此选项受“开箱即用”选项的支持。正如你在这本书中所看到的,它工作得很好。我的问题只是关于避免加载不需要的磁贴。我不清楚您是否担心BBOX的精度或带宽使用。您可以防止加载,但只能很容易地(移除层)。该解决方案是附加到历史层的tileOnError事件,如果发生这种情况,则添加底图以填补空白(如果有)。除此之外,还需要在传单中扩展平铺器,以便两个图层对象都能相互识别。除非你有一套非常小的历史地图和大量的网站使用情况,否则要节省看起来非常少的使用量,这将是一项非常艰巨的工作。这真的没有一个好的答案。但是,看看这是个好主意。完全忘记了_IsValidFile。知道如何/如果可以使用L.TileLayer.wms()而不是L.TileLayer来实现此功能吗?你也能明白为什么这并没有掩盖苏格兰上空的瓦片吗?
L.ExtendedTileLayer = 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

            /*
             * this._globalTileRange is not defined
             * not quite sure why
             */
            var globalTileRange = this._map.getPixelWorldBounds( coords.z );

            var bounds = 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; }
        }

        var tileBounds = this._tileCoordsToBounds(coords);

        // don't load tile if it doesn't intersect the bounds in options
        if (this.options.bounds &&
            ! L.latLngBounds(this.options.bounds).intersects(tileBounds)) {
            return false;
        }

        // don't load tile if it does intersect the hole in options
        if (this.options.hole &&
            L.latLngBounds(this.options.hole).intersects(tileBounds)) {
            return false;
        }

        return true;
    },
});

var map = L.map('map', {
    center: [40.777838, -73.968654], 
    zoom: 14
});

new L.ExtendedTileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
    attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    hole: L.latLngBounds(
        L.latLng(40.791853, -73.967128),
        L.latLng(40.781455, -73.955713)
    )
}).addTo(map);

L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
    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>.',
    bounds: L.latLngBounds(
        L.latLng(40.791853, -73.967128),
        L.latLng(40.781455, -73.955713)
    )
}).addTo(map);