OpenLayers 3: Wie aktualisiere ich eine Karte, nachdem ich den Stil eines Features geändert habe?


9

Ich habe eine OpenLayers 3.2.0-Karte, die einige Vektorquellen ( ol.source.Vector) und zugehörige Vektorebenen ( ol.layer.Vector) enthält.

Wenn Features ( ol.Feature) zu den Vektorquellen hinzugefügt werden, erhalten sie eine dataEigenschaft, die auf das Javascript-Objekt festgelegt ist, das das Feature darstellt. TypeScript folgt ...

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

Die Vektorebenen haben dann eine Stilfunktion, die die dataEigenschaft liest und ihren Stil abruft:

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

Manchmal führen Ereignisse, die nichts mit der Karte zu tun haben, dazu, dass sich die Stile ändern. Wenn ein Objekt beispielsweise ungültig wird, ändert sich sein Stil. Da data.styleich völlig unter meiner Kontrolle bin, ist es natürlich trivial, sie zu ändern.

Das Problem ist, dass die Karte nicht weiß, dass sich der Stil geändert hat. Wenn ich den Stil eines Objekts ändere und dann die Karte zoome und sie zum Neuzeichnen zwinge, stelle ich fest, dass meine Stilfunktionen ausgeführt werden und den neuen Stil zurückgeben und das Feature neu gezeichnet wird. Wie erzwinge ich programmgesteuert eine Aktualisierung der Karte?

Nach einigem Suchen und Experimentieren habe ich versucht:

  1. Der Aufruf render()auf der ol.Mapselbst.
  2. Aufruf dispatchChangeEvent()an dieol.source.Vector
  3. Aufruf redraw()an dieol.layer.Vector

Diese wurden vorgeschlagen, aber keine davon hat funktioniert, was nicht verwunderlich ist, da nur die erste Methode in der OpenLayers 3.2.0-API-Dokumentation aufgeführt ist und nicht als stabil markiert ist.


Haben Sie versucht, vectorlayer.refresh ({force: true}); ?
Ylka

Ich habe aber, nicht überraschend, das funktioniert nicht, weil das eine OpenLayers 2-Methode ist.
Xharlie

Antworten:


12

Durch Zufall bin ich auf die Antwort gestoßen - es geht darum, changed()die Funktionen selbst aufzurufen , nachdem die styleEigenschaft der zugehörigen Daten geändert wurde. Siehe: http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed

Dies erfordert, dass ich die ol.Featuremit jedem vectorDataObjekt verknüpften Objekte im Auge habe (früher musste ich nur die Objekte vectorDataaus einer Funktion finden, mit der dies möglich war get()), aber dies ist kein großer Kostenfaktor.

(Ich fand dies durch einen Blick auf setGeometryund setStyleund andere Methoden auf , ol.Featureum zu sehen , was sie tun.)


Obwohl dieser Ansatz funktioniert, führt das Aufrufen changedeiner angemessenen Anzahl von Funktionen tatsächlich zu einer ziemlich schwerwiegenden Leistungsminderung (auf diese Weise stürzte Chrome mehrmals ab). Ich würde empfehlen, changed()die Quelle Ihrer Ebene aufzurufen, nachdem alle Ihre Funktionen geändert wurden.
Kyle

0

Ich habe eine Woche lang versucht, herauszufinden, wie ein Feature (Polygon) nach dem Löschen aus der Karte verschwindet ( vectorSource.removeFeature(selectedFeature)und es hat keine Lösung funktioniert. Seltsamerweise verfügt die aktuelle OL3 v3.15.1 nicht über eine grundlegende Funktion zum erzwungenen Aktualisieren / Rendern funktioniert! Die Lösung, die für mich funktioniert hat, war, selectedFeatureden Stil zu ändern :

        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)

Jeder Stil würde funktionieren, da das Feature bereits aus der Ebene entfernt, aber nicht aktualisiert wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.