leaflet - 可变宽度覆盖无法通过单击图层控制对话框删除
问题描述
我正在尝试使覆盖线的宽度根据正在使用的图层而变化。也就是说,我有这个代码:
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”图层以外的图层中时,会发生什么,该线不会被删除。它只会在“Light”层中被移除。
为了克服这个问题,我添加了这个:
mymap.on('overlayremove', function(e) {
console.log('overlayremove called');
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
});
那是事情开始变得奇怪的时候。为了删除默认“Light”图层以外的任何图层的所有“Demo”覆盖线,我现在必须双击覆盖控制对话框中的“Demo”覆盖链接,以使“Demo”覆盖线消失。我希望它在单击一次后消失(如果我不尝试动态调整宽度,这就是它通常的工作方式)。
根据console.log
我看到我第一次更改图层时调用了overlayremove,但没有调用overlayadd。这向我表明lightLines.removeFrom(mymap);
正在触发overlayremove
事件。但如果是这种情况,为什么不overlayadd
调用事件呢?无论如何,如果我取消选中然后检查右上角的“演示”覆盖链接,则不会发生任何事情。至少不是我第一次点击它。这条线仍然存在,既没有也没有overlayadd
被overlayremove
调用。但是当我单击“演示”覆盖链接时overlayadd
被调用。当我取消选中它之后,这条线消失了,overlayremove
最后被调用了。
无论如何,我不明白这种行为。
有任何想法吗?
我只是想让可变宽度覆盖线消失,无论显示什么层,在菜单中的覆盖条目被取消选中后。
这是一个独立的演示:
解决方案
仅处理代码中的 L.Control.LayerslightLines
var overlays = {
'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);
当您单击控件时,控件不会satelliteLines
处理任何streetsLines
内容。此外,当覆盖层被移除时,你永远不会hasOverlay
投入。false
因此,根据您正在执行的一组用户操作,会发生不同的行为。例如:
- 打开地图,Light默认,Demo关闭
- Demo被点击(
hasOverlay = true
并被lightLines
添加 - 点击街道。
lightLines
被删除(仍在控件中被检查),streetsLine
被添加,hasOverlay
被true
. - 点击演示。未引发事件,因为
lightLines
不在地图上,并且streetLine
仍在地图上,因为控件不知道它 - 点击演示。
lightLines
被添加到地图 - 点击演示。
lightDemo
从地图中overlayremove
移除并引发移除事件,因此移除了三个叠加层。
为了解决它,我将采用与您不同的方法。不要使用三个不同的覆盖层,而是只使用一个。只听baselayerchange
事件。不要在此回调中手动处理从地图中添加或删除叠加层。只需更改它的样式setStyle
。
推荐阅读
- javascript - 有没有办法通过不必手动执行所有这些功能来从页面中检索 html 代码?
- drupal-8 - Drupal如何使用类似的sql case语句
- python - Tkinter 画布图像错误
- swift - SwiftUI 和 CoreData:将 FetchResults 传递给 DetailView 并更新它们
- javascript - 如何从 Flask 返回错误以便 JavaScript 捕获它
- python - 使用 mpld3 将图形保存到 .html
- install4j - Install4J 自动更新版本检测
- python - 在同一单元格上具有多个类的列上的 Sklearn 编码
- aws-lambda - 在 lambda 函数中使用 npm 模块 (ogr2ogr) 不会返回任何结果
- python - 尝试使用 BeautifulSoup 从网页中提取表格(表格与真实数据不一致)