【问题标题】:Leaflet 0.7.7 Zoombased layer switching separated by themeLeaflet 0.7.7 以主题分隔的基于缩放的图层切换
【发布时间】:2015-12-19 16:07:55
【问题描述】:

我们正在开展一个学校项目,其目的是创建一张地图,在该地图中,图层会根据缩放量从一个聚合级别切换到较小的聚合级别。此外,我们有几组基于需要应用的主题的图层。因此,您单击一个主题,一组基于缩放级别切换的新图层将变为活动状态,当您单击另一个主题时,另一组图层将变为活动状态并根据缩放级别进行切换。这意味着主题是排他性的,理想情况下您一次不能有多个主题处于活动状态。

我们已经尝试通过多种方式完成这项工作,但没有取得多大成功。使用 L.Control.Layers,我们无法将不同的图层组合在一个单选按钮下并让它们根据缩放进行切换,因为传单中内置的图层控件总是将它们分成单独的图层。甚至使用 L.layerGroup 组合多个图层变量或将多个图层创建为一个变量,然后使用 l.control.layer 将它们添加到地图中。

我们还尝试使用 L.easyButton (https://github.com/CliffCloud/Leaflet.EasyButton)。这允许我们将变量放在一个按钮下,并在其中添加一个基于缩放的图层切换。但是,这里的问题是我们无法在激活后停用该功能。这导致它们中的几个在一个点上处于活动状态并相互重叠。

如果可能,我们想知道是否应该使用不同的方法,或者传单控制功能或使用 easyButton 是否可以工作以及如何工作?

这是其中一个按钮的示例代码,它会出现多次但显示不同的主题:

        L.easyButton( '<span class="star">&starf;</span>', function (polygon) {

                    var ejerlav_polygon = new L.tileLayer.betterWms(
                    'http://[IP]:[PORT]/geoserver/prlayer/wms', {
                    layers: 'prlayer:ejerlav',
                    transparent: true,
                    styles: 'polygon',          
                    format: 'image/png'});

                    var municipality_polygon = new L.tileLayer.betterWms(
                    'http://[IP]:[PORT]/geoserver/prlayer/wms', {
                    layers: 'prlayer:municipality',
                    transparent: true,
                    styles: 'polygon',
                    format: 'image/png'});                      

                    map.on("zoomend", function() {
                        if (map.getZoom() <= 10 && map.getZoom() >= 2) {
                            map.addLayer(municipality_polygon);
                        } else if (map.getZoom() > 10 || map.getZoom() < 2) {
                            map.removeLayer(municipality_polygon);
                        }
                        });

                            map.on("zoomend", function() {
                        if (map.getZoom() <= 11 && map.getZoom() >= 11) {
                            map.addLayer(ejerlav_polygon);

                        } else if (map.getZoom() > 11 || map.getZoom() < 11) {
                            map.removeLayer(ejerlav_polygon);
                        }
                        });

        }).addTo(map);

【问题讨论】:

    标签: zooming leaflet layer switching


    【解决方案1】:

    如果我的理解是正确的,您是否希望用户能够在“主题”(根据地图当前缩放级别自行切换的某种图层组)之间切换,可能使用 Leaflet Layers Control?

    关于基于地图缩放的切换,你不能因为使用一些WMS就改变Tile Layer模板URL吗?

    至于后一种功能(根据地图缩放在组/主题内切换图层),“简单”的解决方案是创建您自己的图层类型,该图层将监听地图"zoomend" 事件并更改平铺图层相应的 WMS。

    L.LayerSwitchByZoom = L.Class.extend({
      initialize: function (layersArray) {
        var self = this;
    
        this._layersByZoom = layersArray;
        this._maxZoom = layersArray.length - 1;
    
        this._switchByZoomReferenced = function () {
          self._switchByZoom();
        };
      },
    
      onAdd: function (map) {
        this._map = map;
    
        map.on("zoomend", this._switchByZoomReferenced);
        this._switchByZoom();
      },
    
      onRemove: function (map) {
        map.off("zoomend", this._switchByZoomReferenced);
        this._removeCurrentLayer();
    
        this._map = null;
      },
    
      addTo: function (map) {
        map.addLayer(this);
        return this;
      },
    
      _switchByZoom: function () {
        var map = this._map,
            z = Math.min(map.getZoom(), this._maxZoom);
    
        this._removeCurrentLayer();
        this._currentLayer = this._layersByZoom[z];
        map.addLayer(this._currentLayer);
      },
    
      _removeCurrentLayer: function () {
        if (this._currentLayer) {
          map.removeLayer(this._currentLayer);
        }
      }
    });
    

    然后,您将通过指定图层数组(您的 Tile Layers WMS)来实例化该图层“主题”/组,其中数组索引对应于该 Tile Layer 应出现的缩放级别。

    var myLayerSwitchByZoomA = new L.LayerSwitchByZoom([
      osmMapnik, // zoom 0, osmMapnik is a Tile Layer or any other layer
      osmDE, // zoom 1
      osmFR, // zoom 2
      osmHOT // zoom 3, etc.
    ]);
    

    一旦设置了这种新的图层类型,您就可以在图层控件中使用它,就像任何其他类型的图层/平铺图层等一样。

    L.control.layers({
      "OpenStreetMap": myLayerSwitchByZoomA,
      "ThunderForest": myLayerSwitchByZoomB
    }).addTo(map);
    

    演示:http://jsfiddle.net/ve2huzxw/85/

    请注意,您可以进一步改进L.LayerSwitchByZoom的实现,以避免在缩放结束后更改图层时出现闪烁等问题。

    【讨论】:

    • 非常感谢您的回复!过去几天我们一直在实施您的方法,并且效果很好。闪烁还不错,因为我们通过 wms 请求使用来自地理服务器的我们自己的图层,而且它们并没有那么重。我们想知道是否可以将所有图层都翻转?从现在开始,总会有一个活跃的。
    • 不显示图层的一个非常简单的解决方法是创建一个虚拟图层并将其添加到图层控件。例如:myLayerControl.addBaseLayer(L.layerGroup(), "No layer").
    猜你喜欢
    • 2016-12-04
    • 1970-01-01
    • 2016-02-27
    • 2013-11-18
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多