OpenLayers 3: Jak odświeżyć mapę po zmianie stylu elementu?

9

Mam mapę OpenLayers 3.2.0, która zawiera niektóre źródła wektorowe ( ol.source.Vector) i powiązane warstwy wektorowe ( ol.layer.Vector)

Kiedy Funkcje ( ol.Feature) są dodawane do źródeł wektorowych, otrzymują one datawłaściwość ustawioną na obiekt javascript, który reprezentuje funkcja. TypeScript śledzi ...

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

Warstwy wektorowe mają następnie funkcję stylu, która odczytuje datawłaściwość i pobiera jej styl:

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 */
        }
    }
});

Czasami zdarzenia niezwiązane z mapą powodują zmianę stylów. Na przykład, gdy obiekt staje się nieprawidłowy, zmienia się jego styl. Oczywiście, ponieważ data.stylejest całkowicie pod moją kontrolą, zmiana tego jest banalna.

Problem polega na tym, że mapa nie wie, że styl się zmienił. Jeśli zmienię styl obiektu, a następnie powiększę mapę, zmuszając ją do przerysowania, zauważę, że moje funkcje stylu działają i zwracają nowy styl, a funkcja jest przerysowana. Jak programowo wymusić odświeżenie mapy?

Po kilku poszukiwaniach i eksperymentach próbowałem:

  1. Dzwoniąc render()na ol.Mapsobie.
  2. Dzwoniąc dispatchChangeEvent()naol.source.Vector
  3. Dzwoniąc redraw()naol.layer.Vector

Zostały zasugerowane, ale żadna z nich nie działała, co nie jest zaskakujące, ponieważ tylko pierwsza metoda jest wymieniona w dokumentacji API OpenLayers 3.2.0 i nie jest oznaczona jako stabilna.

Xharlie
źródło
próbowałeś vectorlayer.refresh ({force: true}); ?
ylka
Mam, ale nie jest zaskoczeniem, że to nie działa, ponieważ jest to metoda OpenLayers 2.
Xharlie

Odpowiedzi:

12

Przez przypadek natknąłem się na odpowiedź - jest to wywoływanie changed()samych funkcji po zmianie stylewłaściwości powiązanych z nimi danych. Zobacz: http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed

Wymaga to ode mnie śledzenia ol.Featureobiektów powiązanych z każdym vectorDataobiektem (wcześniej zawsze potrzebowałem tylko znaleźć vectorDatafunkcję, co można zrobić get()), ale nie jest to duży koszt.

(Znalazłem to patrząc na setGeometryi setStyleoraz inne sposoby na ol.Feature, aby zobaczyć, co robią.)

Xharlie
źródło
Chociaż takie podejście działa, wzywanie changeddowolnej rozsądnej liczby funkcji w rzeczywistości wiąże się z dość poważnym spadkiem wydajności (kilkakrotnie w ten sposób rozbijał Chrome). Polecam wywołanie changed()źródła warstwy po zmianie wszystkich funkcji.
Kyle,
0

Spędziłem tydzień próbując dowiedzieć się, jak sprawić, by funkcja (wielokąt) zniknęła z mapy po jej usunięciu ( vectorSource.removeFeature(selectedFeature). I nie zadziałało żadne rozwiązanie. Dziwne, że obecny OL3 v3.15.1 nie ma podstawowej funkcji wymuszonego odświeżania / renderowania, która działa! Rozwiązaniem, które działało dla mnie, była zmiana selectedFeaturestylu:

        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)

Każdy styl działałby, ponieważ element został już usunięty z warstwy, ale nie został odświeżony.

Morey
źródło