首页 > 解决方案 > 传单 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>

标签: javascriptajaxleaflet

解决方案


这是一个简单的解决方案,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,
                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);

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)
    });
}

推荐阅读