Leaflet 0.7.7按主题分隔的Zoombased层切换

时间:2015-12-19 16:07:55

标签: zoom leaflet layer switching

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

我们试图以多种方式完成这项工作,但没有取得多大成功。使用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);

1 个答案:

答案 0 :(得分:0)

如果我的理解是正确的,您希望让用户能够切换&#34;主题&#34; (根据地图当前缩放级别切换自己的某种图层组),可能使用Leaflet图层控件?

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

对于后一种功能(基于地图缩放切换组/主题中的图层),&#34;简单&#34;解决方案是创建自己的图层类型,以监听map "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);
    }
  }
});

然后,您将实例化该层&#34;主题&#34; / group通过指定图层数组(您的图块层WMS),其中数组索引对应于图块层应出现的缩放级别。

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的实现,以避免在缩放结束后更改图层等时出现闪烁。