Entspricht layer.redraw (true) in OpenLayers 3?


13

Ich habe eine Geojson-Ebene in meiner OL3-App, die ich alle 5 Sekunden neu zeichnen möchte (um die Bewegung auf der Karte anzuzeigen).

Wie mache ich es ? Konnte das Äquivalent von Layer.redraw () nicht finden.


Hast du dir ol.animation angesehen? Im Allgemeinen ist das Zeichnen von Vektoren in ol3 flüssiger und wird anders gehandhabt, es ist jedoch nicht ganz klar, was Sie in Ihrer Frage tun möchten.
John Powell

@ JohnBarça - Meine GeoJson-Daten stammen von Postgres, die alle 5 Sekunden mit neuen GPS-Daten aktualisiert werden. Ich möchte die Ebene neu zeichnen, um jedes Mal die aktuelle Position der Einheiten auf der Karte
anzuzeigen

Sie fordern also alle 5 Sekunden Daten mit einem rekursiven setTimeout-Aufruf (oder ähnlichem) an und möchten nur wissen, wie Sie die Aktualisierung der Vektor-Features erzwingen können?
John Powell

@ JohnBarça - Wenn es einen besseren Weg gibt, den ich lernen möchte, aber das ist, was ich tue, möchte ich den GPS-Standort in Echtzeit auf der Karte anzeigen. GPS sendet ihren Standort an PostGIS und von dort aus lese ich die Daten mit GeoJSON (oder ich kann GeoServer verwenden), aber ich möchte, dass sich der Layer von Zeit zu Zeit aktualisiert.
Alophind

Klar, ich verstehe, was du versuchst zu tun. Jede Möglichkeit eines Codebeispiels, da meines Erachtens die Funktionen aktualisiert werden, wenn Sie eine Animationsschleife mit einem Ajax-Aufruf an einen Remoteserver in settimeout setzen und den mit Format.GeoJSON oder ähnlichem zurückkommenden JSON laden.
John Powell

Antworten:


9

So können Sie eine Vektorquelle alle 5 Sekunden über einen Webdienst aktualisieren, der Funktionen in einem GeoJSON-Dokument zurückgibt:

var vectorSource = new ol.source.Vector();
var geojsonFormat = new ol.format.GeoJSON();

window.setTimeout(function() {
  $.ajax('http://example.com/data.json', function(data) {
    var features = geojsonFormat.readFeatures(data
        {featureProjection:"EPSG:3857"});
    geojsonSource.clear();
    geojsonSource.addFeatures(features);
  });
}, 5000);

jQuery wird hier zum Anfordern der Daten über Ajax ( $.ajax) verwendet, aber Sie können natürlich die Bibliothek Ihrer Wahl verwenden.

In diesem Codeausschnitt wird außerdem davon ausgegangen, dass die Projektionen der Karte "EPSG: 3857" (Web Mercator) lauten und dass die Koordinaten in den GeoJSON-Dokumenten Längen- und Breitengrade sind.


3
Dieser Code verwirrt mich, sollte vectorSourceund geojsonSourcesoll zusammengeführt werden?
Kelly Thomas

Ich denke du meinst window.setInterval nicht setTimeout; sonst macht es nur einmal.
Jonathan

9

Ich weiß, dass diese Frage alt ist, aber ich habe endlich eine Lösung gefunden, um eine Ebene auf OpenLayer 3 zu aktualisieren.

Sie müssen die Parameter der Ebenenquelle folgendermaßen aktualisieren:

var source = yourLayer.getSource();
var params = source.getParams();
params.t = new Date().getMilliseconds();
source.updateParams(params);

3
Es scheint, dass nicht alle Quellen die updateParamsMethode unterstützen. OL3.18.2 nur zeigt es ImageArcGISRest, ImageMapGuide, ImageWMS, TileArcGISRestund TileWMS, und nicht für zB ol.source.Vector.
Arjan

