【问题标题】:Leaflet Layer Control: Dynamically Adding and Removing Layer ControlsLeaflet 图层控件:动态添加和删除图层控件
【发布时间】:2021-09-13 19:32:41
【问题描述】:

我正在尝试在 Leaflet Javascript 库中添加图层的控件;供参考,请参阅:https://leafletjs.com/reference-1.7.1.html#control-layers。我的代码大部分工作正常:我有一个layerControl 对象,它使用baseLayers 进行初始化,但还没有覆盖。然后我添加一个layer_USA_Counties Overlay,如下面的代码所示。到目前为止一切顺利。

但我需要能够将新的isochronesGroup 叠加层添加到 layerControl 对象。该代码工作正常,只是在后续代码执行中 isochronesGroup 不断添加到控​​件中 - 请参阅此屏幕截图。我可以使用注释掉的命令删除控件,但它当然也会删除所有isochronesGroup 控件,因此根本不显示它。请注意:加载的图层及其控件不必是layerGroup() 类型。

//globally set
var baseLayers = {
        "Grayscale": grayscale,
        "Streets": streets
 };     
layerControl = L.control.layers(baseLayers, null, { collapsed: false }).addTo(map);

//add a layer from a WMS call and add to the layerControl object
map_LayerGroup = L.layerGroup().addLayer(layer_USA_Counties);///.addTo(map);   
layerControl.addOverlay(map_LayerGroup, "USA Counties");

//Following code gets executed again and again based on user interaction        
isochronesGroup = L.layerGroup().addLayer(route_lines).addTo(map);
layerControl.addOverlay(isochronesGroup, "Isochrones");
///layerControl.removeLayer(isochronesGroup); //WORKS If already created. Or errors

【问题讨论】:

    标签: javascript leaflet


    【解决方案1】:

    您应该能够做到这一点,而不必每次都重新创建控件。问题是isochronesGroup LayerGroup 正在重新创建,这意味着您无法跟踪已添加到控件的图层。尝试在浏览器控制台中逐步执行此示例:

    layerControl = L.control.layers(baseLayers, null, {collapsed: false}).addTo(map);
    
    isochronesGroup = L.layerGroup().addLayer(route_lines).addTo(map);
    layerControl.addOverlay(isochronesGroup, "I1");    // Adds I1
    layerControl.addOverlay(isochronesGroup, "I2");    // Adds I2
    layerControl.removeLayer(isochronesGroup);         // Removes I1
    layerControl.removeLayer(isochronesGroup);         // Removes I2
    layerControl.removeLayer(isochronesGroup);         // No effect (and no error)
    layerControl.removeLayer(wibble);                  // Error
    

    您应该看到,虽然您在层控件中获得了重复的条目,但对removeLayer() 的重复调用最终将它们全部删除。这是有效的,因为变量isochronesGroup 始终引用同一个对象。额外调用removeLayer() 不是问题,即使所有层都从控件中消失,只要isochronesGroup 实际上被定义为有效层。现在试试这个:

    layerControl = L.control.layers(baseLayers, null, {collapsed: false}).addTo(map);
    
    isochronesGroup = L.layerGroup().addLayer(route_lines).addTo(map);
    layerControl.addOverlay(isochronesGroup, "I1");    // Adds I1
    isochronesGroup = L.layerGroup().addLayer(route_lines).addTo(map);
    layerControl.addOverlay(isochronesGroup, "I2");    // Adds I2
    layerControl.removeLayer(isochronesGroup);         // Removes I2
    layerControl.removeLayer(isochronesGroup);         // No effect
    layerControl.removeLayer(isochronesGroup);         // No effect
    

    在上面的示例中,I2 从控件中移除,但 I1 保留。这是因为isochronesGroup 已被重新定义,现在与添加到带有标签 I1 的控件的对象不同。

    考虑到上述情况,这里有两种更优雅的方法来解决您的问题:

    1. 当您需要创建新的isochronesGroup 图层时,请立即从图层控件中删除旧图层,而isochronesGroup 变量仍引用旧图层对象。

    2. 不要每次都重新定义isochronesGroupLayerGroup,而是重用对象,而是使用clearLayers()removeLayer()addLayer()来更改它包含的层。

    使用第二种方法,您不必不断更改图层控件。例如

    // Initialisation
    isochronesGroup = L.layerGroup().addTo(map);           // Create empty LayerGroup
    layerControl.addOverlay(isochronesGroup, "Isochrones");  // Add group to control
    
    // Code to call repeatedly
    isochronesGroup.clearLayers().addLayer(route_lines);
    

    【讨论】:

    • 您好,谢谢先生!我尝试了您的“第二种方法”建议,但收到“TypeError: layerControl.addLayer is not a function”错误。我想我应该坚持我现在所拥有的。再次感谢。
    • 对不起,我的错误。 addLayer() 应该是 addOverlay()。我已经相应地编辑了我的答案。
    • 您好,感谢您一直以来的帮助和支持!所以我按照上面的方法实现了正确的“第二种方法”代码块,错误消失了,但保持添加等时线选项的原始问题又回来了。
    【解决方案2】:

    这就是我最终要做的。这是一个黑客,但有效。稍后,我会将其作为某些维护功能的一部分,以根据需要添加/删除控件的选项。问题中的代码保持不变,但以下部分已更改。基本上,我正在重新创建控件。

    HTH

    //Following code gets executed again and again based on user interaction
    //Remove the control entirely! 
    layerControl.remove();
    //Add the control back with baseLayers
    layerControl = L.control.layers(baseLayers, null, { collapsed: false }).addTo(map);
    //Add back the USA Counties Overlay Control
    usa_counties_LayerGroup = L.layerGroup().addLayer(layer_USA_Counties);///.addTo(map); 
    layerControl.addOverlay(usa_counties_LayerGroup, "USA Counties");
    //Add the isochronesGroup Overlay Control
    isochronesGroup = L.layerGroup().addLayer(route_lines).addTo(map);
    layerControl.addOverlay(isochronesGroup, "Isochrones");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-01
      • 2018-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 2014-05-24
      相关资源
      最近更新 更多