传单 geojsos,使用 Ajax 更新制造商,如何在重新添加之前删除所有标记?

问题描述

我使用带有传单的 GeoJSON 在地图上插入标记,然后我有一个 Ajax 请求,每 60 秒定期更新图标的最新状态(如果位置上升或下降,它们会变成红色或绿色)

然而,我们注意到该页面看起来像是内存泄漏,在进一步调查中我们可以看到每次刷新时都会添加额外的标记,因此一小时后地图上有 100 个标记,我们有 6000 个标记。任何人都可以帮助我根据新数据更新现有标记删除并重新添加它们吗?

当前代码如下

谢谢

<script type="text/javascript">
    var map = L.map('map').setView([54.0,-3.4],7);
    L.tileLayer('https://api.mapBox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accesstoken}',{
        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>',maxZoom: 18,id: 'mapBox/dark-v10',accesstoken: 'pk.*****'
    }).addTo(map);


    $(function() {
        function update_maps() {
            // Update the pins in the amaps
            $.get('/monitoring/data/status_map_geo_data/gb/',function(geo_data) {
                        L.geoJSON(geo_data,{
                            pointToLayer: function (feature,latlng) {
                                var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
                                return L.marker(latlng,{
                                    zIndexOffset: zindex  ? 1000 : 0,icon: L.AwesomeMarkers.icon(
                                                {
                                                    icon: feature.properties.icon,markerColor: feature.properties.color,prefix: 'fa',iconColor: 'white',}
                                            )
                                        }
                                    );
                            },onEachFeature: function (feature,layer) {
                                var layer_text = '<h3><a href="/sites/site/'+feature.properties.site_id+'">'+feature.properties.popupContent+'</a></h3>'
                                layer.bindPopup(layer_text)
                            }
                        }).addTo(map);  
            });
        }
        $(document).ready(function() {
            // load icons on start
            update_maps()
        });
        // refresh page
        setInterval(function() {
            update_maps()
        },60 * 1000);

        

    });
</script>

解决方法

这是一个简单的解决方案,L.geoJSON 返回一个带有标记的组,这个组可以用 .clearLayers() 清除。

因此将您的代码更改为:

var geoJsonGroup = null;
function update_maps() {
            // Update the pins in the amaps
            $.get('/monitoring/data/status_map_geo_data/gb/',function(geo_data) {
                        if(geoJsonGroup){
                           geoJsonGroup.clearLayers();
                        }
                        geoJsonGroup = L.geoJSON(geo_data,{
                            pointToLayer: function (feature,latlng) {
                                var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
                                return L.marker(latlng,{
                                    zIndexOffset: zindex  ? 1000 : 0,icon: L.AwesomeMarkers.icon(
                                                {
                                                    icon: feature.properties.icon,markerColor: feature.properties.color,prefix: 'fa',iconColor: 'white',}
                                            )
                                        }
                                    );
                            },onEachFeature: function (feature,layer) {
                                var layer_text = '<h3><a href="/sites/site/'+feature.properties.site_id+'">'+feature.properties.popupContent+'</a></h3>'
                                layer.bindPopup(layer_text)
                            }
                        }).addTo(map);  
            });
        }

替代方案(来自@gyhbs)“条条大路通罗马”

  1. 调用 geoJsonGroup.removeFrom(map) 而不是 geoJsonGroup.clearLayers();
  2. L.geoJSON 放在外面,然后调用 addData 而不是每次都创建一个新组:
var geoJsonGroup = L.geoJSON(null,{
    pointToLayer: function(feature,latlng) {
        var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
        return L.marker(latlng,{
            zIndexOffset: zindex ? 1000 : 0,icon: L.AwesomeMarkers.icon({
                icon: feature.properties.icon,})
        });
    },onEachFeature: function(feature,layer) {
        var layer_text = '<h3><a href="/sites/site/' + feature.properties.site_id + '">' + feature.properties.popupContent + '</a></h3>'
        layer.bindPopup(layer_text)
    }
}).addTo(map);

function update_maps() {
    // Update the pins in the amaps
    $.get('/monitoring/data/status_map_geo_data/gb/',function(geo_data) {
        if (geoJsonGroup) {
            geoJsonGroup.clearLayers();
        }
        geoJsonGroup.addData(geo_data)
    });
}