15

I have a geojson layer in my OL3 app which I want to redraw every 5 seconds (to show movement on map) .

How do I do it ? Couldn't find the equivalent of Layer.redraw().

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Alophind
  • 2,707
  • 5
  • 40
  • 75
  • Have you looked at ol.animation? In general, vector drawing is smoother and handled differently in ol3, but it isn't entirely clear from your question what you are wanting to do. – John Powell Oct 08 '14 at 00:14
  • @JohnBarça - My GeoJson data comes from postgres which is being updated every 5 seconds with new GPS data. I want to redraw the layer to show each time the current position of the units on the map (it keep changing...) – Alophind Oct 08 '14 at 05:49
  • So, you are requesting data every 5 seconds using a recursive setTimeout call (or something similar) and you just want to know how to force the vector features to refresh? – John Powell Oct 08 '14 at 09:22
  • @JohnBarça - If there is a better way I'm willing to learn ,but this is what I do , I want to show location of GPS in real time on map. GPS send their location to PostGIS and from there I read the data using GeoJSON (or I can use GeoServer) but I wish for the layer to update itself every once in a while. – Alophind Oct 08 '14 at 19:28
  • Sure, I get what you are trying to do. Any chance of a code sample, because in my experience, if you put an animation loop in settimeout, with an ajax call to a remote server, and load the json that comes back using Format.GeoJSON or similar, the features will get updated. – John Powell Oct 09 '14 at 07:40
  • @JohnBarça - Didn't write code yet , Was planning to. So what you suggest is re-adding the features every second ? no auto layer redraw ? – Alophind Oct 09 '14 at 07:42
  • Clear the features from the vector layer and re-add them, within the callback handling the ajax call (I assume you will use ajax to get the json). This should work fine. – John Powell Oct 09 '14 at 08:14
  • Will try it. in OL2 I didn't have to do it because layer.redraw did the ajax call itself . – Alophind Oct 09 '14 at 08:42
  • Really. Sorry, I am being a bit thick today, but in which OL class, Layer.Vector? I'm looking at the source code and I don't see any mechanism whereby layer.redraw goes an ajax call? – John Powell Oct 09 '14 at 09:18

7 Answers7

10

This is how you can refresh a vector source every 5 seconds, from a web service returning features in a GeoJSON document:

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 is used here for requesting the data through Ajax ($.ajax), but you can obviously use the library of your choice.

This code snippet also assumes that the map's projections is "EPSG:3857" (web mercator) and that the coordinates in the GeoJSON documents are longitudes and latitudes.

erilem
  • 2,129
  • 15
  • 14
9

I know that this question is old but i've finally found a solution to refresh a layer on openlayers 3.

You have to update params of the layer source like this:

var source = yourLayer.getSource();
var params = source.getParams();
params.t = new Date().getMilliseconds();
source.updateParams(params);
VincentDEJ
  • 330
  • 4
  • 10
5

You can refresh a WFS layer with myLayer.getSource().clear().

dbaston
  • 13,048
  • 3
  • 49
  • 81
  • 1
    This did it for me with OpenLayers 3 v. 0.14.2 and a WFS GeoJSON vector source. – Dirk Mar 18 '16 at 16:47
  • 3
    nothing wrong with a one-line answer if they are on the money. there should be a reputation award to have this info box removed. – Dennis Bauszus Jun 15 '16 at 17:34
  • 1
    The answer is correct, but this might show some flickering: upon calling clear() any existing features will be removed from the map right away, and only be added again after receiving the HTTP response. This is true for both specifying a value for VectorOptions#url and for VectorOptions#loader. For realtime data, manually doing some WebSockets or XHR magic and then calling getSource().clear() followed by getSource().addFeatures(...) might look better to the end user. – Arjan Sep 29 '16 at 13:14
5

You can use the changed method for layers to indicate a change and let OL repaint it:

layer.changed();
m13r
  • 105
  • 3
Tomas P. R.
  • 51
  • 1
  • 2
  • 2
    You need to explain a bit more about how layer.changed(); works perfect(ly) for layers. The documentation description Increases the revision counter and dispatches a 'change' event. isn't really helpful. How does using the changed() method answer the question regarding redrawing the map every 5 seconds? – nmtoken Nov 25 '16 at 11:07
  • I have used Ajax to save a revised geojson source, and the problem I had was that if I closed the layer and re-opened it the map used the cached (unrevised) version of the source. Once I cleared the cache the layer used the revised source as I would expect. Unfortunately, the suggested layer.changed(); had no effect for me, but source.changed(); did the trick. – Peter Cooper Jan 15 '18 at 19:37
3

With OL2 I used a layer refresh strategy which hasn't been added to OL3. Below is a self calling function that will use an ajax request to fetch the GeoJSON and then read it and add it to a source.

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!

Hope this helps.

Jon Lynch
  • 376
  • 1
  • 4
1

There is no need to refresh explicitly. Each time you update the content of a layer the map is refreshed requesting a new frame rendering.

To force rendering manually you have map.render() and map.renderSync()methods.

acanimal
  • 1,528
  • 9
  • 14
0

I don't know if in OpenLayer 3 this works, but in actual version (OL6) I use a simple

layer.setStyle(layer.getStyle())