Date # getTime ist möglicherweise besser als Date # getMilliseconds , um den Cache ungültig zu machen und das erneute Zeichnen des Layers zu erzwingen, da dadurch jedes Mal eine eindeutige Nummer sichergestellt wird.
Walkermatt

5

Sie können eine WFS-Ebene mit aktualisieren myLayer.getSource().clear().


1
Dies gelang mir mit OpenLayers 3 v. 0.14.2 und einer WFS GeoJSON-Vektorquelle.
Dirk

3
An einer einzeiligen Antwort ist nichts auszusetzen, wenn sie am Geld hängt. Es sollte eine Reputationsauszeichnung geben, um diese Infobox entfernen zu lassen.
Dennis Bauszus

1
Die Antwort ist korrekt, aber dies kann zu einem Flimmern führen: Beim Aufrufen clear()werden vorhandene Features sofort aus der Karte entfernt und erst nach Erhalt der HTTP-Antwort wieder hinzugefügt. Dies gilt sowohl für die Angabe eines Wertes für VectorOptions#urlals auch für VectorOptions#loader. Für Echtzeitdaten sieht es für den Endbenutzer möglicherweise besser aus, getSource().clear()wenn Sie einige WebSockets- oder XHR-Aktionen manuell ausführen und anschließend aufrufen, gefolgt von getSource().addFeatures(...).
Arjan

3

In OL2 habe ich eine Layer-Aktualisierungsstrategie verwendet, die nicht zu OL3 hinzugefügt wurde. Im Folgenden finden Sie eine selbstaufrufende Funktion, die eine Ajax-Anforderung verwendet, um den GeoJSON abzurufen, ihn dann zu lesen und einer Quelle hinzuzufügen.

var yourSource = new ol.source.GeoJSON();

//add this source to a layer, the layer to a map with a view etc
...

//now fetch the data
var fetchData = function () {
    jQuery.ajax(url,
    {
        dataType: 'json',
        success: function (data, textStatus, jqXHR) {
            yourSource.clear(); //remove existing features
            yourSource.addFeatures(yourSource.readFeatures(data));
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(errorThrown);
        }
    });

    //call this again in 5 seconds time
    updateTimer = setTimeout(function () {
        fetchData();
    }, 5000);
};
fetchData(); //must actually call the function!

Hoffe das hilft.


2

Dies funktioniert perfekt für Ebenen:

layer.changed();

gemäß http://openlayers.org/en/latest/apidoc/ol.layer.Vector.html#changed


1
Sie müssen ein bisschen mehr darüber erklären, wie layer.changed();perfekt (ly) für Ebenen funktioniert. Die Dokumentationsbeschreibung Increases the revision counter and dispatches a 'change' event.ist nicht wirklich hilfreich. Wie beantwortet die Verwendung der changed () -Methode die Frage zum erneuten Zeichnen der Karte alle 5 Sekunden?
Nmtoken

Ich habe Ajax verwendet, um eine überarbeitete Geojson-Quelle zu speichern. Das Problem bestand darin, dass beim Schließen der Ebene und erneuten Öffnen der Karte die zwischengespeicherte (nicht überarbeitete) Version der Quelle verwendet wurde. Sobald ich den Cache geleert hatte, verwendete die Ebene die überarbeitete Quelle, wie ich es erwartet hätte. Leider hatte der Vorschlag layer.changed();keine Wirkung für mich, hat aber source.changed();den Trick gemacht.
Peter Cooper

1

Eine explizite Aktualisierung ist nicht erforderlich. Jedes Mal, wenn Sie den Inhalt eines Layers aktualisieren, wird die Karte aktualisiert und fordert ein neues Frame-Rendering an.

Um das Rendern manuell zu erzwingen, haben Sie map.render()und map.renderSync()Methoden.


Dadurch wird der Inhalt nicht aktualisiert, sondern nur der Kartenbereich selbst.
Mapper
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.