openlayers 5在vector.getSource()。clear()

时间:2019-02-01 15:40:04

标签: openlayers openlayers-5

当我在Openlayers中加载超过500个矢量功能时,平板电脑和电话上的性能会大大降低。我的解决方案是清除地图moveend事件中的源。这种方法有效,但是会导致令人讨厌的闪烁,大概是在清除源和重新加载源之间。

对此“闪烁” here的较早解决方案不再起作用,它导致对WFS的递归调用。

这是我当前的代码:

import {GeoJSON} from 'ol/format';
import {bbox as bboxStrategy} from 'ol/loadingstrategy.js';
import VectorSource from 'ol/source/Vector.js';
import VectorLayer from 'ol/layer/Vector';

var vectorSource = new VectorSource({
 format: new GeoJSON({ dataProjection: layerProjection }),
 loader: function(extent, resolution, projection) {
   var proj = projection.getCode();
   var url = 'https://xxx.xxx/geoserver/wfs?service=WFS' +
     '&version=1.1.0&request=GetFeature&typename=' + layer + 
     '&maxFeatures=200&outputFormat=application/json&srsname=' + proj +
     '&bbox=' + extent.join(',') + ',' + proj;
   var xhr = new XMLHttpRequest();
   xhr.open('GET', url);
   var onError = function() {
     vectorSource.removeLoadedExtent(extent);
   }
   xhr.onerror = onError;
   xhr.onload = function() {
     if (xhr.status == 200) {
       //vectorSource.clear();// Causes recursion          
       vectorSource.addFeatures(
         vectorSource.getFormat().readFeatures(xhr.responseText));
     } else {
       onError();
     }
   }
   xhr.send();
 },
 strategy: bboxStrategy
});

var vector = new VectorLayer({
  source: vectorSource,
  style: style,
  visible: visible
});
map.on('moveend', function(evt) {
  console.log('refreshing vector');
  vectorSource.clear()
});

有没有办法避免Openlayers 5中的清除/重新加载闪存?还是我应该使用另一种方法来加载矢量层(我拥有的层通常是具有5000到10000个要素的点层)。

[编辑] @ahocevar发表评论后,这是我使用的样式:

import {Style, Circle, Fill, Stroke} from 'ol/style';
import Defaults from './PointDefaults';

export default function() {
  return new Style({
    image: new Circle({
      radius: Defaults.radius,
      fill: new Fill({
        color: 'green',
      }),
      stroke: new Stroke({
        color: Defaults.strokeColor,
        width: Defaults.strokeWidth
      })
    }),
  });
}

3 个答案:

答案 0 :(得分:1)

不要清除每个moveend上的源,只有当它超过许多功能max时,这才可以防止重新加载太频繁:

map.on('moveend', function(evt) {
  if (vectorSource.getFeatures().length > max) {
    vectorSource.clear()
  }
});

即使在速度较慢的设备上,Openlayers也应能够显示500多个功能。

  • 正如ahocevar所说,可能涉及样式,让我们看看如何使用它。
  • 您还可以尝试在矢量层上使用renderMode: 'image'选项,以便在交互和动画期间更快地渲染。
  • 您可以大规模使用聚类来减少要绘制的要素数量。

例如,即使在移动设备上,此网站也显示超过18.000个点要素:https://c-conforme.fr

答案 1 :(得分:1)

问题在于,您正在为每个渲染帧上的每个功能创建具有新Style图像的新Circle。在您的情况下,您甚至不需要样式功能,因为所有功能的样式都相同。因此,您的style模块应导出样式,而不是返回样式的函数:

import {Style, Circle, Fill, Stroke} from 'ol/style';
import Defaults from './PointDefaults';

export default new Style({
  image: new Circle({
    radius: Defaults.radius,
    fill: new Fill({
      color: 'green',
    }),
    stroke: new Stroke({
      color: Defaults.strokeColor,
      width: Defaults.strokeWidth
    })
  })
});

答案 2 :(得分:0)

2 年后,我找到了一个解决方案,它不是非常“浮华”,但有点(我认为我对这个问题的措辞一定太含糊了)。

我正在使用 vectorSource.refresh()

给这个:

map.on('moveend', function(evt) {
 console.log('refreshing vector');
 vectorSource.refresh()
});

我现在使用的 OpenLayers 版本是 v6.5.0