openlayers 5 раздражает флеш на vector.getSource().clear()
Когда я загружаю более 500 векторных функций в Openlayers, производительность на планшетах и телефонах сильно снижается. Мое решение состояло в том, чтобы очистить источник на карте moveend
событие. Это работает, но приводит к раздражающей вспышке, предположительно между очисткой и перезагрузкой источника.
Более раннее решение этой "перепрошивки" здесь больше не работает, оно приводит к рекурсивным вызовам 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 объектов).
[EDIT] После комментария от @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 ответа
Не очищайте источник на каждом шаге, но только когда он превышает количество функций max
, это предотвратит слишком частые перезагрузки:
map.on('moveend', function(evt) {
if (vectorSource.getFeatures().length > max) {
vectorSource.clear()
}
});
Openlayers должен отображать более 500 функций даже на медленных устройствах.
- Как говорит Ахочевар, стиль может быть задействован, давайте посмотрим, как вы его используете.
- Вы также можете попробовать использовать
renderMode: 'image'
опция для векторного слоя для более быстрой визуализации во время взаимодействия и анимации. - Вы можете использовать кластеризацию в больших масштабах, чтобы уменьшить количество объектов для рисования.
Например, этот сайт отображает более 18 000 точечных функций даже на мобильных устройствах: https://c-conforme.fr/
Проблема в том, что вы создаете новый 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 года я нашел решение, которое не очень «яркое», но немного (я думаю, что моя формулировка вопроса, должно быть, была слишком расплывчатой).
я использую
vectorSource.refresh()
Давая это:
map.on('moveend', function(evt) {
console.log('refreshing vector');
vectorSource.refresh()
});
Версия OpenLayers, которую я сейчас использую, — v6.5.0.