无法通过单击图层控制对话框删除可变宽度叠加层

variable width overlays unable to be removed with one click on layer control dialog

我正在努力使覆盖线的宽度根据正在使用的图层而变化。也就是说,我有这个代码:

var params = {
    color: 'blue',
    opacity: 0.75,
    smoothFactor: 1
};

var latlngs = [[30.267222, -97.743056],[31.267222, -96.743056]];

tempParams = Object.assign(params, {weight: 10});
satelliteLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 3});
lightLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 5});
streetsLines.addLayer(L.polyline(latlngs, tempParams));

var hasOverlay = false;

mymap.on('baselayerchange', function(e) {
    switch (e.name) {
        case 'Light':
            if (hasOverlay) {
                lightLines.addTo(mymap);
                streetsLines.removeFrom(mymap);
                satelliteLines.removeFrom(mymap);
            }
            break;
        case 'Streets':
            if (hasOverlay) {
                lightLines.removeFrom(mymap);
                streetsLines.addTo(mymap);
                satelliteLines.removeFrom(mymap);
            }
            break;
        case 'Satellite':
            if (hasOverlay) {
                lightLines.removeFrom(mymap);
                streetsLines.removeFrom(mymap);
                satelliteLines.addTo(mymap);
            }
    }
});

mymap.on('overlayadd', function(e) {
    console.log('overlayadd called');
    hasOverlay = true;
});

这在我打开“演示”覆盖层时效果很好,但当我关闭覆盖层并且我位于默认“光”层以外的层时效果不佳。当我在“Light”层以外的层中时,会发生什么情况是该行不会被删除。它只会在“Light”层中被移除。

为了克服这个问题,我添加了这个:

mymap.on('overlayremove', function(e) {
    console.log('overlayremove called');
    lightLines.removeFrom(mymap);
    streetsLines.removeFrom(mymap);
    satelliteLines.removeFrom(mymap);
});

那就是事情开始变得奇怪的时候。为了删除除默认“Light”层以外的任何层的所有“Demo”覆盖线,我现在必须双击“Demo”覆盖线的覆盖控制对话框中的“Demo”覆盖link消失。我希望它在单击一次后消失(如果我不尝试动态调整宽度,它通常会这样工作)。

根据 console.log,我看到我第一次更改图层时会调用 overlayremove,但不会调用 overlayadd。这向我暗示 lightLines.removeFrom(mymap); 正在触发 overlayremove 事件。但如果是这样,为什么不调用 overlayadd 事件?无论如何,如果我取消选中然后选中右上角的“演示”覆盖 link,则不会发生任何事情。至少我不是第一次点击它。该行仍然存在,并且 overlayaddoverlayremove 都没有被调用。但是,当我单击“演示”叠加层时,link overlayadd 被调用。当我取消选中它之后,该行消失了,overlayremove 终于被调用了。

无论如何,我不明白这种行为。

有什么想法吗?

我只想让可变宽度覆盖线消失,无论显示哪个层,在菜单中的覆盖条目被取消选中后。

这是一个独立的演示:

https://terrafrost.com/leaflet/demo01.html

L.Control.Layers 在您的代码中只处理了 lightLines

var overlays = {
    'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);

当您单击控件时,satelliteLines 控件都不会处理 streetsLines。此外,当覆盖层被移除时,您永远不会将 hasOverlay 放入 false

因此,根据您正在执行的一组用户操作,会发生不同的行为。例如:

  1. 打开地图,默认Light,Demo关闭
  2. 点击演示(hasOverlay = true 并添加 lightLines
  3. 点击街道。 lightLines 被删除(仍然在控件中是检查),添加 streetsLinehasOverlaytrue
  4. 点击演示。未引发事件,因为 lightLines 不在地图上,而 streetLine 仍在地图上,因为控件不知道它
  5. 点击演示。 lightLines 被添加到地图
  6. 点击演示。 lightDemo 已从地图中移除并引发了 overlayremove 移除事件,因此移除了三个叠加图层。

要修复它,我将采用与您不同的方法。不要使用三个不同的覆盖层,而只使用一个。仅监听 baselayerchange 个事件。不要在此回调中手动处理在地图中添加或删除叠加层。只需使用 setStyle.

更改样式即可