OpenLayers 3: Как обновить карту после изменения стиля объекта?

9

У меня есть карта OpenLayers 3.2.0, которая имеет некоторые векторные источники ( ol.source.Vector) и связанные векторные слои ( ol.layer.Vector)

Когда Features ( ol.Feature) добавляются к векторным источникам, им присваивается dataсвойство, которое устанавливается для объекта javascript, который представляет объект. TypeScript следует ...

vectorSource.addFeature(new ol.Feature({
    geometry: /* ... */,
    data: vectorData,
}));

Векторные слои тогда имеют функцию стиля, которая читает dataсвойство и получает его стиль:

vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    renderBuffer: /* ... */,
    style: function (feature: ol.Feature, resolution: any) {
        var data = </* TypeScript Type */>feature.get('data');
        if ((data) && (data.style)) {
            return [data.style];
        }
        else {
            /* return default style */
        }
    }
});

Иногда события, не связанные с картой, вызывают изменение стилей. Например, когда объект становится недействительным, его стиль меняется. Ясно, что, поскольку я data.styleполностью нахожусь под его контролем, его изменение тривиально.

Проблема в том, что карта не знает, что стиль изменился. Если я изменяю стиль объекта, а затем увеличиваю карту, заставляя ее перерисовывать, я замечаю, что мои функции стиля запускаются и возвращают новый стиль, а функция перерисовывается. Как мне программно заставить карту обновиться?

После некоторых поисков и экспериментов я попытался:

  1. Призывая render()к ol.Mapсебе.
  2. Вызов dispatchChangeEvent()наol.source.Vector
  3. Вызов redraw()наol.layer.Vector

Они были предложены, но ни один из них не сработал, что неудивительно, поскольку только первый метод даже указан в документации по API OpenLayers 3.2.0 и не помечен как стабильный.

Xharlie
источник
Вы пробовали vectorlayer.refresh ({force: true}); ?
Юлка
У меня есть, но, что неудивительно, это не работает, потому что это метод OpenLayers 2.
Ксарли

Ответы:

12

Случайно я наткнулся на ответ - это вызвать changed()сами функции после изменения styleсвойства связанных с ними данных. Смотрите: http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed

Это требует от меня отслеживания ol.Featureобъектов, связанных с каждым vectorDataобъектом (ранее мне когда-либо требовалось только найти vectorDataобъект из функции, что можно было бы сделать get()), но это не слишком дорого.

(Я нашел это, посмотрев на setGeometryи setStyleдругие методы, ol.Featureчтобы увидеть, что они делают.)

Xharlie
источник
Хотя этот подход работает, вызов changedлюбого разумного количества функций на самом деле влечет за собой довольно серьезное снижение производительности (в этом случае Chrome несколько раз падал). Я бы рекомендовал вызывать changed()источник вашего слоя после того, как все ваши функции были изменены.
Кайл
0

Я потратил неделю на то, чтобы выяснить, как заставить объект (Polygon) исчезнуть с карты после его удаления ( vectorSource.removeFeature(selectedFeature)и решение не сработало. Как ни странно, в текущей версии OL3 v3.15.1 нет базовой функции принудительного обновления / рендеринга, которая работает! Решение, которое работало для меня, состояло в том, чтобы изменить selectedFeatureстиль:

        var newStyle = new ol.style.Style({
            image: new ol.style.Circle({
                radius: 5,
                fill: new ol.style.Fill({color: 'red'}),
                stroke: new ol.style.Stroke({color: 'yellow', width: 1})
            })
        });
        selectedFeature.setStyle(newStyle)

Любой стиль будет работать, поскольку объект уже удален со слоя, но не обновлен.

Мори
источник