vector.getSource().clear() 上的 openlayers 3 烦人的闪光灯

openlayers 3 annoying flash on vector.getSource().clear()

限制显示的矢量要素数量在 OpenLayers 中很重要,但这可能会导致某些要素无法显示。移动或放大时,需要通过 XHR 调用 "refresh" 功能。在 OpenLayers 2 中,这可以通过调用

来实现
bboxstrategy.update({ force: true })

在地图的 'zoomend' 事件上。

在使用 SVG 渲染器的 OL2 中,重绘非常平滑,几乎看不出来。

OL3中,看来有必要调用:

    vector.getSource().clear();

在地图的 'moveend' 事件上。

当 OL3 呈现新功能时,这会导致烦人的闪烁。

有没有人知道有更好的技术来重新加载功能但避免闪烁?

这是一个华丽的工作示例,改编自 here

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>WFS</title>
      <link rel="stylesheet" href="https://openlayers.org/en/v4.6.4/css/ol.css" type="text/css">
      <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
      <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
      <script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
    </head>
  <body>
    <div id="map" class="map"></div>
    <script>
      function onMoveEnd( evt ) {
        vector.getSource().clear();
      }

      var vectorSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        url: function(extent) {
        return 'https://ahocevar.com/geoserver/wfs?service=WFS&' +
          'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
          'maxFeatures=500&outputFormat=application/json&srsname=EPSG:3857&' +
          'bbox=' + extent.join(',') + ',EPSG:3857';
        },
        strategy: ol.loadingstrategy.bbox
      });

      var vector = new ol.layer.Vector({
        source: vectorSource,
        style: new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 255, 1.0)',
            width: 2
          })
        })
      });

      var raster = new ol.layer.Tile({
        source: new ol.source.OSM({
        })
      });

      var map = new ol.Map({
        layers: [raster, vector],
        target: document.getElementById('map'),
        view: new ol.View({
          center: [-8908887.277395891, 5381918.072437216],
          maxZoom: 19,
          zoom: 12
        })
      });
      map.on('moveend', onMoveEnd);
   </script>
  </body>
</html>

您可以通过在自定义加载程序中使用 removeLoadedExtent 来实现此目的,它将范围标记为未加载。并且为了避免多次添加功能,您可以在添加之前在加载程序中使用清除。

http://openlayers.org/en/latest/apidoc/ol.source.Vector.html#removeLoadedExtent

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>WFS</title>
      <link rel="stylesheet" href="https://openlayers.org/en/v4.6.4/css/ol.css" type="text/css">
      <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
      <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
      <script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
    </head>
  <body>
    <div id="map" class="map"></div>
    <script>
      var vectorSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        loader: function(extent, resolution, projection) {
          var url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' +
          'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
          'maxFeatures=500&outputFormat=application/json&srsname=EPSG:3857&' +
          'bbox=' + extent.join(',') + ',EPSG:3857';
          var xhr = new XMLHttpRequest();
          xhr.open('GET', url);
          var removeExtent = function() {
            vectorSource.removeLoadedExtent(extent);
          }
          xhr.onerror = removeExtent;
          xhr.onload = function() {
            if (xhr.status == 200) {
              vector.getSource().clear();
              vectorSource.addFeatures(
                vectorSource.getFormat().readFeatures(xhr.responseText));
            }
            removeExtent();
          }
          xhr.send();
        },
        strategy: ol.loadingstrategy.bbox
      });

      var vector = new ol.layer.Vector({
        source: vectorSource,
        style: new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 255, 1.0)',
            width: 2
          })
        })
      });

      var raster = new ol.layer.Tile({
        source: new ol.source.OSM({
        })
      });

      var map = new ol.Map({
        layers: [raster, vector],
        target: document.getElementById('map'),
        view: new ol.View({
          center: [-8908887.277395891, 5381918.072437216],
          maxZoom: 19,
          zoom: 12
        })
      });
   </script>
  </body>
</html>