javascript - 新位置数据之前的传单 map 标记clearLayers()

标签 javascript leaflet

我正在制作带有标记的传单 map 。我正在从一个文件中获取标记经纬度数据,该文件每 5 秒更新一次,其中包含大约 100 个标记的新位置数据。

然后,我使用 switch 将标记分成 2 组,并在 map 上用不同的图标表示。

我的问题是,每次更新新的位置数据时都会创建新的标记,但旧的标记仍然存在,因此不久之后就会出现标记的踪迹,并且 map 变得非常慢。

我想在每次创建新标记时清除旧标记,并尝试使用clearLayers()函数但没有效果。没有错误,但标记仍然存在。我已将 clearLayers() 移至代码中的其他级别,以使其不起作用或完全删除所有标记(包括任何新标记)。

geojson.js

     async function getData() {

        const response = await fetch('../../Export.log');
        var data = await response.text();
        var formatted = JSON.parse('[' + data.trim().replace(/\n/g, ',') + ']')
        var enemyForces = L.layerGroup().addTo(map);
        var alliedForces = L.layerGroup().addTo(map);
        alliedForces.clearLayers();
        enemyForces.clearLayers();

        for (var i = 0; i < formatted.length; i++){
            var unit = formatted[i];
            var coalition = unit.coalition;
            var Lat = unit.Lat;
            var Long = unit.Long;
            var LatLong = [Lat, Long];
            var LongLat = [Long, Lat];
            var name = unit.name;
            var ID = unit.ID;
        

            switch (coalition) {
                case "Enemies":

                    L.marker([Lat, Long], {icon: enemyIcon}).bindPopup(name + "<br>" + coalition + "<br>" + ID).addTo(enemyForces);

                    break;
                case "Allies":

                    L.marker([Lat, Long], {icon: alliedIcon}).bindPopup(name + "<br>" + coalition + "<br>" + ID).addTo(alliedForces);

            } // End switch
        
        } // End for

    }
        
        getData();
        setInterval(getData, 5000);

index.html

<!DOCTYPE html>
<html>
<head>
    
    <title>Test Map</title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2a464f4b4c464f5e6a1b041c041a" rel="noreferrer noopener nofollow">[email protected]</a>/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
    <script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aec2cbcfc8c2cbdaee9f8098809e" rel="noreferrer noopener nofollow">[email protected]</a>/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>

    <style>
        html, body {
            height: 100%;
            margin: 0;
        }
        #map {
            width: 100%;
            height: 100%;
        }
    </style>

  </head>
  <body>
    <div id='map'></div>
<script src="js/geojson.js" type="text/javascript"></script>
<script src="js/map.js" type="text/javascript"></script>
  </body>
</html>

map .js

// Start Map
var map = L.map('map').setView([33.5, -117.0], 7);

L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
        '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
        'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    id: 'mapbox/light-v9',
    tileSize: 512,
    zoomOffset: -1
}).addTo(map);

var unitIcon = L.Icon.extend({
    options: {
        iconSize:     [32, 37],
        iconAnchor:   [0, 0],
        popupAnchor:  [0, -5]
    }
});

var alliedIcon = new unitIcon({iconUrl: 'img/ally.png'}),
    enemyIcon = new unitIcon({iconUrl: 'img/enemy.png'});


function onEachFeature(feature, layer) {
// does this feature have a property named popupContent?
if (feature.properties && feature.properties.popupContent) {
    layer.bindPopup(feature.properties.popupContent);
}
}

导出.log

{"ID" : 50, "name" : "Blue1", "coalition" : "Allies", "Lat" : 33.331, "Long" : -117.162, "Alt" : 10.160897, "heading" : 6.283185}
{"ID" : 51, "name" : "Red1", "coalition" : "Enemies", "Lat" : 33.374, "Long" : -116.835, "Alt" : 0.045466, "heading" : 4.879922}
{"ID" : 52, "name" : "Blue2", "coalition" : "Allies", "Lat" : 33.783, "Long" : -117.228, "Alt" : 6.703342, "heading" : 3.078192}

最佳答案

每次调用getData时,您都会创建一个全新的enemyForcesalliedForces。您正在将其添加到 map 中。当您运行 switch 语句时,if 会修改当前函数闭包的 enemyForcesalliedForces,但不会影响之前函数闭包中的那些变量。将这些变量声明移到函数之外。


// move these definitions outside of your function
var enemyForces = L.layerGroup().addTo(map);
var alliedForces = L.layerGroup().addTo(map);

async function getData(){

  ...

  enemyForces.clearLayers();
  alliedForces.clearLayers();

  for (...){

    ...

    switch (coalition) {

      case "Enemies":
        L.marker([Lat, Long], {icon: enemyIcon}).bindPopup(...).addTo(enemyForces);
        break;

      case "Allies":
        L.marker([Lat, Long], {icon: alliedIcon}).bindPopup(...).addTo(alliedForces);

    } // end switch
  } // end for
 
}

编辑:

更改了答案。使用 clearLayer 就足够了,无需调用 remove()

关于javascript - 新位置数据之前的传单 map 标记clearLayers(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62646569/

相关文章:

javascript - 在 HTML 元素之前附加字符串

javascript - LeafLet绘制,标记层无法点击

javascript - 我有一个函数带有一些在 Firefox 上不工作的数据属性

javascript - 外部 Javascript 文件无法正常工作,需要帮​​助

javascript - 悬停时放大图像的智能方法

javascript - map.on ('click' ,onClick) 当 zoomBox 时也会触发

javascript - 将 JavaScript date() 转换为 Python Django models.DateTimeField

javascript - 我可以检测用户何时使用后退按钮进入页面吗?

javascript - 如何通过传单查询立交桥面积?

r - 在 R Shiny 中将传单 map 缩放为默认值