Leaflet 0.7.7 Zoombased layer switching by theme separated by 主题

Leaflet 0.7.7 Zoombased layer switching separated by theme

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

我们已经尝试通过多种方式使这项工作奏效,但收效甚微。使用 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);

如果我的理解是正确的,你想让用户能够在 "themes" 之间切换(某种基于地图当前缩放级别自行切换的图层组),可能使用 Leaflet图层控制?

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

至于后一个功能(根据地图缩放在组/主题内切换图层),"simple" 解决方案是创建您自己的图层类型来监听地图 "zoomend"事件并相应地更改 Tile Layer 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)来实例化该层 "theme"/组,其中数组索引对应于该 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 的实现,以避免在缩放结束后更改图层等时出现闪烁。