OpenLayers 3 Reload Layer (s)

I am working on a project using OL3, in which I need to be able to manually (by pressing a button) or automatically (in time) reload vector layers if they have been updated since the last boot using conditional HTTP GET (304 headers and the like) .

I found this very old post ( https://gis.stackexchange.com/questions/333/how-to-dynamically-refresh-reload-a-kml-layer-in-openlayers ) for KML layers, but it seems to be uses variables that are no longer found in OL3, and I'm not sure that this will only allow downloading files that have changed since the last upload. At first glance, it seems that a full reboot is forced, even if the file has not been modified.

There is nothing in the API that resembles the reload function for map or layer objects in OL3. Is there any way to do this?

Update 1:

I found a possible way to do this as an answer in this question: https://gis.stackexchange.com/questions/125074/openlayers3-how-to-reload-a-layer-from-geoserver-when-underlying-data-change with using code:

layer.getSource().updateParams({"time": Date.now()}); 

however, when I run this code, I get an error:

 TypeError: selectedLayer.getSource(...).updateParams is not a function 

After checking the API Reference for OL3, it seems that such functions do not exist. The closest is setProperties () or setAttributions (). None of them work. It also seems that not all layer types implement getSource ().

Update 2:

Update () reloads the fragments, but does not seem to request them from the server. Rather, it looks like they are loading from the cache (but not the HTTP cache). There are no requests, no HTTP 304 or something like that. He will try the KML approach and publish the results soon.

Update 3:

After trying several different solutions, I accidentally stumbled upon something that worked for vector layers. By calling the source.clear () function of the layer, and then calling Map.updateSize (), this layer is automatically reloaded from the source URL. An XHR GET request is issued, and if the original file has changed, it will be reloaded from the file. If the source file has not changed, 304 will be issued and the source will be reloaded from the cache.

The following is a function that should use this method to reload this layer:

 function refreshLayer(selectedLayer) { var selectedLayerSource = selectedLayer.getSource(); if(selectedLayerSource instanceof ol.source.Vector) { //do vector reload selectedLayerSource.clear(); map.updateSize(); } else { //reload the entire page window.location.reload(); } } 

However, it seems that the first few attempts (depending on the browser) are sent, the code 200 is sent back, but this layer does not reflect any changes. After several attempts (and reloading the page several times), this works. When it starts working for a layer, it continues to work as often as the original file changes. Does anyone know what is going on?

Update 4:

Using an adaptation of Jonathas answer, I get better results. New features appear instantly upon reboot. However, old functions are not removed from the map, and many functions that move locations are displayed on the map twice. Below is my code:

 function refreshSelectedLayer() { console.log("This feature is still in the process of being implemented. Refresh may not actually occur."); var selectedLayerSource = selectedLayer.getSource(); if(selectedLayerSource instanceof ol.source.Vector) { var now = Date.now(); var format = selectedLayerSource.getFormat(); var url = selectedLayerSource.getUrl(); url = url + '?t=' + now; loader = ol.featureloader.xhr(url, format); selectedLayerSource.clear(); loader.call(selectedLayerSource, [], 1, 'EPSG:3857'); map.updateSize(); } else if(selectedLayerSource instanceof ol.source.Tile) { selectedLayerSource.changed(); selectedLayerSource.refresh(); } } 

Note that var selectedLayer is set elsewhere in the code. Any ideas why these very strange results come up?

Update 5:

I noticed that if I delete all other codes except:

 source.clear(); 

an XHR GET request is called and the functions do not disappear. Why purging the source does not eliminate all the features?

Update 6:

After finding that ol.source.clear () does not actually remove functions from this data source / level, I replaced it using the following code:

 selectedLayerSource.forEachFeature(function(feature){ selectedLayerSource.removeFeature(feature); }); 

The output of functions at the level before and after each step, I got the following:

 var now = Date.now(); var format = selectedLayerSource.getFormat(); var url = selectedLayerSource.getUrl(); url = url + '?t=' + now; console.log("time: "+now+" format: "+format+" url: "+url); loader = ol.featureloader.xhr(url, format); console.log(selectedLayerSource.getFeatures()); console.log("Deleting features..."); /* Try adding code here to manually remove all features from source */ selectedLayerSource.forEachFeature(function(feature){ selectedLayerSource.removeFeature(feature); }); console.log(selectedLayerSource.getFeatures()); console.log("Loading features from file..."); loader.call(selectedLayerSource, [], 1, 'EPSG:3857'); window.setTimeout(function(){ console.log(selectedLayerSource.getFeatures()); map.updateSize(); }, 500); 

What information is displayed on the console:

 "time: 1471462410554 format: [object Object] url: http://server/file.ext?t=1471462410554" file.php:484:3 Array [ Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, 1 more… ] file.php:491:3 Deleting features... file.php:492:3 Array [ ] file.php:501:3 Loading features from file... file.php:503:3 GET XHR http://server/file.ext [HTTP/1.1 200 OK 34ms] Array [ Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, 1 more… ] 

After several tests with the GeoJSON and KML levels, I confirmed that this method works !!!

However, since the loader makes its request asynchronously, I still have a problem with how to execute the code after calling the loader function. Obviously using setTimeout () is a terrible way to do this and has only been implemented for testing purposes. A success / failure callback function would be ideal, and looking at the source of featureloader.js, it seems that they are offered as parameters in the ol.featureloader.loadFhaturesXhr file. See below the code block from featureloader.js:

 /** * @param {string|ol.FeatureUrlFunction} url Feature URL service. * @param {ol.format.Feature} format Feature format. * @param {function(this:ol.VectorTile, Array.<ol.Feature>, ol.proj.Projection)|function(this:ol.source.Vector, Array.<ol.Feature>)} success * Function called with the loaded features and optionally with the data * projection. Called with the vector tile or source as `this`. * @param {function(this:ol.VectorTile)|function(this:ol.source.Vector)} failure * Function called when loading failed. Called with the vector tile or * source as `this`. * @return {ol.FeatureLoader} The feature loader. */ ol.featureloader.loadFeaturesXhr = function(url, format, success, failure) 

I tried to implement these functions, for example, when creating a bootloader:

 loader = ol.featureloader.xhr(url, format, function(){ console.log(selectedLayerSource.getFeatures()); map.updateSize(); console.log("Successful load!"); }, function(){ console.log("Could not load "+selectedLayerName+" layer data from "+url); } ); 

but not one of the functions is called. Any suggestions? I feel like I'm missing something really simple here ...

Update 7:

Using the solution provided by @Jonatas Walker, I adapted it to use jQuery:

  var now = Date.now(); var format = selectedLayerSource.getFormat(); var url = selectedLayerSource.getUrl(); url = url + '?t=' + now; //make AJAX request to source url $.ajax({url: url, success: function(result){ //manually remove features from the source selectedLayerSource.forEachFeature(function(feature){ selectedLayerSource.removeFeature(feature); }); //create features from AJAX results var features = format.readFeatures(result, { featureProjection: 'EPSG:3857' }); //add features to the source selectedLayerSource.addFeatures(features); }, error: function(err){ alert("Could not load features from "+selectedLayerName+" at "+url+" error code: "+err.status); } }); 

After extensive testing with GeoJSON and KML sources, this turned out to be an extremely reliable update method!

+5
source share
2 answers

Well, there are other options! You have your own bootloader.

Download this script - in case someone is still using older browsers

 <script src="//cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script> 

Then upload your JSON file and know when it is ready / loaded:

 function refreshSelectedLayer(layer) { var now = Date.now(); var source = layer.getSource(); var format = new ol.format.GeoJSON(); var url = '//your_server.net/tmp/points.json?t=' + now; fetch(url) .then(function(response) { return response.json(); }).then(function(json) { console.log('parsed json', json); source.clear(); // if this is not enough try yours var features = format.readFeatures(json, { featureProjection: 'EPSG:3857' }); source.addFeatures(features); }).catch(function(ex) { console.log('parsing failed', ex); }); } 
+1
source

Try to adapt this:

 function refreshSource() { var now = Date.now(); var source = vectorLayer.getSource(); var format = new ol.format.GeoJSON(); var url = '//your_server.net/tmp/points.json?t=' + now; var loader = ol.featureloader.xhr(url, format); source.clear(); loader.call(source, [], 1, 'EPSG:3857'); } 

The trick is to tell the browser that this is a new download by changing the URL.

+2
source

All Articles