1

I am pulling data from a 3rd party API that gives me lat/lon coords as well as a status for the point. I am currently able to successfully plot the points and give them the correct style for their status on the first iteration. However, every 3 seconds I need to be able to update their style if the status changed. I have tried using mySource.changed() but it did not work. I looked all over and cannot find the solution, even though this does not seem like it should be a difficult thing to accomplish?

I also tried to clear() my source every 3 seconds, but then the vector layer 'flashes' and I need it to update seamlessly. I also tried removing/re-adding the entire vector layer. Do I need to use a style function? Or a feature overlay? Why can I not just overwrite styles like I can in google maps or leaflet?

My Styles

var takenStyle = new ol.style.Style({
    image: new ol.style.Icon({
        src: '../_images/redMark.png',
        scale: .2
    })
});
var openStyle = new ol.style.Style({
    image: new ol.style.Icon({
        src: '../_images/greenMark.png',
        scale: .2
    })
});
var unsureStyle = new ol.style.Style({
    image: new ol.style.Icon({
        src: '../_images/yellowMark.png',
        scale: .2
    })
});

How I am assigning the styles/features

if ((data.scopes[i].parking_spot.status === true)) {
var feature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.transform(pointCoords, 'EPSG:4326', 'EPSG:3857'))
});
feature.setStyle(takenStyle);
feature.setId(i);
pointSource.addFeature(feature);

UPDATE: Using Navageer Gowda's suggestion, I was able to finally figure this out. I Created a second function, and had that iterate through the features to update the styles.

if ((data.scopes[i].parking_spot.occupied === true && data.scopes[i].parking_spot.occupied === lastCheck[i].occupied)) {
     theFeatures[i].setStyle(takenStyle);
}
Truextacy
  • 532
  • 1
  • 4
  • 21
  • have you tried `feature.changed()` method? [see it](http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed) – tfidelis Feb 13 '17 at 21:15
  • Yes I tried that. Nothing seemed to happen. I also tried using it on the pointSource. But had no luck. Would I call my feature.changed() inside the if statement where I set the styles? – Truextacy Feb 13 '17 at 21:18
  • yes, i think so. Could you show all your code for us? i will create a jsfiddle and try to debug it to better help you. – tfidelis Feb 13 '17 at 21:19
  • Yeah, I will add everything I have. It is quite a lot. It is also worth noting, that the styles will correctly change if I add a pointSource.clear(). But I need to update to be seamless. – Truextacy Feb 13 '17 at 21:20

2 Answers2

2

To force a refresh of layer style every 3 seconds, you can do this:

window.setInterval(function () {
  layer.getSource().dispatchEvent('change');
}, 3000);

However, the API supports what you're trying to do in a cleaner way by using a custom loader function on your ol.source.Vector and a custom style function on your ol.layer.Vector. It looks like this:

var layer = new ol.layer.Vector({
  source: new ol.source.Vector({
    loader: function(extent, resolution, projection) {
      var fetchData = function() {
        // Fetch data here, add features *without style* to layer.getSource()
      };

      // Fetch data once immediately
      fetchData();

      // re-fetch every 3 seconds
      window.setInterval(fetchData, 3000);
    }
  }),
  style: function(feature, resolution) {
    var props = feature.getProperties();

    // Psuedo-logic shown here, use your own to determine which style to return
    if (isTaken) {
      return takenStyle;
    } else if (isOpen) {
      return openStyle;
    } else {
      return unsureStyle;
    }
  }
});
Jeff McCloud
  • 5,067
  • 1
  • 13
  • 21
1

It seems you are adding same features again when you change the styles each time. You can do either

  1. Read features for source and change the style of the features or
  2. Do source.clear() before you create new features and adding to pointSource.(source.clear removes all the features present in the vector source)
NVG
  • 2,690
  • 3
  • 23
  • 48
  • I am adding the same features, I would like to just create one function for them. If I change it so I have another function that only updates the styles would I just do a source.getFeatures([i]).setStyle('whateverstyle')? Then run the refresh on my vector layers? I currently can get it to work by running the clear() at the beginning of the function every three seconds, but that causes the vector layer to 'flash' and I need it to be seamless. – Truextacy Feb 14 '17 at 16:07
  • Also, I believe I tried an updateParams() and I don't think you can use it on the vector layer. – Truextacy Feb 14 '17 at 16:12
  • @AustinTruex source.getFeatures([i]).setStyle('whateverstyle')? Try iterating through all the features and set the Style. It should work – NVG Feb 14 '17 at 17:20
  • your method also worked, I accepted Jeff McCloud's answer because it worked and provided a cleaner way to do what I was trying to do. Thank you for your help. – Truextacy Feb 14 '17 at 19:30