More

Refreshing map after changing Feature's style in OpenLayers 3

Refreshing map after changing Feature's style in OpenLayers 3


I have an OpenLayers 3.2.0 map that features some vector sources (ol.source.Vector) and associated vector layers (ol.layer.Vector)

When Features (ol.Feature) are added to the vector sources, they are given adataproperty that is set to the javascript object that the feature represents. TypeScript follows…

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

The vector layers then have a style-function that reads thedataproperty and retrieves its style:

vectorLayer = new ol.layer.Vector({ source: vectorSource, renderBuffer: /*… */, style: function (feature: ol.Feature, resolution: any) { var data = feature.get('data'); if ((data) && (data.style)) { return [data.style]; } else { /* return default style */ } } });

Sometimes, events unrelated to the map cause the styles to change. For example, when an object becomes invalid, its style changes. Clearly, sincedata.styleis entirely within my control, changing it is trivial.

The problem is that the map does not know that the style has changed. If I change an object's style and then zoom the map, forcing it to redraw, I notice that my style-functions run and return the new style and the feature is redrawn. How do I programatically force the map to refresh?

After some searching and experimentation, I have tried:

  1. Callingrender()on theol.Mapitself.
  2. CallingdispatchChangeEvent()on theol.source.Vector
  3. Callingredraw()on theol.layer.Vector

These were suggested but none of them worked, which isn't surprising since only the first method is even listed in the OpenLayers 3.2.0 API documentation and it is not marked as stable.


By chance, I have stumbled upon the answer - it is to callchanged()on the features themselves after changing thestyleproperty of their associated data. See: http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed

This does require me to keep track of theol.Featureobjects associated with eachvectorDataobject (formerly, I only ever needed to find thevectorDatafrom a feature, which could be done withget()) but this isn't much of a cost.

(I found this by looking atsetGeometryandsetStyleand other methods onol.Featureto see what they do.)


I spent a week on trying to figure out how to make a feature (Polygon) disappear from the map after deleting it (vectorSource.removeFeature(selectedFeature). And no solution worked. Oddly the current OL3 v3.15.1 doesn't have basic forced-refresh/render function that works! The solution that worked for me was to changeselectedFeature's style:

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)

Any style would work since the feature has already been removed from the layer but not refreshed.


Xharlie's answer helped me with the calling changed idea, except that in some cases you have to call it on the layer instead of the feature. In my case I had a style function bound to the layer and the style used a calculated geometry instead of the geometry of the feature.

layer.changed() map.once('rendercomplete', () => { layer.changed() }) map.renderSync()

ps: I actually do all this once more inside the first rendercomplete listener; and disable user interaction during this time; not ideal especially when it's long to compute so if you can avoid this kind of hack all the best for you.


Watch the video: CRUD Proyecto GIS, App, Google Maps, Geoserver, Postgis, Open layers