清除图层时浏览器冻结

时间:2018-12-01 00:14:35

标签: javascript leaflet leaflet.markercluster

我有一张地图,需要根据所选年份显示一些位置。每年大约有10万个地点。

在第一次加载(2015年)期间一切正常。但是,如果用户选择另一年(比如2016年),浏览器将冻结。

下面是我的代码。我叫markers.clearLayers()是为了删除当前点(从2015年开始)并用新的点更新地图(2016年)。

var map = L.map('map', {
  center: latlng,
  zoom: 10,
  layers: [tiles]
});

var markers = L.markerClusterGroup({
  chunkedLoading: true
});

fetchLocations(yearSlider.value)

function fetchLocations(year) {
  markers.clearLayers();

  fetch('http://localhost:3003/locations/year/' + year)
    .then(response => response.json())
    .then(json => {
      for (var i = 0; i < json.length; i++) {
        const geo = json[i].geo;
        const coords = geo.coordinates;

        var marker = L.marker(L.latLng(coords[1], coords[0]), {
          title: "abc"
        });
        marker.bindPopup("abc");
        markers.addLayer(marker);
      }

      map.addLayer(markers);
    });
}

3 个答案:

答案 0 :(得分:0)

第一种方法是减少屏幕上可见内容的可见标记。这将提高很多性能。

var markers = new L.MarkerClusterGroup(....);

// Remove everything outside the current view (Performance)
markers._getExpandedVisibleBounds = function () {
    return mcg._map.getBounds();
};

第二种方式在增加maxClusterRadius时会减少地图上的聚类。这也可以改善拖动性能。
另一个冻结问题可能是创建L.marker(...)个10万个位置。

已编辑:

fetchLocations(yearSlider.value)

var map;

function initMap () {
  // Reset whole map and redraw it.
  if (map) {
    map.off();
    map.remove();
  }
  // Create a new leaflet map
  map = L.map('map', {
    center: latlng,
    zoom: 10,
    layers: [tiles]
  });
  return;
}

function fetchLocations(year) {

  initMap();
  
  fetch('http://localhost:3003/locations/year/' + year)
    .then(response => response.json())
    .then(json => {
      // Create new marker cluster group
      var markers = L.markerClusterGroup({
        chunkedLoading: true
      });
      
      for (var i = 0; i < json.length; i++) {
        const geo = json[i].geo;
        const coords = geo.coordinates;

        var marker = L.marker(L.latLng(coords[1], coords[0]), {
          title: "abc"
        });
        marker.bindPopup("abc");
        markers.addLayer(marker);
      }
      // Add individual group to the map
      map.addLayer(markers);
    });
}

答案 1 :(得分:0)

问题是您正在单独将标记添加到群集组中,而群集组已经在地图上:

function () {
  // On next calls, `markers` is still on map
  for (var i = 0; i < json.length; i++) {
    markers.addLayer(marker); // synchronously processes when the group is on map
  }

  map.addLayer(markers); // on first call, `markers` is not yet on map
}

您可以将标记累积在循环内的数组中,然后将其填满,就可以使用markers.addLayers(arrayOfMarkers)

或在函数开始时从地图上删除您的markers组,以便它在内部累积您的标记并在标记末尾添加到批处理时对其进行批处理。

答案 2 :(得分:0)

尽管parndepu的解决方案也可以使用,但我还是设法通过在map.removeLayer(markers);之后添加markers.clearLayers();来解决了这个问题。