0
votes

I'm trying to force a vector layer in OpenLayers 3 to periodically reload its data from a GeoJSON source. The GeoJSON source changes from time to time.

After many different attempts using different methods, I think this is the closest I've managed to get so far:

$(document).ready(function(){
  map.once("postcompose", function(){
       //start refreshing each 3 seconds
       window.setInterval(function(){
         var source = testLayer.getSource();
         var params = source.getParams();
         params.t = new Date().getMilliseconds();
         source.updateParams(params);
       }, 3000);
   });
});

However this is giving me the following (every 3 seconds of course):

Uncaught TypeError: source.getParams is not a function

Here's all of the other code I'm using to load and display the GeoJSON file. The other layers in the map are loaded in the same way:

var testSource = new ol.source.Vector({
    url: '/js/geojson/testfile.geojson',
    format: new ol.format.GeoJSON()
});

...

window.testLayer = new ol.layer.Vector({
    source: testSource,
    style: function(feature, resolution) {
        var style = new ol.style.Style({
            fill: new ol.style.Fill({color: '#ffffff'}),
            stroke: new ol.style.Stroke({color: 'black', width: 1}),
            text: new ol.style.Text({
                font: '12px Verdana',
                text: feature.get('testvalue'),
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.1)'
                }),
                stroke: new ol.style.Stroke({
                    color: 'rgba(0, 0, 0, 1)',
                    width: 1
                })
            })
        });

        return style
    }
});

...

var olMapDiv = document.getElementById('olmap');
var map = new ol.Map({
    layers: [paddocksLayer,zonesLayer,structuresLayer,roadsLayer,testLayer],
    interactions: ol.interaction.defaults({
        altShiftDragRotate: false,
        dragPan: false,
        rotate: false
    }).extend([new ol.interaction.DragPan({kinetic: null})]),
    target: olMapDiv,
    view: view
});
view.setZoom(1);
view.setCenter([0,0]);

I read somewhere else that getParams simply doesn't work on vector layers, so this error wasn't entirely unexpected.

Is there an alternative method which will reload (not just re-render) a vector layer?

Thanks in advance. I must also apologise in advance as I'll need really specific guidance with this - I'm very new to JS and OpenLayers.

Gareth

1
You'll have to show how you load (AJAX) your json file.Jonatas Walker
See my edits above - I'm not using AJAX to load the GeoJSON when initialising the map. Should I be doing that? The layer is showing correctly with the additional code above - just not updating.Gareth Jones

1 Answers

0
votes

(fiddle)

You can achieve this with a custom AJAX loader (when you pass url to ol.source.Vector this is AJAX as well). Then you can reload your JSON file as you will.

You can use any AJAX library you want but this is as simple as:

var utils = {
  refreshGeoJson: function(url, source) {
    this.getJson(url).when({
      ready: function(response) {
        var format = new ol.format.GeoJSON();
        var features = format.readFeatures(response, {
          featureProjection: 'EPSG:3857'
        });
        source.addFeatures(features);
        source.refresh();
      }
    });
  },
  getJson: function(url) {
    var xhr = new XMLHttpRequest(),
        when = {},
        onload = function() {
          if (xhr.status === 200) {
            when.ready.call(undefined, JSON.parse(xhr.response));
          }
        },
        onerror = function() {
          console.info('Cannot XHR ' + JSON.stringify(url));
        };
    xhr.open('GET', url, true);
    xhr.setRequestHeader('Accept','application/json');
    xhr.onload = onload;
    xhr.onerror = onerror;
    xhr.send(null);

    return {
      when: function(obj) { when.ready = obj.ready; }
    };
  }
};